#!/bin/sh ######################################################################### # ADMINISTRATION LOG - Log administrative changes to the system here. # # This software is public domain. The latest version of this software # is available from http://seriss.com/people/erco/unixtools # # 1.00 ??/??/97 erco@3dsite.com # ######################################################################### ################## ### FUNCTIONS ################## # LOCK THE FILE # $1 - original filename Lock() { if mv $1 $1.lock; then return 0; fi echo $PROGNAME: ${DBASE}: 2>&1 echo $PROGNAME: someone has the file locked 2>&1 exit 1 } # UNLOCK THE FILE # $1 - original filename Unlock() { if mv $1.lock $1; then return 0; fi echo "$PROGNAME: HELP: your changes are stuck in $1.lock!" echo "$PROGNAME: HELP: You must 'mv $1.lock $1' by hand" exit 1 } # TEMP COPY OF LOCKED OR UNLOCKED VERSION # $1 - original filename # $2 - temp copy filename # TempCopy() { # IF NEITHER ORIGINAL NOR LOCKED EXISTS, FAIL if [ ! -f $1 -a ! -f $1.lock ]; then # CHECK AGAIN INCASE OF RACE CONDITION sleep 1; if [ ! -f $1 -a ! -f $1.lock ]; then echo "$PROGNAME: FAIL: Can't find $1 or $1.lock" exit 1 fi fi while [ 1 ]; do # FIRST, TRY UNLOCKED FILE if cp $1 $2 2> /dev/null; then return 0; fi # SECOND, TRY LOCKED FILE if cp $1.lock $2 2> /dev/null; then return 0; fi # RACE CONDITION? TRY AGAIN sleep 1 done } # JUST EDIT THE FILE (ASSUME LOCKING HANDLED) # $1 - filename Edit() { ${EDITOR:-vi} $1 } # CHECK THE USER ID # $1 - uid to check UidCheck() { ID=`id | sed 's/uid=//;s/(.*$//'` if [ "$ID" != 0 ]; then echo "$PROGNAME: you must be root to edit the log" exit 1 fi return 0; } # MAKE A FOUR LEVEL BACKUP OF THE FILE (..just incase..) # $1 - filename to backup # $2 - actual name for backup copy Backup() { if [ -f $2.3 ]; then mv $2.3 $2.4; fi if [ -f $2.2 ]; then mv $2.2 $2.3; fi if [ -f $2.1 ]; then mv $2.1 $2.2; fi cp $1 $2.1 } # PREPEND A NEW ENTRY TO THE LOG # $1 - filename DateStamp() { # PREPEND DATE STAMP # Just be sure to add it AFTER any comments at the top if $NAWK ' BEGIN { tarr = 0; flag = 1; # GET THE DATE cmd = "date +%D,%T"; cmd | getline date; close(cmd); # GET THE LOGIN NAME cmd = "logname"; cmd | getline logname; close(cmd); } # MIDDLE { if (flag && $1 != "#") { arr[tarr++] = \ "--- "date" - "logname": YOUR_ONE_LINE_DESCRIPTION"; arr[tarr++] = ""; arr[tarr++] = " Your_multi_line_comments_here"; arr[tarr++] = ""; flag = 0; } arr[tarr++] = $0; } END { # OVERWRITE THE INPUT FILE WITH MODIFIED DATA out = "'$1'"; # the output filename for (t=0; t out; close(out); }' $1; then return 0; fi echo "${PROGNAME}: error prepending date info - aborting" return 1; } # PRINT HELP AND EXIT # No arguments HelpAndExit() { cat << EOF NAME: admlog - when changes are made to the system, log them here USAGE: admlog - Show the log in more(1) admlog -v[iew] - View the log in vi (you can't change it) admlog -e[dit] - Edit the log in vi (must be root) admlog -n[ew] - Create new entry in log admlog -h[elp] - help The -new and -edit options put a lock on the log file to prevent more than one person from editing the file. EOF exit 1 } ################## ### INITIALIZATION ################## umask 022 NAWK=gawk PROGNAME=admlog DBASEDIR=/home/local/data/$PROGNAME DBASE=${DBASEDIR}/$PROGNAME DBASELOCK=${DBASE}.lock TMP=/usr/tmp/$PROGNAME.$$ ################## ### MAIN ################## trap "echo ${PROGNAME}': killed (removing crap)'; rm -f ${TMP} 2>/dev/null" 3 15 case "$1" in "") TempCopy ${DBASE} ${TMP} more ${TMP} rm -f ${TMP} exit 0 ;; -view|-v) TempCopy ${DBASE} ${TMP} Edit ${TMP} rm -f ${TMP} exit 0 ;; -edit|-e) UidCheck 0 Lock ${DBASE} Backup ${DBASELOCK} ${DBASE} Edit ${DBASELOCK} Unlock ${DBASE} exit 0 ;; -new|-n) UidCheck 0 Lock ${DBASE} Backup ${DBASELOCK} ${DBASE} DateStamp ${DBASELOCK} Edit ${DBASELOCK} Unlock ${DBASE} exit 0 ;; -|-h|-help) HelpAndExit ;; *) echo ${PROGNAME}: unknown option $1 exit 1 ;; esac fi exit 0 fi