pda@Dixie.Com (Paul D. Anderson) (03/23/91)
Setlock is a program that can be used by shell scripts to set and clear System V uucp-style lock files (located in /usr/spool/locks). Setlock always reads the lock file, testing to see if the process indicated in the lock file is still active, before performing any indicated action. Setlock exits such that an exit code of '0' always means "action completed successfully". Failure exit codes from setlock are not symmetrical. Each exit code carries a specific meaning corresponding to the action given by a specific switch. I would appreciate any feedback regarding portability and enhancements. I hope you find this as useful as I have found it already, here. -paul Submitted-by: pda@Dixie.Com Archive-name: setlock/part01 ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is setlock, a shell archive (shar 3.43) # made 03/23/1991 11:28 UTC by pda@Dixie.Com # Source directory /usr/local/tools/setlock # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 5692 -r--rw---- setlock.c # 740 -r--r--r-- makefile # 1928 -r--r--r-- README # 4924 -r--r--r-- setlock.1 # 4866 -r--rw---- dotest # 3521 -rwxrwx--- Hourly # 614 -rwxrw---- gettyclear # 778 -r-xrwx--- log # # ============= setlock.c ============== if test -f 'setlock.c' -a X"$1" != X"-c"; then echo 'x - skipping setlock.c (File already exists)' else echo 'x - extracting setlock.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'setlock.c' && X /* Setlock - test for a lock file and set up a lock. X Copyright 1991 Paul D. Anderson, All Rights Reserved Worldwide X X License Agreement: X You may use this program for any legal purpose, but you may X not sell it. You may not pretend that you wrote it. X */ X #include <stdio.h> #include <ctype.h> #include <string.h> #include <errno.h> X X usage() { X static char *utext[] = { X X "setlock -l lockname -p lockpid [ -f | -s | -r | -t | -R ] [-v]", #ifndef SHORTHELP X " -l lockname ... name of the lockfile ", X " -p lockpid ... pid to write to lockfile (and to test for)", X " -f ... freshen lock file - touch it with current pid again", X " -s ... set the lock", X " -r ... remove the lock, only if it matches lockpid", X " -R ... remove the lock, iff the lock is invalid,", X " even if it doesn't match lockpid", X " -t ... test to see if the lock is valid", X " -v ... say the exit code to stdout", X "", X "exit codes:", X " 0 ... action performed OK", X " 1 ... unable to set lock (current lockfile valid)", X " 2 ... did not remove lock (pid passed doesn't match lockfile)", X " 3 ... unable to freshen lock file, file does not exist", X " 4 ... unable to freshen lock file, file found but process is dead", X " 5 ... unable to freshen lock file, lock file not owned by you", X " 6 ... lock is not valid, process is gone.", X " 7 ... lock file does not exist", X " 8 ... pid specified on command line is not active", X " 9 ... unable to remove lock file not owned by you, still active", X " 50 ... unable to perform action, other error occurred", X "", X " 100 ... program exited due to error" #else X "" #endif X }; X X int i; X X for (i=0; i<sizeof utext/sizeof (char *); ++i) X puts(utext[i]); } X #ifndef LCKPATH #define LCKPATH "/usr/spool/locks" #endif X static char sccsid[] = { "@(#) setlock.c 1.5 91/03/19 20:43:23" }; X extern int errno; X int vflg = 0; X main(ac,av) int ac; char *av[]; { X int c, lockpid, pid=0, fflg=0,sflg=0,rflg=0,tflg=0,errflg=0; X int Rflg=0; X char *cp, *lockname=0, buf[128], path[128]; X extern char *optarg; X X while ((c=getopt(ac,av,"l:p:ftsrvR"))!= -1) { X switch (c) { X case 'l': lockname=optarg; break; X case 'p': pid=atoi(optarg); break; X case 'f': ++fflg; break; X case 't': ++tflg; break; X case 's': ++sflg; break; X case 'r': ++rflg; break; X case 'R': ++Rflg; break; X case 'v': ++vflg; break; X case '?': errflg++; break; X }} X X if ( X (errflg || Rflg+tflg+fflg+sflg+rflg > 1 || !lockname) X || ( !(Rflg || tflg ) && !pid ) X || ( ( Rflg || tflg ) && pid ) X ) { X usage(); X die(100); X } X X /* make sure the given pid is for real */ X if ( pid && ! testpid(pid) ) die(8); X X /* if there is a slash in the lockname, then assume a path X has been specified, as this dude may want a lock in a directory X other than /usr/spool/locks... */ X X if (strchr(lockname,'/')) { strcpy(path,lockname); } X else sprintf(path,"%s/%s",LCKPATH, lockname); X X /* test for a valid lockfile */ X if (tflg) { X switch (lockpid=valid(path)) { X case -1: die(7); /* lock file not found */ X case 0: die(6); /* lock found, lock inactive */ X default: die(0); /* process is still active */ X } X } X X /* remove the lock file */ X if (rflg || Rflg ) { X switch(lockpid=valid(path)) { X case -1: die(0); /* lock file not there, so exit ok */ X case 0: /* lock there, but inactive, so rm it */ X unlink(path); X die(0); X default: X /* lock is there and active */ X if (Rflg) die(9); X /* rflg - rmove the lock iff its ours. */ X if ( rflg && pid == lockpid ) { X unlink(path); X die(0); X } else { X die(2); /* pid in lock file doesn't match our pid */ X } X } X } X X /* set a lock file */ X if (sflg) { X switch(lockpid=valid(path)) { X case -1: /* lock file not found */ X case 0: /* lock found but process dead */ X if (set(path,pid)) die(0); /* write the lock file */ X else die(50); X default: X die(1); /* lock is valid, can't set one */ X } X } X X /* freshen the lock file */ X if (fflg) { X switch(lockpid=valid(path)) { X case -1: /* lock file not found */ X die(3); X case 0: /* lock found but process dead */ X die(4); X default: /* lock is valid, can't set one */ X if ( lockpid != pid ) die(5); /* not owned by me */ X else if ( freshen(path,pid) ) die(0); X else die(50); X } X } X X die(100); } X /* returns -1 if lock file is not found. X 0 if there is a lock file, but process is dead and X 'pid' of process if process is still active */ X valid(path) char *path; { X FILE *fp; X char buf[20]; X int pid, rc, saveerrno; X X /* try to get the lock pid - if we can't open the file, then X presume the lock is invalid. So return a 1 to say that the X process is dead. (a non-readable lock file is incorrectly X formed and we needn't try any further error recovery) */ X X if ( access(path,0) ) return -1; X if ( (fp=fopen(path,"r")) == (FILE *)0 ) return -1; X X fgets(buf,sizeof buf,fp); X fclose(fp); X X return testpid(atoi(buf)); } X testpid(pid) { X int rc; X X rc = kill(pid,0); X X /* we should return 1 if the process is active */ X switch(rc) { X case 0: /* it's our process and must be alive, so return ok */ X return pid; X default: /* it's someone else's process or doesn't exist... */ X switch(errno) { X case ESRCH: /* process doesn't exist */ X return 0; X default: /* something else happened, but process is alive */ X return pid; X } X } } X set(path,pid) char *path; { X FILE *fp; X X if ( (fp=fopen(path,"w")) == (FILE *) 0) return 0; X X fprintf(fp,"%10ld\n",(long)pid); X fclose(fp); X return 1; } X freshen(path,pid) char *path; { X FILE *fp; X X if ( (fp=fopen(path,"r+")) == (FILE *) 0) return 0; X X fprintf(fp,"%10ld\n",(long)pid); X fclose(fp); X return 1; } X die(code) { X if (vflg) printf("%d\n",code); X exit(code); } SHAR_EOF chmod 0460 setlock.c || echo 'restore of setlock.c failed' Wc_c="`wc -c < 'setlock.c'`" test 5692 -eq "$Wc_c" || echo 'setlock.c: original size 5692, current size' "$Wc_c" fi # ============= makefile ============== if test -f 'makefile' -a X"$1" != X"-c"; then echo 'x - skipping makefile (File already exists)' else echo 'x - extracting makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'makefile' && X # Makefile for setlock # @(#) makefile 1.3 X # Set where section 1 man pages go MAN1DIR=/usr/local/man/man1 # Set where the binary goes BINDIR=/usr/local/bin # CFLAGS= -O -DLCKPATH=\"/usr/spool/locks\" X # If using shared libs on ISC SysV, then c_s *must* be at the end of the line. LIBS= -lc_s X all: setlock X setlock: setlock.c X cc -o setlock $(CFLAGS) setlock.c $(LIBS) X clean: X rm setlock X strip: X strip setlock X mcs -d setlock X install: X cp setlock $(BINDIR) X cd $(BINDIR); chmod 555 setlock; chown bin setlock; chgrp sys setlock X cp setlock.1 $(MAN1DIR) X cd $(MAN1DIR); chmod 444 setlock.1; chown bin setlock.1; chgrp sys setlock.1 X shar: X shar -c -a -nsetlock -osetlock setlock.c makefile README setlock.1 dotest Hourly gettyclear log SHAR_EOF chmod 0444 makefile || echo 'restore of makefile failed' Wc_c="`wc -c < 'makefile'`" test 740 -eq "$Wc_c" || echo 'makefile: original size 740, current size' "$Wc_c" fi # ============= README ============== if test -f 'README' -a X"$1" != X"-c"; then echo 'x - skipping README (File already exists)' else echo 'x - extracting README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'README' && X Mon Mar 18 18:22:27 EST 1991 @(#) README 1.2 X To build setlock, define in the makefile in what directory your lock files are located and type make. X When done, test setlock using the 'dotest' script. It will attempt to put setlock through all of its paces creating locks in /usr/spool/locks, in the local directory and in a remote directory. It'll even try to create a lock file in /usr/lib (so don't be root when you run it!). If it succeeds, then setlock will probably work ok on your system, although I could have made the test probably 3 times larger for a complete test. X Dotest will report 'passed' or 'FAILED' on your screen. It's up to you to figure out why the test failed. I've put some diagnostic printouts in to help in the trace. X I have enclosed 3 scripts that we use here on our system that give an example of how I use setlock to enhance news processing, recover gettys on the dialin ports and share a common log file. X 'Hourly' runs various jobs for news processing, including compress and news' expire(8). By running those programs in sequential fashion we don't become IO or Memory bound. The script is run every 15 minutes by crontab, but to do so without having 10 copies running simultaneously, I had to use a lock indicating the script was already running (since many jobs run longer than 15 minutes). The first thing Hourly always does is to set a number of flags to indicate that specific processing is needed. Hourly then checks (via setlock) to see if it is already running. If so, it exits. If not, the lockfile is set and Hourly does its processing. X The 'gettyclear' script resets ports on our machine. Gettyclear uses the '-R' option of setlock to remove a lock file that doesn't belong to the process iff the process associated with that lock file is dead. X The 'log' script allows us to write to a common logfile with vi, by setting a lock to solve concurrency problems. SHAR_EOF chmod 0444 README || echo 'restore of README failed' Wc_c="`wc -c < 'README'`" test 1928 -eq "$Wc_c" || echo 'README: original size 1928, current size' "$Wc_c" fi # ============= setlock.1 ============== if test -f 'setlock.1' -a X"$1" != X"-c"; then echo 'x - skipping setlock.1 (File already exists)' else echo 'x - extracting setlock.1 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'setlock.1' && .TH SETLOCK 1 "21 March 1991" "Version 1.4" .SH NAME .B setlock - test, set and clear System V UUCP lock files .SH SYNOPSIS .B setlock -l lockname -p lockpid [ -f | -s | -r ] [-v] .LP .B setlock -l lockname [ -t | -R ] [-v] .SH DESCRIPTION .I Setlock is a program that can be used by shell scripts to set and clear System V uucp-style lock files (located in /usr/spool/locks). .LP .I Setlock always reads the lock file, testing to see if the process indicated in the lock file is still active, before performing any indicated action. .LP .I Setlock exits such that an exit code of '0' always means "action completed successfully". Failure exit codes from setlock are not symmetrical. Each exit code carries a specific meaning corresponding to the action given by a specific switch. X .SH OPTIONS .LP The -l switch is required under all circumstances: .TP -l lockname ... name of the lockfile .IP If 'lockname' is a just a file name, then setlock will create the lockfile in /usr/spool/locks. If 'lockname' has a path element in it, the lock file will be created where specified. ie: .nf X -l ./mylock .fi .IP will create a lock file 'mylock' in the current directory. .TP -p lockpid ... pid to write to lockfile (and to test for) .IP This should be the process id of the invoking process. A good way to do this is to use the '$$' variable of the shell process. ie: .nf X -p $$ .fi .IP The remaining switches specify actions to take in regards to the specified lock file. .TP -s ... set the lock .IP Create the lock file specified. The name given for the lock file is checked for existance. If it currently exists, then the file is read for the PID and the system is checked to see if the process number in the lock file is still running. If so, setlock exits with error. If not, then setlock creates a lock file and exits with good status. .TP -r ... remove the lock, only if it matches lockpid .IP Try to remove the lock file specified. The lock file is checked to make sure the pid in the file is the same as that specified on the command line. If the pids don't match, setlock exits with an error. If the pid is correct, the lock file is removed. .TP -f ... freshen lock file - touch it with current pid again .IP The lock file is checked to make sure the pid in the file is the same as that specified on the command line. If so, then the lock data is written to the file again (the file is updated), so that the modification date becomes current. If the pid is incorrect, setlock exits with error. .TP -R ... remove the lock, iff the lock is invalid .IP Remove a lock, even if it is not owned by you, but only if the process specified in the lock file is dead. If the process is still running, setlock exits with error. .TP -t ... test to see if the lock is valid .IP Test a lock file to see if it is valid and the process specified by the lock file is still running. Exits with error if the lock file does not exist or the process is dead. .TP -v ... say the exit code to stdout .IP Write the exit code on stdout. Useful for debugging. .LP .SH EXIT CODES .LP .TP 0 Action performed OK. .TP 1 Unable to set lock (current lockfile valid). .TP 2 Did not remove lock (pid passed doesn't match lockfile). .TP 3 Unable to freshen lock file, file does not exist. .TP 4 Unable to freshen lock file, file found but process is dead. .TP 5 Unable to freshen lock file, lock file not owned by you. .TP 6 Lock is not valid, process is gone. .TP 7 Lock file does not exist. .TP 8 Pid specified on command line is not active. .TP 9 Unable to remove lock file not owned by you, still active. .TP 50 Unable to perform action, other error occurred. .TP 100 Program exited due to error. .SH FILES .LP Only the file given in the -l switch. .SH "SEE ALSO" .LP uucico(1), cu(1), tip(1), pcomm(1) .LP .SH AUTHOR .LP Copyright 1991 Paul D. Anderson, All Rights Reserved Worldwide. .LP paul@Dixie.Com, Dixie Communications, (404) 578-9547 (noon-10PM). PO Box 670386, Marietta, GA 30066. .LP @(#) setlock.1 1.4 91/03/23 06:19:11 .SH LICENSE AGREEMENT .LP You may use this program for any legal purpose, but you may not sell it. You may not pretend that you wrote it. .SH DEFICIENCIES / BUGS .LP Maybe setlock should report some kind of unique status when a file (or any component of the path) is not accessible. This particularly applicable when removing a lock: setlock just returns good status: "lock does not exist". .LP When setlock is given a pid, it tests to make sure that the pid specified is at least active on the system before continuing, but it does not make sure the pid is owned by the program invoker. I could probably test the result code if I wanted tighter code, but I'm not worried enough that using '$$' will cause any great problem. .LP .SH FUTURE SHOCK I suppose setlock could be tightened up and made a setuid program, for environments that don't have world writeable lock directories. SHAR_EOF chmod 0444 setlock.1 || echo 'restore of setlock.1 failed' Wc_c="`wc -c < 'setlock.1'`" test 4924 -eq "$Wc_c" || echo 'setlock.1: original size 4924, current size' "$Wc_c" fi # ============= dotest ============== if test -f 'dotest' -a X"$1" != X"-c"; then echo 'x - skipping dotest (File already exists)' else echo 'x - extracting dotest (Text)' sed 's/^X//' << 'SHAR_EOF' > 'dotest' && : # A script to see if setlock is *really* working OK. # (well, it gets things going, anyway) # "@(#) dotest 1.1" X # define UULOCK to test locks in /usr/spool/locks UULOCK="LCK..setlock" # lock dir - trailing slash IS significant LOCKDIR="/usr/spool/locks/" X # define HERE to test local directory locks HERE="./a.lock.$$" X # define THERE to test a lock in a remote directory THERE="/usr/tmp/a.lock.$$" X # define ILLEGAL to test illegal lock creation ILLEGAL="/usr/lib/a.lock.$$" X sl() { X echo "./setlock $* -->\c" X ./setlock $* X rc=$? X echo "$rc \c" X return $rc } X # failure flag F=0 X for LOCK in $UULOCK $HERE $THERE do X echo "\nChecking using lockfile: $LOCK" X X if [ "$LOCK" = "$UULOCK" ] ; then L="$LOCKDIR"; else L=""; fi X X trap "" 0 1 2 3 15 X if [ -f "${L}$LOCK" ] ; then echo "$LOCK exists. Aborted. "; exit 1; fi X trap "rm -f ${L}$LOCK" 0 1 2 3 15 X X # create the lock then try to create it again X if sl -s -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if [ ! -f "${L}$LOCK" ] ; then echo "CREATE FAILED"; F=1; fi X if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi X # remove it then remove it again X if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if [ -f "${L}$LOCK" ] ; then echo "REMOVE FAILED"; F=1; fi X if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X # set the lock then remove it as a 'foreign' lock X if sl -s -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if sl -R -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi X if [ ! -f "${L}$LOCK" ] ; then echo "REMOVE SUCCEEDED - SHOULDN'T HAVE"; F=1; fi X # lock had better be there, so freshen it X if sl -f -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X # now test to see if it is there X if sl -t -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X # remove it and make sure it's not there X if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X X # create the lock with a pid that we know exists, but is not ours X # then try to create a lock over it X if sl -s -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X # now try to remove a lock that is not ours and make sure it still exists X if sl -r -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X if sl -t -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X # try to remove it as a foreign lock file X if sl -R -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi X if [ ! -f "${L}$LOCK" ] ; then echo "REMOVE SUCCEEDED - SHOULDN'T HAVE"; F=1; fi X # make sure we can remove the original lock file X if sl -r -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X if [ -f "${L}$LOCK" ] ; then echo "REMOVE FAILED - SHOULDN'T HAVE"; F=1; fi X X # if we've passed tests so far, then test all all the other X # exit codes (3,4,5,6,8,50) X X if [ "$F" -ne 0 ] ; then X echo "Too many failures, testing stopped" X exit 1 X fi X X # freshen a non-existant log file X if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X if [ -f "${L}$LOCK" ] ; then echo "CREATED LOCK - SHOULDN'T HAVE"; F=1; fi X X # create a lock file for a process that must be dead X echo " 40000" > "${L}$LOCK" X # then try to freshen it X if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X # since we know its a dead process, then try a foreign removal X if sl -R -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X rm -f "${L}$LOCK" X X # create a lock for an active process and then freshen it with our X # process X if sl -s -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X if sl -r -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi X X # test an invalid lock X echo " 40000" > "${L}$LOCK" X if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X rm -f "${L}$LOCK" X X # test for an illegal invocation pid X if sl -s -p 40000 -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi X rm -f "${L}$LOCK" X done X if [ "$F" -ne 0 ] ; then X echo "Too many tests failed. exiting." X exit 1 fi X trap "" 0 1 2 3 15 X if [ -n "$ILLEGAL" ] ; then X X LOCK="$ILLEGAL" X L="" X X echo "\nTesting for illegal access lock creation" X # only test for creating a lock where it is not allowed, since X # we have pretty much wrung out functionality. X if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi X if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi fi X if [ "$F" -eq 0 ] ; then X echo "\nCongratulations, it appears that setlock works on your system!" X exit 0 fi X exit 1 X SHAR_EOF chmod 0460 dotest || echo 'restore of dotest failed' Wc_c="`wc -c < 'dotest'`" test 4866 -eq "$Wc_c" || echo 'dotest: original size 4866, current size' "$Wc_c" fi # ============= Hourly ============== if test -f 'Hourly' -a X"$1" != X"-c"; then echo 'x - skipping Hourly (File already exists)' else echo 'x - extracting Hourly (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Hourly' && : set -x LIBD=/usr/local/news/bin X # %Z% %M% %I% %E% %Q% %U% X # News stuff to do every hour. But we will do it in sequence, so # that we don't get 4 copies of compress running concurrently. # It is important to run this script at exactly 0, 15, 30 and 45 minutes. X # This script will run every 15 minutes, but we'll make # sure that some things only occur hourly. X # To do this, we will test the date and time, setting some files # in the bin dir as flags, showing that we should do certain # functions. We need to do it this way, because there may be # occassions where this script will not exit for several hours # and we would miss the window for performing certain functions... # As such, we will just set a flag and perform the functions later. X # Set 'flags' here to direct processing... X MINUTE=`date +%M` HOUR=`date +%H` X STATUS="$LIBD/.status" # here is where status is written X FLUSH="$LIBD/.flush" # flush all batch queues when present UUNET="$LIBD/.uunet" # do the sendbatch for uunet when present REGULAR="$LIBD/.regular" # do regular batching when present CLEANUP="$LIBD/.cleanup" # run expire ARCHIVE="$LIBD/.archive" # archive files X if [ $MINUTE = "00" ] ; then X case $HOUR in X 02|06|09|14|18|23) X touch $ARCHIVE;; # archive data X 07) X touch $CLEANUP;; # run expire and free disk X 10) X touch $FLUSH;; # flush all batch queues X 22) X touch $UUNET;; # batch up uunet news X *) X esac X X # Start batching every hour X touch $REGULAR fi X # Now see if we are already running, and if so, then exit # because there is no further processing we can do. Otherwise, set # a lock file and begin processing. X LCKDIR=/usr/spool/locks LOCK=LCK..newshour LOCKPRG=/usr/local/bin/setlock X if $LOCKPRG -s -p $$ -l $LOCK ; then X : # we set the lock, now do the rest of the processing else X #echo "Already running" X exit 0 fi X trap "rm -f $LCKDIR/$LOCK $STATUS" 0 1 2 3 15 X status() { X echo "$*" > $STATUS } X # flush all articles at 10 each morning by using default -a0 # by setting a minimum before queing, we can ensure full batches... X if [ -f $FLUSH ] ; then X rm -f $FLUSH X for system in kd4nc nanovx wa4mei slammer ke4zv X do X status "Flushing batch que for $system" X $LIBD/Sendbatch -c -f10000 -m12000000 -s250000 $system X done X status fi X # post stuff to uunet only once a day, just before we get our feed from them X if [ -f $UUNET ] ; then X rm -f $UUNET X status "Preparing batch for uunet" X $LIBD/Sendbatch -c -m2000000 -f2000 uunet X status fi X X # always cleanup before unbatching... if [ -f $CLEANUP ] ; then X rm -f $CLEANUP X status "Running nightly cleanup" X $LIBD/Nightly X status fi X X # ALWAYS unbatch status "Unbatching" rnews -U status X X # Archive away any articles X if [ -f $ARCHIVE ] ; then X rm -f $ARCHIVE X status "Archiving news articles" X $LIBD/Archive2 X status fi X # Feed news to other sites # leave the day and evening hours free for our use # -f = MIN Blocks on spool # -m = max bytes allowed for site # -s = batch size # -a = min Articles in batch file for site before batching # X if [ -f $REGULAR ] ; then X rm -f $REGULAR X X # Emory is our primary feed. I want them to get anything posted here asap. X status "Preparing batch for emory" X $LIBD/Sendbatch -c -f2500 -m4000000 emory X X # do the Dynafeed sends X for system in arg toolz X do X status "Preparing batch for $system" X $LIBD/dofeeds $system X done X status X X for system in kd4nc nanovx wa4mei slammer ke4zv X do X status "Preparing batch for $system" X $LIBD/Sendbatch -c -a150 -f10000 -m12000000 -s250000 $system X done X status fi X SHAR_EOF chmod 0770 Hourly || echo 'restore of Hourly failed' Wc_c="`wc -c < 'Hourly'`" test 3521 -eq "$Wc_c" || echo 'Hourly: original size 3521, current size' "$Wc_c" fi # ============= gettyclear ============== if test -f 'gettyclear' -a X"$1" != X"-c"; then echo 'x - skipping gettyclear (File already exists)' else echo 'x - extracting gettyclear (Text)' sed 's/^X//' << 'SHAR_EOF' > 'gettyclear' && X X # script to periodically kill the getty on the dialin ports, resetting modems X LCKDIR="/usr/spool/locks" TMP="/usr/tmp/gc.$$" X SETLOCK=/usr/local/bin/setlock X trap "rm -f $TMP" 0 1 2 3 15 X for d in 01 04 05 06 07 do X ps -ef >$TMP & X X $SETLOCK -R -l LCK..ttya$d X $SETLOCK -R -l LCK..ttyA$d X X wait X X if [ -f "$LCKDIR/LCK..ttya$d" -o -f "$LCKDIR/LCK..ttyA$d" ] ; then X : # if the lockfile still exists, then do nothing X else X pid=`grep [u]utty < $TMP | egrep 'tty[aA]'$d | awk ' { print $2 } '` X if [ -n "$pid" ] ; then X kill -9 $pid X fi X chmod 666 /dev/ttya$d /dev/ttyA$d X stty sane </dev/ttya$d X fi done SHAR_EOF chmod 0760 gettyclear || echo 'restore of gettyclear failed' Wc_c="`wc -c < 'gettyclear'`" test 614 -eq "$Wc_c" || echo 'gettyclear: original size 614, current size' "$Wc_c" fi # ============= log ============== if test -f 'log' -a X"$1" != X"-c"; then echo 'x - skipping log (File already exists)' else echo 'x - extracting log (Text)' sed 's/^X//' << 'SHAR_EOF' > 'log' && : # script to help with team logging #LOG=/usr1/foo/teamlog #LOGLOCK=/usr1/foo/LCK..teamlog X if [ -z "$LOG" ] ; then X echo "You must set the LOG environment variable to set where the" X echo "log file is to be located." X exit 1; fi if [ -z "$LOGLOCK" ] ; then X echo "You must set the LOGLOCK environment variable to set where the" X echo "lock file is to be located." X exit 1; fi X if setlock -s -p $$ -l $LOGLOCK ; then X trap "rm -f $LOGLOCK" 0 1 2 3 15 else X echo "Log is currently being edited. Try again later.\n" X echo "The log is currently being edited by:" X ps -fp `cat $LOGLOCK` X exit 1 fi X echo "------------------------------------------------------" >>${LOG} echo "Entry: `date +'%A, %D, %R %p'` `id`\n\n" >> ${LOG} chmod 0660 ${LOG} vi +\$ ${LOG} echo "" >>${LOG} X SHAR_EOF chmod 0570 log || echo 'restore of log failed' Wc_c="`wc -c < 'log'`" test 778 -eq "$Wc_c" || echo 'log: original size 778, current size' "$Wc_c" fi exit 0 -- * Paul Anderson * Dixie Communications * (404) 578-9547 * pda@dixie.com *