#!/bin/ksh
# orbit: rotate log files around
# usage: orbit <filename> <archives-to-keep>
# defaults to 7 archives + one working version
#
# Copyright (c) 1989, 1991, 1997  by The Trustees of Columbia University in
# the City of New York.  Permission is granted to any individual or
# institution to use, copy, or redistribute this software so long as it
# is not sold for profit, provided this copyright notice is retained.

function usage
{
   echo "usage: orbit [-c] [-l length] [-z | -g] [ -s SIG ] [ -p pid ] [ -U user ] [ -G group ] [ -M archive-file-mode ] [ -m main-file-mode ] <filename> <archives-to-keep>"
   exit 1
}

if [ $# = 0 ]; then		# just orbit
    usage
fi

if [ -f /etc/vfstab ]; then 
    COMPRESS=/usr/bin/compress
    CHOWN=/usr/ucb/chown
else
    COMPRESS=/usr/ucb/compress
    CHOWN=/etc/chown
fi
GZIPCMD=/usr/local/bin/gzip
CHGRP=/usr/bin/chgrp
CHMOD=/usr/bin/chmod

#defaults
tonum=7
docopy=0
compressit=0
gzip=0
sig=HUP
amode=640

while :
do
    case $1 in
      -c)
	docopy=1
	;;
      -l)
	shift
	length=$1
	;;
      -z)
	compressit=1
	;;
      -g)
	gzip=1
	;;   
      -s)
        shift
        sig=$1
        ;;
      -p)
        shift
	pid=$1
        ;;
      -U)
        shift
	user=$1
	;;
      -G)
        shift
	grp=$1
	;;
      -M)
        shift
	amode=$1
	;;
      -m)
        shift
	mmode=$1
	;;
      *)
	break
	;;
    esac
    shift
done

if [ $# = 0 ]; then		# no filenames
    usage
fi

if [ "$mmode" = "" ]; then
    mmode=$amode
fi

if [ $# = 2 ]; then
    tonum=$2
fi

file=$1

if [ "$length" != "" ]; then	# orbit only if longer
    size=`ls -s $file | awk '{print $1}'`
    if [ $size -lt $length ]; then	# too short, don't orbit
	exit
    fi
fi

let fromnum=$tonum-1		# mv foo.3 foo.4

# remove the oldest file before we start
if [ -f $file.$tonum ]; then
    /bin/rm -f $file.$tonum
fi
if [ -f $file.$tonum.Z ]; then
    /bin/rm -f $file.$tonum.Z
fi
if [ -f $file.$tonum.gz ]; then
    /bin/rm -f $file.$tonum.gz
fi

# mv file.(n-1) to file.n up to file.1 to file.2
while [ $fromnum != 0 ]; do
    if [ -f $file.$fromnum ]; then
        mv $file.$fromnum $file.$tonum
    elif [ -f $file.$fromnum.Z ]; then
        mv $file.$fromnum.Z $file.$tonum.Z
    elif [ -f $file.$fromnum.gz ]; then
        mv $file.$fromnum.gz $file.$tonum.gz
    fi
    tonum=$fromnum
    let fromnum=$fromnum-1
done

# handle the file -> file.1 case
if [ $docopy = 1 ] && [ $compressit = 1 ] && [ -s $file ]; then
    $COMPRESS < $file > $file.1.Z
    $CHMOD $amode $file.1.Z
    if [ "$user" != "" ]; then
	$CHOWN $user $file.1.Z
    fi
    if [ "$grp" != "" ]; then
	$CHGRP $grp $file.1.Z
    fi
elif [ $docopy = 1 ] && [ $gzip = 1 ] && [ -s $file ]; then
    $GZIPCMD -9 -c $file > $file.1.gz
    $CHMOD $amode $file.1.gz
    if [ "$user" != "" ]; then
	$CHOWN $user $file.1.gz
    fi
    if [ "$grp" != "" ]; then
	$CHGRP $grp $file.1.gz
    fi
elif [ $docopy = 1 ]; then
    cp $file $file.1
    $CHMOD $amode $file.1
    if [ "$user" != "" ]; then
	$CHOWN $user $file.1
    fi
    if [ "$grp" != "" ]; then
	$CHGRP $grp $file.1
    fi
else	
    # all of the above were copy cases (leaving original intact)
    # this case is for a move, creating a new original file
    mv $file $file.1
    $CHMOD $amode $file.1
    touch $file
    $CHMOD $mmode $file
    if [ "$user" != "" ]; then
	$CHOWN $user $file
    fi
    if [ "$grp" != "" ]; then
	$CHGRP $grp $file
    fi
fi

# see if we should send a signal somewhere before a potentially long compress
# (e.g. we may need to HUP syslog if we did a move above)
if [ "$pid" != "" ]; then
    kill -$sig $pid
fi

# gzip/compress if necessary
if [ $gzip = 1 ] && [ -s $file.1 ]; then
    $GZIPCMD -9 $file.1
elif [ $compressit = 1 ] && [ -s $file.1 ]; then
    $COMPRESS $file.1
fi

exit 0
