xref: /freebsd/contrib/bmake/mk/newlog.sh (revision c59c3bf34db360695f07735bebc76a768cac5afc)
1c1d01b5fSSimon J. Gerraty#!/bin/sh
2c1d01b5fSSimon J. Gerraty
3c1d01b5fSSimon J. Gerraty# NAME:
4c1d01b5fSSimon J. Gerraty#	newlog - rotate log files
5c1d01b5fSSimon J. Gerraty#
6c1d01b5fSSimon J. Gerraty# SYNOPSIS:
7c1d01b5fSSimon J. Gerraty#	newlog.sh [options] "log"[:"num"] ...
8c1d01b5fSSimon J. Gerraty#
9c1d01b5fSSimon J. Gerraty# DESCRIPTION:
10c1d01b5fSSimon J. Gerraty#	This script saves multiple generations of each "log".
11c1d01b5fSSimon J. Gerraty#	The "logs" are kept compressed except for the current and
12c1d01b5fSSimon J. Gerraty#	previous ones.
13c1d01b5fSSimon J. Gerraty#
14c1d01b5fSSimon J. Gerraty#	Options:
15c1d01b5fSSimon J. Gerraty#
16c1d01b5fSSimon J. Gerraty#	-C "compress"
17c1d01b5fSSimon J. Gerraty#		Compact old logs (other than .0) with "compress"
18c1d01b5fSSimon J. Gerraty#		(default is 'gzip' or 'compress' if no 'gzip').
19c1d01b5fSSimon J. Gerraty#
20c1d01b5fSSimon J. Gerraty#	-E "ext"
21c1d01b5fSSimon J. Gerraty#		If "compress" produces a file extention other than
22c1d01b5fSSimon J. Gerraty#		'.Z' or '.gz' we need to know.
23c1d01b5fSSimon J. Gerraty#
24c1d01b5fSSimon J. Gerraty#	-G "gens"
25c1d01b5fSSimon J. Gerraty#		"gens" is a comma separated list of "log":"num" pairs
26c1d01b5fSSimon J. Gerraty#		that allows certain logs to handled differently.
27c1d01b5fSSimon J. Gerraty#
28c1d01b5fSSimon J. Gerraty#	-N	Don't actually do anything, just show us.
29c1d01b5fSSimon J. Gerraty#
30c1d01b5fSSimon J. Gerraty#	-R	Rotate rather than save logs by default.
31c1d01b5fSSimon J. Gerraty#		This is the default anyway.
32c1d01b5fSSimon J. Gerraty#
33c1d01b5fSSimon J. Gerraty#	-S	Save rather than rotate logs by default.
34c1d01b5fSSimon J. Gerraty#		Each log is saved to a unique name that remains
35c1d01b5fSSimon J. Gerraty#		unchanged.  This results in far less churn.
36c1d01b5fSSimon J. Gerraty#
37c1d01b5fSSimon J. Gerraty#	-f "fmt"
38c1d01b5fSSimon J. Gerraty#		Format ('%Y%m%d.%H%M%S') for suffix added to "log" to
39c1d01b5fSSimon J. Gerraty#		uniquely name it when using the '-S' option.
40c1d01b5fSSimon J. Gerraty#		If a "log" is saved more than once per second we add
41c1d01b5fSSimon J. Gerraty#		an extra suffix of our process-id.
42c1d01b5fSSimon J. Gerraty#
43c1d01b5fSSimon J. Gerraty#	-d	The "log" to be rotated/saved is a directory.
44c1d01b5fSSimon J. Gerraty#		We leave the mode of old directories alone.
45c1d01b5fSSimon J. Gerraty#
46c1d01b5fSSimon J. Gerraty#	-e	Normally logs are only cycled if non-empty, this
47c1d01b5fSSimon J. Gerraty#		option forces empty logs to be cycled as well.
48c1d01b5fSSimon J. Gerraty#
49c1d01b5fSSimon J. Gerraty#	-g "group"
50c1d01b5fSSimon J. Gerraty#		Set the group of "log" to "group".
51c1d01b5fSSimon J. Gerraty#
52c1d01b5fSSimon J. Gerraty#	-m "mode"
53c1d01b5fSSimon J. Gerraty#		Set the mode of "log".
54c1d01b5fSSimon J. Gerraty#
55c1d01b5fSSimon J. Gerraty#	-M "mode"
56c1d01b5fSSimon J. Gerraty#		Set the mode of old logs (default 444).
57c1d01b5fSSimon J. Gerraty#
58c1d01b5fSSimon J. Gerraty#	-n "num"
59c1d01b5fSSimon J. Gerraty#		Keep "num" generations of "log".
60c1d01b5fSSimon J. Gerraty#
61c1d01b5fSSimon J. Gerraty#	-o "owner"
62c1d01b5fSSimon J. Gerraty#		Set the owner of "log".
63c1d01b5fSSimon J. Gerraty#
64c1d01b5fSSimon J. Gerraty#	Regardless of whether '-R' or '-S' is provided, we attempt to
65c1d01b5fSSimon J. Gerraty#	choose the correct behavior based on observation of "log.0" if
66c1d01b5fSSimon J. Gerraty#	it exists; if it is a symbolic link, we save, otherwise
67c1d01b5fSSimon J. Gerraty#	we rotate.
68c1d01b5fSSimon J. Gerraty#
69c1d01b5fSSimon J. Gerraty# BUGS:
70c1d01b5fSSimon J. Gerraty#	'Newlog.sh' tries to avoid being fooled by symbolic links, but
71c1d01b5fSSimon J. Gerraty#	multiply indirect symlinks are only handled on machines where
72c1d01b5fSSimon J. Gerraty#	test(1) supports a check for symlinks.
73c1d01b5fSSimon J. Gerraty#
74c1d01b5fSSimon J. Gerraty# AUTHOR:
75c1d01b5fSSimon J. Gerraty#	Simon J. Gerraty <sjg@crufty.net>
76c1d01b5fSSimon J. Gerraty#
77c1d01b5fSSimon J. Gerraty
78c1d01b5fSSimon J. Gerraty# RCSid:
79*c59c3bf3SSimon J. Gerraty#	$Id: newlog.sh,v 1.27 2024/02/17 17:26:57 sjg Exp $
80*c59c3bf3SSimon J. Gerraty#
81*c59c3bf3SSimon J. Gerraty#	SPDX-License-Identifier: BSD-2-Clause
82c1d01b5fSSimon J. Gerraty#
83c1d01b5fSSimon J. Gerraty#	@(#) Copyright (c) 1993-2016 Simon J. Gerraty
84c1d01b5fSSimon J. Gerraty#
85c1d01b5fSSimon J. Gerraty#	This file is provided in the hope that it will
86c1d01b5fSSimon J. Gerraty#	be of use.  There is absolutely NO WARRANTY.
87c1d01b5fSSimon J. Gerraty#	Permission to copy, redistribute or otherwise
88c1d01b5fSSimon J. Gerraty#	use this file is hereby granted provided that
89c1d01b5fSSimon J. Gerraty#	the above copyright notice and this notice are
90c1d01b5fSSimon J. Gerraty#	left intact.
91c1d01b5fSSimon J. Gerraty#
92c1d01b5fSSimon J. Gerraty#	Please send copies of changes and bug-fixes to:
93c1d01b5fSSimon J. Gerraty#	sjg@crufty.net
94c1d01b5fSSimon J. Gerraty#
95c1d01b5fSSimon J. Gerraty
96c1d01b5fSSimon J. GerratyMydir=`dirname $0`
97c1d01b5fSSimon J. Gerratycase $Mydir in
98c1d01b5fSSimon J. Gerraty/*) ;;
99c1d01b5fSSimon J. Gerraty*) Mydir=`cd $Mydir; pwd`;;
100c1d01b5fSSimon J. Gerratyesac
101c1d01b5fSSimon J. Gerraty
102c1d01b5fSSimon J. Gerraty# places to find chown (and setopts.sh)
103c1d01b5fSSimon J. GerratyPATH=$PATH:/usr/etc:/sbin:/usr/sbin:/usr/local/share/bin:/share/bin:$Mydir
104c1d01b5fSSimon J. Gerraty
105c1d01b5fSSimon J. Gerraty# linux doesn't necessarily have compress,
106c1d01b5fSSimon J. Gerraty# and gzip appears in various locations...
107c1d01b5fSSimon J. GerratyWhich() {
108c1d01b5fSSimon J. Gerraty	case "$1" in
109c1d01b5fSSimon J. Gerraty	-*) t=$1; shift;;
110c1d01b5fSSimon J. Gerraty	*) t=-x;;
111c1d01b5fSSimon J. Gerraty	esac
112c1d01b5fSSimon J. Gerraty	case "$1" in
113c1d01b5fSSimon J. Gerraty	/*)	test $t $1 && echo $1;;
114c1d01b5fSSimon J. Gerraty	*)
115c1d01b5fSSimon J. Gerraty		for d in `IFS=:; echo ${2:-$PATH}`
116c1d01b5fSSimon J. Gerraty		do
117c1d01b5fSSimon J. Gerraty			test $t $d/$1 && { echo $d/$1; break; }
118c1d01b5fSSimon J. Gerraty		done
119c1d01b5fSSimon J. Gerraty		;;
120c1d01b5fSSimon J. Gerraty	esac
121c1d01b5fSSimon J. Gerraty}
122c1d01b5fSSimon J. Gerraty
123c1d01b5fSSimon J. Gerraty# shell's typically have test(1) as built-in
124c1d01b5fSSimon J. Gerraty# and not all support all options.
125c1d01b5fSSimon J. Gerratytest_opt() {
126c1d01b5fSSimon J. Gerraty    _o=$1
127c1d01b5fSSimon J. Gerraty    _a=$2
128c1d01b5fSSimon J. Gerraty    _t=${3:-/}
129c1d01b5fSSimon J. Gerraty
130c1d01b5fSSimon J. Gerraty    case `test -$_o $_t 2>&1` in
131c1d01b5fSSimon J. Gerraty    *:*) eval test_$_o=$_a;;
132c1d01b5fSSimon J. Gerraty    *) eval test_$_o=-$_o;;
133c1d01b5fSSimon J. Gerraty    esac
134c1d01b5fSSimon J. Gerraty}
135c1d01b5fSSimon J. Gerraty
136c1d01b5fSSimon J. Gerraty# convert find/ls mode to octal
137c1d01b5fSSimon J. Gerratyfmode() {
138c1d01b5fSSimon J. Gerraty	eval `echo $1 |
139c1d01b5fSSimon J. Gerraty		sed 's,\(.\)\(...\)\(...\)\(...\),ft=\1 um=\2 gm=\3 om=\4,'`
140c1d01b5fSSimon J. Gerraty	sm=
141c1d01b5fSSimon J. Gerraty	case "$um" in
142c1d01b5fSSimon J. Gerraty	*s*)	sm=r
143c1d01b5fSSimon J. Gerraty		um=`echo $um | sed 's,s,x,'`
144c1d01b5fSSimon J. Gerraty		;;
145c1d01b5fSSimon J. Gerraty	*)	sm=-;;
146c1d01b5fSSimon J. Gerraty	esac
147c1d01b5fSSimon J. Gerraty	case "$gm" in
148c1d01b5fSSimon J. Gerraty	*[Ss]*)
149c1d01b5fSSimon J. Gerraty		sm=${sm}w
150c1d01b5fSSimon J. Gerraty		gm=`echo $gm | sed 's,s,x,;s,S,-,'`
151c1d01b5fSSimon J. Gerraty		;;
152c1d01b5fSSimon J. Gerraty	*)	sm=${sm}-;;
153c1d01b5fSSimon J. Gerraty	esac
154c1d01b5fSSimon J. Gerraty	case "$om" in
155c1d01b5fSSimon J. Gerraty	*t)
156c1d01b5fSSimon J. Gerraty		sm=${sm}x
157c1d01b5fSSimon J. Gerraty		om=`echo $om | sed 's,t,x,'`
158c1d01b5fSSimon J. Gerraty		;;
159c1d01b5fSSimon J. Gerraty	*)	sm=${sm}-;;
160c1d01b5fSSimon J. Gerraty	esac
161c1d01b5fSSimon J. Gerraty	echo $sm $um $gm $om |
162c1d01b5fSSimon J. Gerraty	sed 's,rwx,7,g;s,rw-,6,g;s,r-x,5,g;s,r--,4,g;s,-wx,3,g;s,-w-,2,g;s,--x,1,g;s,---,0,g;s, ,,g'
163c1d01b5fSSimon J. Gerraty}
164c1d01b5fSSimon J. Gerraty
165c1d01b5fSSimon J. Gerratyget_mode() {
166c1d01b5fSSimon J. Gerraty	case "$OS,$STAT" in
167c1d01b5fSSimon J. Gerraty	FreeBSD,*)
168c1d01b5fSSimon J. Gerraty		$STAT -f %Op $1 | sed 's,.*\(....\),\1,'
169c1d01b5fSSimon J. Gerraty		return
170c1d01b5fSSimon J. Gerraty		;;
171c1d01b5fSSimon J. Gerraty	esac
172c1d01b5fSSimon J. Gerraty	# fallback to find
173c1d01b5fSSimon J. Gerraty	fmode `find $1 -ls -prune | awk '{ print $3 }'`
174c1d01b5fSSimon J. Gerraty}
175c1d01b5fSSimon J. Gerraty
176c1d01b5fSSimon J. Gerratyget_mtime_suffix() {
177c1d01b5fSSimon J. Gerraty	case "$OS,$STAT" in
178c1d01b5fSSimon J. Gerraty	FreeBSD,*)
179c1d01b5fSSimon J. Gerraty		$STAT -t "${2:-$opt_f}" -f %Sm $1
180c1d01b5fSSimon J. Gerraty		return
181c1d01b5fSSimon J. Gerraty		;;
182c1d01b5fSSimon J. Gerraty	esac
183c1d01b5fSSimon J. Gerraty	# this will have to do
184c1d01b5fSSimon J. Gerraty	date "+${2:-$opt_f}"
185c1d01b5fSSimon J. Gerraty}
186c1d01b5fSSimon J. Gerraty
187c1d01b5fSSimon J. Gerratycase /$0 in
188c1d01b5fSSimon J. Gerraty*/newlog*) rotate_func=rotate_log;;
189c1d01b5fSSimon J. Gerraty*/save*) rotate_func=save_log;;
190c1d01b5fSSimon J. Gerraty*) rotate_func=rotate_log;;
191c1d01b5fSSimon J. Gerratyesac
192c1d01b5fSSimon J. Gerraty
193c1d01b5fSSimon J. Gerratyopt_n=7
194c1d01b5fSSimon J. Gerratyopt_m=
195c1d01b5fSSimon J. Gerratyopt_M=444
196c1d01b5fSSimon J. Gerratyopt_f=%Y%m%d.%H%M%S
197c1d01b5fSSimon J. Gerratyopt_str=dNn:o:g:G:C:M:m:eE:f:RS
198c1d01b5fSSimon J. Gerraty
199c1d01b5fSSimon J. Gerraty. setopts.sh
200c1d01b5fSSimon J. Gerraty
201c1d01b5fSSimon J. Gerratytest $# -gt 0 || exit 0	# nothing to do.
202c1d01b5fSSimon J. Gerraty
203c1d01b5fSSimon J. GerratyOS=${OS:-`uname`}
204c1d01b5fSSimon J. GerratySTAT=${STAT:-`Which stat`}
205c1d01b5fSSimon J. Gerraty
206c1d01b5fSSimon J. Gerraty# sorry, setops semantics for booleans changed.
207c1d01b5fSSimon J. Gerratycase "${opt_d:-0}" in
208c1d01b5fSSimon J. Gerraty0)	rm_f=-f
209c1d01b5fSSimon J. Gerraty	opt_d=-f
210c1d01b5fSSimon J. Gerraty	for x in $opt_C gzip compress
211c1d01b5fSSimon J. Gerraty	do
212c1d01b5fSSimon J. Gerraty		opt_C=`Which $x "/bin:/usr/bin:$PATH"`
213c1d01b5fSSimon J. Gerraty		test -x $opt_C && break
214c1d01b5fSSimon J. Gerraty	done
215c1d01b5fSSimon J. Gerraty	empty() { test ! -s $1; }
216c1d01b5fSSimon J. Gerraty	;;
217c1d01b5fSSimon J. Gerraty*)	rm_f=-rf
218c1d01b5fSSimon J. Gerraty	opt_d=-d
219c1d01b5fSSimon J. Gerraty	opt_M=
220c1d01b5fSSimon J. Gerraty	opt_C=:
221c1d01b5fSSimon J. Gerraty	empty() {
222c1d01b5fSSimon J. Gerraty	    if [ -d $1 ]; then
223c1d01b5fSSimon J. Gerraty		n=`'ls' -a1 $1/. | wc -l`
224c1d01b5fSSimon J. Gerraty		[ $n -gt 2 ] && return 1
225c1d01b5fSSimon J. Gerraty	    fi
226c1d01b5fSSimon J. Gerraty	    return 0
227c1d01b5fSSimon J. Gerraty	}
228c1d01b5fSSimon J. Gerraty	;;
229c1d01b5fSSimon J. Gerratyesac
230c1d01b5fSSimon J. Gerratycase "${opt_N:-0}" in
231c1d01b5fSSimon J. Gerraty0)	ECHO=;;
232c1d01b5fSSimon J. Gerraty*)	ECHO=echo;;
233c1d01b5fSSimon J. Gerratyesac
234c1d01b5fSSimon J. Gerratycase "${opt_e:-0}" in
235c1d01b5fSSimon J. Gerraty0)	force=;;
236c1d01b5fSSimon J. Gerraty*)	force=yes;;
237c1d01b5fSSimon J. Gerratyesac
238c1d01b5fSSimon J. Gerratycase "${opt_R:-0}" in
239c1d01b5fSSimon J. Gerraty0) ;;
240c1d01b5fSSimon J. Gerraty*) rotate_func=rotate_log;;
241c1d01b5fSSimon J. Gerratyesac
242c1d01b5fSSimon J. Gerratycase "${opt_S:-0}" in
243c1d01b5fSSimon J. Gerraty0) ;;
244c1d01b5fSSimon J. Gerraty*) rotate_func=save_log opt_S=;;
245c1d01b5fSSimon J. Gerratyesac
246c1d01b5fSSimon J. Gerraty
247c1d01b5fSSimon J. Gerraty# see whether test handles -h or -L
248c1d01b5fSSimon J. Gerratytest_opt L -h
249c1d01b5fSSimon J. Gerratytest_opt h ""
250c1d01b5fSSimon J. Gerratycase "$test_L,$test_h" in
251c1d01b5fSSimon J. Gerraty-h,) test_L= ;;			# we don't support either!
252c1d01b5fSSimon J. Gerratyesac
253c1d01b5fSSimon J. Gerraty
254c1d01b5fSSimon J. Gerratycase "$test_L" in
255c1d01b5fSSimon J. Gerraty"")	# No, so this is about all we can do...
256c1d01b5fSSimon J. Gerraty	logs=`'ls' -ld $* | awk '{ print $NF }'`
257c1d01b5fSSimon J. Gerraty	;;
258c1d01b5fSSimon J. Gerraty*)	# it does
259c1d01b5fSSimon J. Gerraty	logs="$*"
260c1d01b5fSSimon J. Gerraty	;;
261c1d01b5fSSimon J. Gerratyesac
262c1d01b5fSSimon J. Gerraty
263c1d01b5fSSimon J. Gerratyread_link() {
264c1d01b5fSSimon J. Gerraty	case "$test_L" in
265c1d01b5fSSimon J. Gerraty	"")	'ls' -ld $1 | awk '{ print $NF }'; return;;
266c1d01b5fSSimon J. Gerraty	esac
267c1d01b5fSSimon J. Gerraty	if test $test_L $1; then
268c1d01b5fSSimon J. Gerraty		'ls' -ld $1 | sed 's,.*> ,,'
269c1d01b5fSSimon J. Gerraty	else
270c1d01b5fSSimon J. Gerraty		echo $1
271c1d01b5fSSimon J. Gerraty	fi
272c1d01b5fSSimon J. Gerraty}
273c1d01b5fSSimon J. Gerraty
274c1d01b5fSSimon J. Gerraty# create the new log
275c1d01b5fSSimon J. Gerratynew_log() {
276c1d01b5fSSimon J. Gerraty	log=$1
277c1d01b5fSSimon J. Gerraty	mode=$2
278c1d01b5fSSimon J. Gerraty	if test "x$opt_M" != x; then
279c1d01b5fSSimon J. Gerraty		$ECHO chmod $opt_M $log.0 2> /dev/null
280c1d01b5fSSimon J. Gerraty	fi
281c1d01b5fSSimon J. Gerraty	# someone may have managed to write to it already
282c1d01b5fSSimon J. Gerraty	# so don't truncate it.
283c1d01b5fSSimon J. Gerraty	case "$opt_d" in
284c1d01b5fSSimon J. Gerraty	-d) $ECHO mkdir -p $log;;
285c1d01b5fSSimon J. Gerraty	*) $ECHO touch $log;;
286c1d01b5fSSimon J. Gerraty	esac
287c1d01b5fSSimon J. Gerraty	# the order here matters
288c1d01b5fSSimon J. Gerraty	test "x$opt_o" = x || $ECHO chown $opt_o $log
289c1d01b5fSSimon J. Gerraty	test "x$opt_g" = x || $ECHO chgrp $opt_g $log
290c1d01b5fSSimon J. Gerraty	test "x$mode" = x || $ECHO chmod $mode $log
291c1d01b5fSSimon J. Gerraty}
292c1d01b5fSSimon J. Gerraty
293c1d01b5fSSimon J. Gerratyrotate_log() {
294c1d01b5fSSimon J. Gerraty	log=$1
295c1d01b5fSSimon J. Gerraty	n=${2:-$opt_n}
296c1d01b5fSSimon J. Gerraty
297c1d01b5fSSimon J. Gerraty	# make sure excess generations are trimmed
298c1d01b5fSSimon J. Gerraty	$ECHO rm $rm_f `echo $log.$n | sed 's/\([0-9]\)$/[\1-9]*/'`
299c1d01b5fSSimon J. Gerraty
300c1d01b5fSSimon J. Gerraty	mode=${opt_m:-`get_mode $log`}
301c1d01b5fSSimon J. Gerraty	while test $n -gt 0
302c1d01b5fSSimon J. Gerraty	do
303c1d01b5fSSimon J. Gerraty		p=`expr $n - 1`
304c1d01b5fSSimon J. Gerraty		if test -s $log.$p; then
305c1d01b5fSSimon J. Gerraty			$ECHO rm $rm_f $log.$p.*
306c1d01b5fSSimon J. Gerraty			$ECHO $opt_C $log.$p
307c1d01b5fSSimon J. Gerraty			if test "x$opt_M" != x; then
308c1d01b5fSSimon J. Gerraty				$ECHO chmod $opt_M $log.$p.* 2> /dev/null
309c1d01b5fSSimon J. Gerraty			fi
310c1d01b5fSSimon J. Gerraty		fi
311c1d01b5fSSimon J. Gerraty		for ext in $opt_E .gz .Z ""
312c1d01b5fSSimon J. Gerraty		do
313c1d01b5fSSimon J. Gerraty			test $opt_d $log.$p$ext || continue
314c1d01b5fSSimon J. Gerraty			$ECHO mv $log.$p$ext $log.$n$ext
315c1d01b5fSSimon J. Gerraty		done
316c1d01b5fSSimon J. Gerraty		n=$p
317c1d01b5fSSimon J. Gerraty	done
318c1d01b5fSSimon J. Gerraty	# leave $log.0 uncompressed incase some one still has it open.
319c1d01b5fSSimon J. Gerraty	$ECHO mv $log $log.0
320c1d01b5fSSimon J. Gerraty	new_log $log $mode
321c1d01b5fSSimon J. Gerraty}
322c1d01b5fSSimon J. Gerraty
323c1d01b5fSSimon J. Gerraty# unlike rotate_log we do not rotate files,
324c1d01b5fSSimon J. Gerraty# but give each log a unique (but stable name).
325c1d01b5fSSimon J. Gerraty# This avoids churn for folk who rsync things.
326c1d01b5fSSimon J. Gerraty# We make log.0 a symlink to the most recent log
327c1d01b5fSSimon J. Gerraty# so it can be found and compressed next time around.
328c1d01b5fSSimon J. Gerratysave_log() {
329c1d01b5fSSimon J. Gerraty	log=$1
330c1d01b5fSSimon J. Gerraty	n=${2:-$opt_n}
331c1d01b5fSSimon J. Gerraty	fmt=$3
332c1d01b5fSSimon J. Gerraty
333c1d01b5fSSimon J. Gerraty	last=`read_link $log.0`
334c1d01b5fSSimon J. Gerraty	case "$last" in
335c1d01b5fSSimon J. Gerraty	$log.0) # should never happen
336c1d01b5fSSimon J. Gerraty		test -s $last && $ECHO mv $last $log.$$;;
337c1d01b5fSSimon J. Gerraty	$log.*)
338c1d01b5fSSimon J. Gerraty		$ECHO $opt_C $last
339c1d01b5fSSimon J. Gerraty		;;
340c1d01b5fSSimon J. Gerraty	*.*)	$ECHO $opt_C `dirname $log`/$last
341c1d01b5fSSimon J. Gerraty		;;
342c1d01b5fSSimon J. Gerraty	esac
343c1d01b5fSSimon J. Gerraty	$ECHO rm -f $log.0
344c1d01b5fSSimon J. Gerraty	# remove excess logs - we rely on mtime!
345c1d01b5fSSimon J. Gerraty	$ECHO rm $rm_f `'ls' -1td $log.* 2> /dev/null | sed "1,${n}d"`
346c1d01b5fSSimon J. Gerraty
347c1d01b5fSSimon J. Gerraty	mode=${opt_m:-`get_mode $log`}
348c1d01b5fSSimon J. Gerraty	# this is our default suffix
349c1d01b5fSSimon J. Gerraty	opt_S=${opt_S:-`get_mtime_suffix $log $fmt`}
350c1d01b5fSSimon J. Gerraty	case "$fmt" in
351c1d01b5fSSimon J. Gerraty	""|$opt_f) suffix=$opt_S;;
352c1d01b5fSSimon J. Gerraty	*) suffix=`get_mtime_suffix $log $fmt`;;
353c1d01b5fSSimon J. Gerraty	esac
354c1d01b5fSSimon J. Gerraty
355c1d01b5fSSimon J. Gerraty	# find a unique name to save current log as
356c1d01b5fSSimon J. Gerraty	for nlog in $log.$suffix $log.$suffix.$$
357c1d01b5fSSimon J. Gerraty	do
358c1d01b5fSSimon J. Gerraty		for f in $nlog*
359c1d01b5fSSimon J. Gerraty		do
360c1d01b5fSSimon J. Gerraty			break
361c1d01b5fSSimon J. Gerraty		done
362c1d01b5fSSimon J. Gerraty		test $opt_d $f || break
363c1d01b5fSSimon J. Gerraty	done
364c1d01b5fSSimon J. Gerraty	# leave $log.0 uncompressed incase some one still has it open.
365c1d01b5fSSimon J. Gerraty	$ECHO mv $log $nlog
366c1d01b5fSSimon J. Gerraty	test "x$opt_M" = x || $ECHO chmod $opt_M $nlog 2> /dev/null
367c1d01b5fSSimon J. Gerraty	$ECHO ln -s `basename $nlog` $log.0
368c1d01b5fSSimon J. Gerraty	new_log $log $mode
369c1d01b5fSSimon J. Gerraty}
370c1d01b5fSSimon J. Gerraty
371c1d01b5fSSimon J. Gerratyfor f in $logs
372c1d01b5fSSimon J. Gerratydo
373c1d01b5fSSimon J. Gerraty	n=$opt_n
374c1d01b5fSSimon J. Gerraty	save=
375c1d01b5fSSimon J. Gerraty	case "$f" in
376c1d01b5fSSimon J. Gerraty	*:[1-9]*)
377c1d01b5fSSimon J. Gerraty		set -- `IFS=:; echo $f`; f=$1; n=$2;;
378c1d01b5fSSimon J. Gerraty	*:n=*|*:save=*)
379c1d01b5fSSimon J. Gerraty		eval `echo "f=$f" | tr ':' ' '`;;
380c1d01b5fSSimon J. Gerraty	esac
381c1d01b5fSSimon J. Gerraty	# try and pick the right function to use
382c1d01b5fSSimon J. Gerraty	rfunc=$rotate_func	# default
383c1d01b5fSSimon J. Gerraty	if test $opt_d $f.0; then
384c1d01b5fSSimon J. Gerraty		case `read_link $f.0` in
385c1d01b5fSSimon J. Gerraty		$f.0) rfunc=rotate_log;;
386c1d01b5fSSimon J. Gerraty		*) rfunc=save_log;;
387c1d01b5fSSimon J. Gerraty		esac
388c1d01b5fSSimon J. Gerraty	fi
389c1d01b5fSSimon J. Gerraty	case "$test_L" in
390c1d01b5fSSimon J. Gerraty	-?)
391c1d01b5fSSimon J. Gerraty		while test $test_L $f	# it is [still] a symlink
392c1d01b5fSSimon J. Gerraty		do
393c1d01b5fSSimon J. Gerraty			f=`read_link $f`
394c1d01b5fSSimon J. Gerraty		done
395c1d01b5fSSimon J. Gerraty		;;
396c1d01b5fSSimon J. Gerraty	esac
397c1d01b5fSSimon J. Gerraty	case ",${opt_G}," in
398c1d01b5fSSimon J. Gerraty	*,${f}:n=*|,${f}:save=*)
399c1d01b5fSSimon J. Gerraty		eval `echo ",${opt_G}," | sed "s!.*,${f}:\([^,]*\),.*!\1!;s,:, ,g"`
400c1d01b5fSSimon J. Gerraty		;;
401c1d01b5fSSimon J. Gerraty	*,${f}:*)
402c1d01b5fSSimon J. Gerraty		# opt_G is a , separated list of log:n pairs
403c1d01b5fSSimon J. Gerraty		n=`echo ,$opt_G, | sed -e "s,.*${f}:\([0-9][0-9]*\).*,\1,"`
404c1d01b5fSSimon J. Gerraty		;;
405c1d01b5fSSimon J. Gerraty	esac
406c1d01b5fSSimon J. Gerraty
407c1d01b5fSSimon J. Gerraty	if empty $f; then
408c1d01b5fSSimon J. Gerraty		test "$force" || continue
409c1d01b5fSSimon J. Gerraty	fi
410c1d01b5fSSimon J. Gerraty
411c1d01b5fSSimon J. Gerraty	test "$save" && rfunc=save_log
412c1d01b5fSSimon J. Gerraty
413c1d01b5fSSimon J. Gerraty	$rfunc $f $n $save
414c1d01b5fSSimon J. Gerratydone
415