diff options
author | Clint Adams <schizo@debian.org> | 2005-06-21 23:30:25 +0000 |
---|---|---|
committer | Clint Adams <schizo@debian.org> | 2005-06-21 23:30:25 +0000 |
commit | c2a1c435ef5e7d590328802ce333de410ce40cb6 (patch) | |
tree | 6095e344242e76daf58d6d42afc5ca29673d2a0a /savelog | |
download | debianutils-c2a1c435ef5e7d590328802ce333de410ce40cb6.tar.gz |
tag of schizo@debian.org--2004-primary/debianutils--etch--0--version-0
(automatically generated log message)
git-archimport-id: schizo@debian.org--etch/debianutils--etch--0--base-0
Diffstat (limited to 'savelog')
-rw-r--r-- | savelog | 301 |
1 files changed, 301 insertions, 0 deletions
@@ -0,0 +1,301 @@ +#! /bin/sh +# savelog - save a log file +# Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll +# Copyright (C) 1992 Ronald S. Karr +# Slight modifications by Ian A. Murdock <imurdock@gnu.ai.mit.edu>: +# * uses `gzip' rather than `compress' +# * doesn't use $savedir; keeps saved log files in the same directory +# * reports successful rotation of log files +# * for the sake of consistency, files are rotated even if they are +# empty +# More modifications by Guy Maor <maor@debian.org>: +# * cleanup. +# * -p (preserve) option +# +# usage: savelog [-m mode] [-u user] [-g group] [-t] [-p] [-c cycle] +# [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file... +# -m mode - chmod log files to mode +# -u user - chown log files to user +# -g group - chgrp log files to group +# -c cycle - save cycle versions of the logfile (default: 7) +# -r rolldir- use rolldir instead of . to roll files +# -C - force cleanup of cycled logfiles +# -d - use standard date for rolling +# -t - touch file +# -l - don't compress any log files (default: compress) +# -p - preserve mode/user/group of original file +# -j - use bzip2 instead of gzip +# -n - do not rotate empty files +# -q - be quiet +# file - log file names +# +# The savelog command saves and optionally compresses old copies of files. +# Older version of 'file' are named: +# +# 'file'.<number><compress_suffix> +# +# where <number> is the version number, 0 being the newest. By default, +# version numbers > 0 are compressed (unless -l prevents it). The +# version number 0 is never compressed on the off chance that a process +# still has 'file' opened for I/O. +# +# if the '-d' option is specified, <number> will be YYMMDDhhmmss +# +# If the 'file' does not exist and -t was given, it will be created. +# +# For files that do exist and have lengths greater than zero, the following +# actions are performed. +# +# 1) Version numered files are cycled. That is version 6 is moved to +# version 7, version is moved to becomes version 6, ... and finally +# version 0 is moved to version 1. Both compressed names and +# uncompressed names are cycled, regardless of -t. Missing version +# files are ignored. +# +# 2) The new file.1 is compressed and is changed subject to +# the -m, -u and -g flags. This step is skipped if the -t flag +# was given. +# +# 3) The main file is moved to file.0. +# +# 4) If the -m, -u, -g, -t, or -p flags are given, then the file is +# touched into existence subject to the given flags. The -p flag +# will preserve the original owner, group, and permissions. +# +# 5) The new file.0 is changed subject to the -m, -u and -g flags. +# +# Note: If no -m, -u, -g, -t, or -p is given, then the primary log file is +# not created. +# +# Note: Since the version numbers start with 0, version number <cycle> +# is never formed. The <cycle> count must be at least 2. +# +# Bugs: If a process is still writing to the file.0 and savelog +# moved it to file.1 and compresses it, data could be lost. +# Smail does not have this problem in general because it +# restats files often. + +# common location +export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin +COMPRESS="gzip -9f" +DOT_Z=".gz" +DATUM=`date +%Y%m%d%H%M%S` + +# parse args +exitcode=0 # no problems to far +prog=`basename $0` +mode= +user= +group= +touch= +forceclean= +rolldir= +datum= +preserve= +quiet=0 +rotateifempty=yes +count=7 + +usage() +{ + echo "Usage: $prog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-p]" + echo " [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file ..." + echo " -m mode - chmod log files to mode" + echo " -u user - chown log files to user" + echo " -g group - chgrp log files to group" + echo " -c cycle - save cycle versions of the logfile (default: 7)" + echo " -r rolldir - use rolldir instead of . to roll files" + echo " -C - force cleanup of cycled logfiles" + echo " -d - use standard date for rolling" + echo " -t - touch file" + echo " -l - don't compress any log files (default: compress)" + echo " -p - preserve mode/user/group of original file" + echo " -j - use bzip2 instead of gzip" + echo " -n - do not rotate empty files" + echo " -q - suppress rotation message" + echo " file - log file names" +} + + +fixfile() +{ + if [ -n "$user" ]; then + chown -- "$user" "$1" + fi + if [ -n "$group" ]; then + chgrp -- "$group" "$1" + fi + if [ -n "$mode" ]; then + chmod -- "$mode" "$1" + fi +} + + +while getopts m:u:g:c:r:Cdtlphjnq opt ; do + case "$opt" in + m) mode="$OPTARG" ;; + u) user="$OPTARG" ;; + g) group="$OPTARG" ;; + c) count="$OPTARG" ;; + r) rolldir="$OPTARG" ;; + C) forceclean=1 ;; + d) datum=1 ;; + t) touch=1 ;; + j) COMPRESS="bzip2 -9f" ; DOT_Z=".bz2" ;; + l) COMPRESS="" ;; + p) preserve=1 ;; + n) rotateifempty="no" ;; + q) quiet=1 ;; + h) usage; exit 0 ;; + *) usage; exit 1 ;; + esac +done + +shift $(($OPTIND - 1)) + +if [ "$count" -lt 2 ]; then + echo "$prog: count must be at least 2" 1>&2 + exit 2 +fi + +# cycle thru filenames +while [ $# -gt 0 ]; do + + # get the filename + filename="$1" + shift + + # catch bogus files + if [ -e "$filename" ] && [ ! -f "$filename" ]; then + echo "$prog: $filename is not a regular file" 1>&2 + exitcode=3 + continue + fi + + # if not a file or empty, do nothing major + # (in the Debian version, we rotate even if empty by default) + if [ ! -s "$filename" ] && [ "$rotateifempty" != "yes" ]; then + # if -t was given and it does not exist, create it + if test -n "$touch" && [ ! -f "$filename" ]; then + touch -- "$filename" + if [ "$?" -ne 0 ]; then + echo "$prog: could not touch $filename" 1>&2 + exitcode=4 + continue + fi + fixfile "$filename" + fi + continue + fi + + # be sure that the savedir exists and is writable + # (Debian default: $savedir is . and not ./OLD) + savedir=`dirname -- "$filename"` + if [ -z "$savedir" ]; then + savedir=. + fi + savedir="$savedir/$rolldir" + if [ ! -d "$savedir" ]; then + mkdir -p -- "$savedir" + if [ "$?" -ne 0 ]; then + echo "$prog: could not mkdir $savedir" 1>&2 + exitcode=5 + continue + fi + chmod 0755 -- "$savedir" + fi + if [ ! -w "$savedir" ]; then + echo "$prog: directory $savedir is not writable" 1>&2 + exitcode=7 + continue + fi + + # determine our uncompressed file names + newname=`basename -- "$filename"` + newname="$savedir/$newname" + + # cycle the old compressed log files + cycle=$(( $count - 1)) + rm -f -- "$newname.$cycle" "$newname.$cycle$DOT_Z" + while [ $cycle -gt 1 ]; do + # --cycle + oldcycle=$cycle + cycle=$(( $cycle - 1 )) + # cycle log + if [ -f "$newname.$cycle$DOT_Z" ]; then + mv -f -- "$newname.$cycle$DOT_Z" \ + "$newname.$oldcycle$DOT_Z" + fi + if [ -f "$newname.$cycle" ]; then + # file was not compressed. move it anyway + mv -f -- "$newname.$cycle" "$newname.$oldcycle" + fi + done + + # compress the old uncompressed log if needed + if [ -f "$newname.0" ]; then + if [ -z "$COMPRESS" ]; then + newfile="$newname.1" + mv -- "$newname.0" "$newfile" + else + newfile="$newname.1$DOT_Z" +# $COMPRESS < $newname.0 > $newfile +# rm -f $newname.0 + $COMPRESS "$newname.0" + mv -- "$newname.0$DOT_Z" "$newfile" + fi + fixfile "$newfile" + fi + + # compress the old uncompressed log if needed + if test -n "$datum" && test -n "$COMPRESS"; then + $COMPRESS -- "$newname".[0-9]*[0-9] + fi + + # remove old files if so desired + if [ -n "$forceclean" ]; then + cycle=$(( $count - 1)) + if [ -z "$COMPRESS" ]; then + rm -f -- `ls -t -- $newname.[0-9]* | sed -e 1,${cycle}d` + else + rm -f -- `ls -t -- $newname.[0-9]*$DOT_Z | sed -e 1,${cycle}d` + fi + fi + + # create new file if needed + if [ -n "$preserve" ]; then + (umask 077 + touch -- "$filename.new" + chown --reference="$filename" -- "$filename.new" + chmod --reference="$filename" -- "$filename.new") + filenew=1 + elif [ -n "$touch$user$group$mode" ]; then + touch -- "$filename.new" + fixfile "$filename.new" + filenew=1 + fi + + # link the file into the file.0 holding place + if [ -f "$filename" ]; then + if [ -n "$filenew" ]; then + if ln -f -- "$filename" "$newname.0"; then + mv -- "$filename.new" "$filename" + else + echo "Error hardlinking $filename to $newname.0" >&2 + exitcode=8 + continue + fi + else + mv -- "$filename" "$newname.0" + fi + fi + [ ! -f "$newname.0" ] && touch -- "$newname.0" + fixfile "$newname.0" + if [ -n "$datum" ]; then + mv -- "$newname.0" "$newname.$DATUM" + fi + + # report successful rotation + test "$quiet" -eq 1 || echo "Rotated \`$filename' at `date`." +done +exit $exitcode |