home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3124 < prev    next >
Internet Message Format  |  1991-03-23  |  28KB

  1. From: pda@Dixie.Com (Paul D. Anderson)
  2. Newsgroups: alt.sources
  3. Subject: Setlock - uucp style lock tool for setting/clearing locks
  4. Message-ID: <8628@rsiatl.Dixie.Com>
  5. Date: 23 Mar 91 11:38:27 GMT
  6.  
  7. Setlock is a program that can be used by shell scripts to set
  8. and clear System V uucp-style lock files (located in
  9. /usr/spool/locks).
  10.  
  11. Setlock always reads the lock file, testing to see if the
  12. process indicated  in the lock file is still active, before
  13. performing any indicated action. 
  14.  
  15. Setlock  exits such that an exit code of '0' always means
  16. "action completed successfully".  Failure exit codes from
  17. setlock are not symmetrical.  Each exit code carries a  specific
  18. meaning corresponding to the action given by a specific switch. 
  19.  
  20. I would appreciate any feedback regarding portability and 
  21. enhancements.  I hope you find this as useful as I have found
  22. it already, here.
  23.  
  24. -paul
  25.  
  26. Submitted-by: pda@Dixie.Com
  27. Archive-name: setlock/part01
  28.  
  29. ---- Cut Here and feed the following to sh ----
  30. #!/bin/sh
  31. # This is setlock, a shell archive (shar 3.43)
  32. # made 03/23/1991 11:28 UTC by pda@Dixie.Com
  33. # Source directory /usr/local/tools/setlock
  34. #
  35. # existing files will NOT be overwritten unless -c is specified
  36. #
  37. # This shar contains:
  38. # length  mode       name
  39. # ------ ---------- ------------------------------------------
  40. #   5692 -r--rw---- setlock.c
  41. #    740 -r--r--r-- makefile
  42. #   1928 -r--r--r-- README
  43. #   4924 -r--r--r-- setlock.1
  44. #   4866 -r--rw---- dotest
  45. #   3521 -rwxrwx--- Hourly
  46. #    614 -rwxrw---- gettyclear
  47. #    778 -r-xrwx--- log
  48. #
  49. # ============= setlock.c ==============
  50. if test -f 'setlock.c' -a X"$1" != X"-c"; then
  51.     echo 'x - skipping setlock.c (File already exists)'
  52. else
  53. echo 'x - extracting setlock.c (Text)'
  54. sed 's/^X//' << 'SHAR_EOF' > 'setlock.c' &&
  55. X
  56. /* Setlock - test for a lock file and set up a lock.
  57. X    Copyright 1991 Paul D. Anderson, All Rights Reserved Worldwide
  58. X
  59. X    License Agreement:
  60. X    You may use this program for any legal purpose, but you may
  61. X    not sell it.  You may not pretend that you wrote it.
  62. X
  63. */
  64. X
  65. #include <stdio.h>
  66. #include <ctype.h>
  67. #include <string.h>
  68. #include <errno.h>
  69. X
  70. X
  71. usage()
  72. {
  73. X    static char *utext[] = {
  74. X
  75. X    "setlock -l lockname -p lockpid [ -f | -s | -r | -t | -R ] [-v]",
  76. #ifndef SHORTHELP
  77. X    "  -l lockname    ... name of the lockfile ",
  78. X    "  -p lockpid    ... pid to write to lockfile (and to test for)",
  79. X    "  -f        ... freshen lock file - touch it with current pid again",
  80. X    "  -s        ... set the lock",
  81. X    "  -r        ... remove the lock, only if it matches lockpid",
  82. X    "  -R        ... remove the lock, iff the lock is invalid,",
  83. X    "            even if it doesn't match lockpid",
  84. X    "  -t        ... test to see if the lock is valid",
  85. X    "  -v        ... say the exit code to stdout",
  86. X    "",
  87. X    "exit codes:",
  88. X    "  0    ... action performed OK",
  89. X    "  1    ... unable to set lock (current lockfile valid)",
  90. X    "  2    ... did not remove lock (pid passed doesn't match lockfile)",
  91. X    "  3    ... unable to freshen lock file, file does not exist",
  92. X    "  4    ... unable to freshen lock file, file found but process is dead",
  93. X    "  5    ... unable to freshen lock file, lock file not owned by you",
  94. X    "  6    ... lock is not valid, process is gone.",
  95. X    "  7    ... lock file does not exist",
  96. X    "  8    ... pid specified on command line is not active",
  97. X    "  9    ... unable to remove lock file not owned by you, still active",
  98. X    "  50    ... unable to perform action, other error occurred",
  99. X    "",
  100. X    "  100    ... program exited due to error"
  101. #else
  102. X    ""
  103. #endif
  104. X    };
  105. X
  106. X    int i;
  107. X
  108. X    for (i=0; i<sizeof utext/sizeof (char *); ++i) 
  109. X        puts(utext[i]);
  110. }
  111. X
  112. #ifndef LCKPATH
  113. #define LCKPATH "/usr/spool/locks"
  114. #endif
  115. X
  116. static char sccsid[] = { "@(#) setlock.c 1.5 91/03/19  20:43:23" };
  117. X
  118. extern int errno;
  119. X
  120. int vflg = 0;
  121. X
  122. main(ac,av)
  123. int ac;
  124. char *av[];
  125. {
  126. X    int c, lockpid, pid=0, fflg=0,sflg=0,rflg=0,tflg=0,errflg=0;
  127. X    int Rflg=0;
  128. X    char *cp, *lockname=0, buf[128], path[128];
  129. X    extern char *optarg;
  130. X
  131. X    while ((c=getopt(ac,av,"l:p:ftsrvR"))!= -1) {
  132. X    switch (c) {
  133. X    case 'l':    lockname=optarg;        break;
  134. X    case 'p':    pid=atoi(optarg);        break;
  135. X    case 'f':    ++fflg;                    break;
  136. X    case 't':    ++tflg;                    break;
  137. X    case 's':    ++sflg;                    break;
  138. X    case 'r':    ++rflg;                    break;
  139. X    case 'R':    ++Rflg;                    break;
  140. X    case 'v':    ++vflg;                    break;
  141. X    case '?':    errflg++;    break;
  142. X    }}
  143. X
  144. X    if (
  145. X        (errflg || Rflg+tflg+fflg+sflg+rflg > 1 || !lockname)
  146. X        || ( !(Rflg || tflg ) && !pid )
  147. X        || ( ( Rflg || tflg ) && pid ) 
  148. X    ) {
  149. X        usage();
  150. X        die(100);
  151. X    }
  152. X
  153. X    /* make sure the given pid is for real */
  154. X    if ( pid && ! testpid(pid) ) die(8);
  155. X
  156. X    /* if there is a slash in the lockname, then assume a path
  157. X    has been specified, as this dude may want a lock in a directory
  158. X    other than /usr/spool/locks... */
  159. X
  160. X    if (strchr(lockname,'/')) { strcpy(path,lockname); }
  161. X    else sprintf(path,"%s/%s",LCKPATH, lockname);
  162. X
  163. X    /* test for a valid lockfile */
  164. X    if (tflg) {
  165. X        switch (lockpid=valid(path)) {
  166. X        case -1:    die(7);        /* lock file not found */
  167. X        case 0:        die(6);        /* lock found, lock inactive */
  168. X        default:    die(0);        /* process is still active */
  169. X        }
  170. X    }
  171. X
  172. X    /* remove the lock file */
  173. X    if (rflg || Rflg ) {
  174. X        switch(lockpid=valid(path)) {
  175. X        case -1:    die(0);        /* lock file not there, so exit ok */
  176. X        case 0:                    /* lock there, but inactive, so rm it */
  177. X                unlink(path);
  178. X                die(0);
  179. X        default:
  180. X                /* lock is there and active */
  181. X                if (Rflg) die(9);
  182. X                /* rflg - rmove the lock iff its ours.  */
  183. X                if ( rflg && pid == lockpid ) {
  184. X                    unlink(path);
  185. X                    die(0);
  186. X                } else {
  187. X                    die(2);    /* pid in lock file doesn't match our pid */
  188. X                }
  189. X        }
  190. X    }
  191. X
  192. X    /* set a lock file */
  193. X    if (sflg) {
  194. X        switch(lockpid=valid(path)) {
  195. X        case -1:    /* lock file not found */
  196. X        case 0:        /* lock found but process dead */
  197. X                if (set(path,pid)) die(0);        /* write the lock file */
  198. X                else die(50);
  199. X        default:
  200. X                die(1);        /* lock is valid, can't set one */
  201. X        }
  202. X    }
  203. X
  204. X    /* freshen the lock file */
  205. X    if (fflg) { 
  206. X        switch(lockpid=valid(path)) {
  207. X        case -1:    /* lock file not found */
  208. X                die(3);
  209. X        case 0:        /* lock found but process dead */
  210. X                die(4);
  211. X        default:    /* lock is valid, can't set one */
  212. X                if ( lockpid != pid ) die(5);        /* not owned by me */
  213. X                else if ( freshen(path,pid) ) die(0);
  214. X                else die(50);
  215. X        }
  216. X    }
  217. X
  218. X    die(100);
  219. }
  220. X
  221. /* returns -1 if lock file is not found.
  222. X        0 if there is a lock file, but process is dead and
  223. X        'pid' of process if process is still active */
  224. X
  225. valid(path)
  226. char *path;
  227. {
  228. X    FILE *fp;
  229. X    char buf[20];
  230. X    int pid, rc, saveerrno;
  231. X
  232. X    /* try to get the lock pid - if we can't open the file, then
  233. X    presume the lock is invalid.  So return a 1 to say that the
  234. X    process is dead.  (a non-readable lock file is incorrectly
  235. X    formed and we needn't try any further error recovery) */
  236. X
  237. X    if ( access(path,0) ) return -1;
  238. X    if ( (fp=fopen(path,"r")) == (FILE *)0 ) return -1;
  239. X
  240. X    fgets(buf,sizeof buf,fp);
  241. X    fclose(fp);
  242. X
  243. X    return testpid(atoi(buf));
  244. }
  245. X
  246. testpid(pid)
  247. {
  248. X    int rc;
  249. X
  250. X    rc = kill(pid,0);
  251. X
  252. X    /* we should return 1 if the process is active */
  253. X    switch(rc) {
  254. X    case 0:        /* it's our process and must be alive, so return ok */
  255. X            return pid;
  256. X    default:    /* it's someone else's process or doesn't exist... */
  257. X        switch(errno) {
  258. X        case ESRCH:    /* process doesn't exist */
  259. X            return 0;    
  260. X        default:    /* something else happened, but process is alive */
  261. X            return pid;
  262. X        }
  263. X    }
  264. }
  265. X
  266. set(path,pid)
  267. char *path;
  268. {
  269. X    FILE *fp;
  270. X
  271. X    if ( (fp=fopen(path,"w")) == (FILE *) 0) return 0;
  272. X
  273. X    fprintf(fp,"%10ld\n",(long)pid);
  274. X    fclose(fp);
  275. X    return 1;
  276. }
  277. X
  278. freshen(path,pid)
  279. char *path;
  280. {
  281. X    FILE *fp;
  282. X
  283. X    if ( (fp=fopen(path,"r+")) == (FILE *) 0) return 0;
  284. X
  285. X    fprintf(fp,"%10ld\n",(long)pid);
  286. X    fclose(fp);
  287. X    return 1;
  288. }
  289. X
  290. die(code)
  291. {
  292. X    if (vflg) printf("%d\n",code);
  293. X    exit(code);
  294. }
  295. SHAR_EOF
  296. chmod 0460 setlock.c ||
  297. echo 'restore of setlock.c failed'
  298. Wc_c="`wc -c < 'setlock.c'`"
  299. test 5692 -eq "$Wc_c" ||
  300.     echo 'setlock.c: original size 5692, current size' "$Wc_c"
  301. fi
  302. # ============= makefile ==============
  303. if test -f 'makefile' -a X"$1" != X"-c"; then
  304.     echo 'x - skipping makefile (File already exists)'
  305. else
  306. echo 'x - extracting makefile (Text)'
  307. sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&
  308. X
  309. # Makefile for setlock
  310. # @(#) makefile 1.3
  311. X
  312. # Set where section 1 man pages go
  313. MAN1DIR=/usr/local/man/man1
  314. # Set where the binary goes
  315. BINDIR=/usr/local/bin
  316. #
  317. CFLAGS=    -O -DLCKPATH=\"/usr/spool/locks\"
  318. X
  319. # If using shared libs on ISC SysV, then c_s *must* be at the end of the line.
  320. LIBS= -lc_s
  321. X
  322. all: setlock
  323. X
  324. setlock:    setlock.c
  325. X    cc -o setlock $(CFLAGS) setlock.c $(LIBS)
  326. X
  327. clean:
  328. X    rm setlock
  329. X
  330. strip:
  331. X    strip setlock
  332. X    mcs -d setlock
  333. X
  334. install:
  335. X    cp setlock $(BINDIR)
  336. X    cd $(BINDIR); chmod 555 setlock; chown bin setlock; chgrp sys setlock
  337. X    cp setlock.1 $(MAN1DIR)
  338. X    cd $(MAN1DIR); chmod 444 setlock.1; chown bin setlock.1; chgrp sys setlock.1
  339. X
  340. shar:
  341. X    shar -c -a -nsetlock -osetlock setlock.c makefile README setlock.1 dotest Hourly gettyclear log
  342. SHAR_EOF
  343. chmod 0444 makefile ||
  344. echo 'restore of makefile failed'
  345. Wc_c="`wc -c < 'makefile'`"
  346. test 740 -eq "$Wc_c" ||
  347.     echo 'makefile: original size 740, current size' "$Wc_c"
  348. fi
  349. # ============= README ==============
  350. if test -f 'README' -a X"$1" != X"-c"; then
  351.     echo 'x - skipping README (File already exists)'
  352. else
  353. echo 'x - extracting README (Text)'
  354. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  355. X
  356. Mon Mar 18 18:22:27 EST 1991
  357. @(#) README 1.2 
  358. X
  359. To build setlock, define in the makefile in what directory your
  360. lock files are located and type make.  
  361. X
  362. When done, test setlock using the 'dotest' script.  It will
  363. attempt to put setlock through all of its paces creating locks
  364. in  /usr/spool/locks, in the local directory and in a remote
  365. directory. It'll even try to create a lock file in /usr/lib (so
  366. don't be root when you run it!).  If it succeeds, then setlock
  367. will probably  work ok on your system, although I could have
  368. made the test probably 3 times larger for a complete test. 
  369. X
  370. Dotest will report 'passed' or 'FAILED' on your screen.  It's
  371. up to you to figure out why the test failed.  I've put some
  372. diagnostic printouts in to help in the trace.
  373. X
  374. I have enclosed 3 scripts that we use here on our system that
  375. give an example of how I use setlock to enhance news processing,
  376. recover gettys on the dialin ports and share a common log file.
  377. X
  378. 'Hourly' runs various jobs for news processing, including
  379. compress and news' expire(8).  By running those programs in
  380. sequential fashion we don't become IO  or Memory bound.   The
  381. script is run every 15 minutes by crontab, but to do so without
  382. having 10 copies running simultaneously, I had to use a lock
  383. indicating the script was already running (since many jobs run 
  384. longer than 15 minutes). The first thing Hourly always does is
  385. to set a number of flags to indicate that specific processing is
  386. needed. Hourly then checks (via setlock) to see if it is already
  387. running.  If so, it exits.  If not, the lockfile is set and
  388. Hourly does its processing.   
  389. X
  390. The 'gettyclear' script resets ports on our machine.  Gettyclear
  391. uses the '-R' option of setlock to remove a lock file that
  392. doesn't belong to the process iff the process associated with
  393. that lock file is dead. 
  394. X
  395. The 'log' script allows us to write to a common logfile with 
  396. vi, by setting a lock to solve concurrency problems.
  397. SHAR_EOF
  398. chmod 0444 README ||
  399. echo 'restore of README failed'
  400. Wc_c="`wc -c < 'README'`"
  401. test 1928 -eq "$Wc_c" ||
  402.     echo 'README: original size 1928, current size' "$Wc_c"
  403. fi
  404. # ============= setlock.1 ==============
  405. if test -f 'setlock.1' -a X"$1" != X"-c"; then
  406.     echo 'x - skipping setlock.1 (File already exists)'
  407. else
  408. echo 'x - extracting setlock.1 (Text)'
  409. sed 's/^X//' << 'SHAR_EOF' > 'setlock.1' &&
  410. .TH SETLOCK 1 "21 March 1991" "Version 1.4"
  411. .SH NAME
  412. .B setlock 
  413. - test, set and clear System V UUCP lock files
  414. .SH SYNOPSIS
  415. .B setlock
  416. -l lockname -p lockpid [ -f | -s | -r ] [-v]
  417. .LP
  418. .B setlock
  419. -l lockname [ -t | -R ] [-v]
  420. .SH DESCRIPTION
  421. .I Setlock
  422. is a program that can be used by shell scripts to set
  423. and clear System V uucp-style lock files (located in /usr/spool/locks).  
  424. .LP
  425. .I Setlock 
  426. always reads the lock file, testing to see if the process indicated 
  427. in the lock file is still active, before performing any indicated action.
  428. .LP
  429. .I Setlock 
  430. exits such that an exit code of '0' always means "action
  431. completed successfully".  Failure exit codes from setlock are
  432. not symmetrical.  Each exit code carries a  specific meaning
  433. corresponding to the action given by a specific switch. 
  434. X
  435. .SH OPTIONS
  436. .LP
  437. The -l  switch is required under all circumstances:
  438. .TP
  439. -l lockname    ... name of the lockfile 
  440. .IP
  441. If 'lockname' is a just a file name, then setlock will create the
  442. lockfile in /usr/spool/locks.  If 'lockname' has a path element
  443. in it, the lock file will be created where specified.  ie:
  444. .nf
  445. X                -l ./mylock
  446. .fi
  447. .IP
  448. will create a lock file 'mylock' in the current directory.
  449. .TP
  450. -p lockpid ... pid to write to lockfile (and to test for)
  451. .IP
  452. This should be the process id of the invoking process.  A 
  453. good way to do this is to use the '$$' variable of the shell
  454. process.  ie:
  455. .nf
  456. X                -p $$
  457. .fi
  458. .IP
  459. The remaining switches specify actions to take in regards to
  460. the specified lock file.
  461. .TP
  462. -s ... set the lock
  463. .IP
  464. Create the lock file specified.  The name given for the lock
  465. file is checked for existance.  If it currently exists, then
  466. the file is read for the PID and the system is checked to see
  467. if the process number in the lock file is still running.  If
  468. so, setlock exits with error.  If not, then setlock creates
  469. a lock file and exits with good status.
  470. .TP
  471. -r ... remove the lock, only if it matches lockpid
  472. .IP
  473. Try to remove the lock file specified.  The lock file is
  474. checked to make sure the pid in the file is the same as
  475. that specified on the command line.  If the pids don't match, setlock
  476. exits with an error.  If the pid is correct, the lock file
  477. is removed.
  478. .TP
  479. -f ... freshen lock file - touch it with current pid again
  480. .IP
  481. The lock file is checked to make sure the pid in the file is the
  482. same as that specified on the command line.  If so, then the
  483. lock data is written to the file again (the file is updated),
  484. so that the modification date becomes current.  If the pid is
  485. incorrect, setlock exits with error.
  486. .TP
  487. -R ... remove the lock, iff the lock is invalid
  488. .IP
  489. Remove a lock, even if it is not owned by you, but only if the
  490. process specified in the lock file is dead.  If the process is
  491. still running, setlock exits with error.
  492. .TP
  493. -t ... test to see if the lock is valid
  494. .IP
  495. Test a lock file to see if it is valid and the process specified
  496. by the lock file is still running.  Exits with error if the lock
  497. file does not exist or the process is dead.
  498. .TP
  499. -v ... say the exit code to stdout
  500. .IP
  501. Write the exit code on stdout.  Useful for debugging.
  502. .LP
  503. .SH EXIT CODES
  504. .LP
  505. .TP
  506. 0
  507. Action performed OK.
  508. .TP
  509. 1
  510. Unable to set lock (current lockfile valid).
  511. .TP
  512. 2
  513. Did not remove lock (pid passed doesn't match lockfile).
  514. .TP
  515. 3
  516. Unable to freshen lock file, file does not exist.
  517. .TP
  518. 4
  519. Unable to freshen lock file, file found but process is dead.
  520. .TP
  521. 5
  522. Unable to freshen lock file, lock file not owned by you.
  523. .TP
  524. 6
  525. Lock is not valid, process is gone.
  526. .TP
  527. 7
  528. Lock file does not exist.
  529. .TP
  530. 8
  531. Pid specified on command line is not active.
  532. .TP
  533. 9
  534. Unable to remove lock file not owned by you, still active.
  535. .TP
  536. 50
  537. Unable to perform action, other error occurred.
  538. .TP
  539. 100
  540. Program exited due to error.
  541. .SH FILES
  542. .LP
  543. Only the file given in the -l switch.
  544. .SH "SEE ALSO"
  545. .LP
  546. uucico(1), cu(1), tip(1), pcomm(1)
  547. .LP
  548. .SH AUTHOR
  549. .LP
  550. Copyright 1991 Paul D. Anderson, All Rights Reserved Worldwide.
  551. .LP
  552. paul@Dixie.Com, Dixie Communications, (404) 578-9547 (noon-10PM).
  553. PO Box 670386, Marietta, GA 30066. 
  554. .LP
  555. @(#) setlock.1 1.4 91/03/23  06:19:11
  556. .SH LICENSE AGREEMENT
  557. .LP
  558. You may use this program for any legal purpose, but you may
  559. not sell it.  You may not pretend that you wrote it.
  560. .SH DEFICIENCIES / BUGS
  561. .LP
  562. Maybe setlock should report some kind of unique status when a file
  563. (or any component of the path) is not accessible.  This particularly
  564. applicable when removing a lock: setlock just returns good status:
  565. "lock does not exist".
  566. .LP
  567. When setlock is given a pid, it tests to make sure that the
  568. pid specified is at least active on the system before continuing,
  569. but it does not make sure the pid is owned by the program invoker.
  570. I could probably test the result code if I wanted tighter code,
  571. but I'm not worried enough that using '$$' will cause any great
  572. problem.
  573. .LP
  574. .SH FUTURE SHOCK
  575. I suppose setlock could be tightened up and made a setuid program,
  576. for environments that don't have world writeable lock directories.
  577. SHAR_EOF
  578. chmod 0444 setlock.1 ||
  579. echo 'restore of setlock.1 failed'
  580. Wc_c="`wc -c < 'setlock.1'`"
  581. test 4924 -eq "$Wc_c" ||
  582.     echo 'setlock.1: original size 4924, current size' "$Wc_c"
  583. fi
  584. # ============= dotest ==============
  585. if test -f 'dotest' -a X"$1" != X"-c"; then
  586.     echo 'x - skipping dotest (File already exists)'
  587. else
  588. echo 'x - extracting dotest (Text)'
  589. sed 's/^X//' << 'SHAR_EOF' > 'dotest' &&
  590. :
  591. # A script to see if setlock is *really* working OK.
  592. # (well, it gets things going, anyway)
  593. # "@(#) dotest 1.1"
  594. X
  595. # define UULOCK to test locks in /usr/spool/locks
  596. UULOCK="LCK..setlock"
  597. # lock dir - trailing slash IS significant
  598. LOCKDIR="/usr/spool/locks/"
  599. X
  600. # define HERE to test local directory locks
  601. HERE="./a.lock.$$"
  602. X
  603. # define THERE to test a lock in a remote directory
  604. THERE="/usr/tmp/a.lock.$$"
  605. X
  606. # define ILLEGAL to test illegal lock creation
  607. ILLEGAL="/usr/lib/a.lock.$$"
  608. X
  609. sl() {
  610. X    echo "./setlock $*  -->\c"
  611. X    ./setlock $*
  612. X    rc=$?
  613. X    echo "$rc  \c"
  614. X    return $rc
  615. }
  616. X
  617. # failure flag
  618. F=0
  619. X
  620. for LOCK in $UULOCK $HERE $THERE
  621. do
  622. X    echo "\nChecking using lockfile: $LOCK"
  623. X
  624. X    if [ "$LOCK" = "$UULOCK" ] ; then L="$LOCKDIR"; else L=""; fi
  625. X
  626. X    trap "" 0 1 2 3 15
  627. X    if [ -f "${L}$LOCK" ] ; then echo "$LOCK exists. Aborted. "; exit 1; fi
  628. X    trap "rm -f ${L}$LOCK" 0 1 2 3 15
  629. X
  630. X    # create the lock then try to create it again
  631. X    if sl -s -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  632. X    if [ ! -f "${L}$LOCK" ] ; then echo "CREATE FAILED"; F=1; fi
  633. X    if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi
  634. X    # remove it then remove it again
  635. X    if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  636. X    if [ -f "${L}$LOCK" ] ; then echo "REMOVE FAILED"; F=1; fi
  637. X    if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  638. X    # set the lock then remove it as a 'foreign' lock
  639. X    if sl -s -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  640. X    if sl -R -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi
  641. X    if [ ! -f "${L}$LOCK" ] ; then echo "REMOVE SUCCEEDED - SHOULDN'T HAVE"; F=1; fi
  642. X    # lock had better be there, so freshen it
  643. X    if sl -f -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  644. X    # now test to see if it is there
  645. X    if sl -t -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  646. X    # remove it and make sure it's not there
  647. X    if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  648. X    if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  649. X
  650. X    # create the lock with a pid that we know exists, but is not ours
  651. X    # then try to create a lock over it
  652. X    if sl -s -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  653. X    if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  654. X    # now try to remove a lock that is not ours and make sure it still exists
  655. X    if sl -r -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  656. X    if sl -t -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  657. X    # try to remove it as a foreign lock file
  658. X    if sl -R -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi
  659. X    if [ ! -f "${L}$LOCK" ] ; then echo "REMOVE SUCCEEDED - SHOULDN'T HAVE"; F=1; fi
  660. X    # make sure we can remove the original lock file
  661. X    if sl -r -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  662. X    if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  663. X    if [ -f "${L}$LOCK" ] ; then echo "REMOVE FAILED - SHOULDN'T HAVE"; F=1; fi
  664. X
  665. X    # if we've passed tests so far, then test all all the other
  666. X    # exit codes (3,4,5,6,8,50)
  667. X
  668. X    if [ "$F" -ne 0 ] ; then
  669. X        echo "Too many failures, testing stopped"
  670. X        exit 1
  671. X    fi
  672. X
  673. X    # freshen a non-existant log file
  674. X    if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  675. X    if [ -f "${L}$LOCK" ] ; then echo "CREATED LOCK - SHOULDN'T HAVE"; F=1; fi
  676. X
  677. X    # create a lock file for a process that must be dead
  678. X    echo "     40000" > "${L}$LOCK"
  679. X    # then try to freshen it
  680. X    if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  681. X    # since we know its a dead process, then try a foreign removal
  682. X    if sl -R -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  683. X    rm -f "${L}$LOCK"
  684. X
  685. X    # create a lock for an active process and then freshen it with our
  686. X    # process
  687. X    if sl -s -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  688. X    if sl -f -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  689. X    if sl -r -p 1 -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  690. X
  691. X    # test an invalid lock
  692. X    echo "     40000" > "${L}$LOCK"
  693. X    if sl -t -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  694. X    rm -f "${L}$LOCK"
  695. X
  696. X    # test for an illegal invocation pid
  697. X    if sl -s -p 40000 -l $LOCK ; then echo "FAILED"; F=1; else echo "passed"; fi
  698. X    rm -f "${L}$LOCK"
  699. X
  700. done
  701. X
  702. if [ "$F" -ne 0 ] ; then
  703. X    echo "Too many tests failed. exiting."
  704. X    exit 1
  705. fi
  706. X
  707. trap "" 0 1 2 3 15
  708. X
  709. if [ -n "$ILLEGAL" ] ; then
  710. X
  711. X    LOCK="$ILLEGAL"
  712. X    L=""
  713. X
  714. X    echo "\nTesting for illegal access lock creation"
  715. X    # only test for creating a lock where it is not allowed, since
  716. X    # we have pretty much wrung out functionality.
  717. X    if sl -s -p $$ -l $LOCK ; then echo "FAILED"; F=1; else echo "passed" ; fi
  718. X    if sl -r -p $$ -l $LOCK ; then echo "passed"; else echo "FAILED"; F=1; fi
  719. fi
  720. X
  721. if [ "$F" -eq 0 ] ; then
  722. X    echo "\nCongratulations, it appears that setlock works on your system!"
  723. X    exit 0
  724. fi
  725. X
  726. exit 1
  727. X
  728. SHAR_EOF
  729. chmod 0460 dotest ||
  730. echo 'restore of dotest failed'
  731. Wc_c="`wc -c < 'dotest'`"
  732. test 4866 -eq "$Wc_c" ||
  733.     echo 'dotest: original size 4866, current size' "$Wc_c"
  734. fi
  735. # ============= Hourly ==============
  736. if test -f 'Hourly' -a X"$1" != X"-c"; then
  737.     echo 'x - skipping Hourly (File already exists)'
  738. else
  739. echo 'x - extracting Hourly (Text)'
  740. sed 's/^X//' << 'SHAR_EOF' > 'Hourly' &&
  741. :
  742. set -x
  743. LIBD=/usr/local/news/bin
  744. X
  745. # %Z% %M% %I% %E% %Q% %U%
  746. X
  747. # News stuff to do every hour.  But we will do it in sequence, so
  748. # that we don't get 4 copies of compress running concurrently.
  749. # It is important to run this script at exactly 0, 15, 30 and 45 minutes.
  750. X
  751. # This script will run every 15 minutes, but we'll make
  752. # sure that some things only occur hourly.  
  753. X
  754. # To do this, we will test the date and time, setting some files
  755. # in the bin dir as flags, showing that we should do certain
  756. # functions.  We need to do it this way, because there may be
  757. # occassions where this script will not exit for several hours
  758. # and we would miss the window for performing certain functions...
  759. # As such, we will just set a flag and perform the functions later.
  760. X
  761. # Set 'flags' here to direct processing...
  762. X
  763. MINUTE=`date +%M`
  764. HOUR=`date +%H`
  765. X
  766. STATUS="$LIBD/.status"        # here is where status is written
  767. X
  768. FLUSH="$LIBD/.flush"        # flush all batch queues when present
  769. UUNET="$LIBD/.uunet"        # do the sendbatch for uunet when present
  770. REGULAR="$LIBD/.regular"     # do regular batching when present
  771. CLEANUP="$LIBD/.cleanup"    # run expire
  772. ARCHIVE="$LIBD/.archive"    # archive files
  773. X
  774. if [ $MINUTE = "00" ] ; then
  775. X    case $HOUR in
  776. X    02|06|09|14|18|23)
  777. X            touch $ARCHIVE;;    # archive data
  778. X    07)    
  779. X            touch $CLEANUP;;    # run expire and free disk
  780. X    10)
  781. X            touch $FLUSH;;        # flush all batch queues
  782. X    22)
  783. X            touch $UUNET;;        # batch up uunet news
  784. X    *)
  785. X    esac
  786. X
  787. X    # Start batching every hour
  788. X    touch $REGULAR
  789. fi
  790. X
  791. # Now see if we are already running, and if so, then exit
  792. # because there is no further processing we can do.  Otherwise, set
  793. # a lock file and begin processing.
  794. X
  795. LCKDIR=/usr/spool/locks
  796. LOCK=LCK..newshour
  797. LOCKPRG=/usr/local/bin/setlock
  798. X
  799. if  $LOCKPRG -s -p $$ -l $LOCK  ; then
  800. X    : # we set the lock, now do the rest of the processing
  801. else
  802. X    #echo "Already running"
  803. X    exit 0
  804. fi
  805. X
  806. trap "rm -f $LCKDIR/$LOCK $STATUS" 0 1 2 3 15
  807. X
  808. status() {
  809. X    echo "$*" > $STATUS
  810. }
  811. X
  812. # flush all articles at 10 each morning by using default -a0
  813. # by setting a minimum before queing, we can ensure full batches...
  814. X
  815. if [ -f $FLUSH ] ; then
  816. X    rm -f $FLUSH
  817. X    for system in kd4nc nanovx wa4mei slammer ke4zv
  818. X    do
  819. X        status "Flushing batch que for $system"
  820. X        $LIBD/Sendbatch -c -f10000 -m12000000 -s250000 $system
  821. X    done
  822. X    status
  823. fi
  824. X
  825. # post stuff to uunet only once a day, just before we get our feed from them
  826. X
  827. if [ -f $UUNET ] ; then
  828. X    rm -f $UUNET
  829. X    status "Preparing batch for uunet"
  830. X    $LIBD/Sendbatch -c -m2000000 -f2000 uunet
  831. X    status
  832. fi
  833. X
  834. X
  835. # always cleanup before unbatching...
  836. if [ -f $CLEANUP ] ; then
  837. X    rm -f $CLEANUP
  838. X    status "Running nightly cleanup"
  839. X    $LIBD/Nightly
  840. X    status
  841. fi
  842. X
  843. X
  844. # ALWAYS unbatch
  845. status "Unbatching"
  846. rnews -U
  847. status
  848. X
  849. X
  850. # Archive away any articles
  851. X
  852. if [ -f $ARCHIVE ] ; then
  853. X    rm -f $ARCHIVE
  854. X    status "Archiving news articles"
  855. X    $LIBD/Archive2
  856. X    status
  857. fi
  858. X
  859. # Feed news to other sites
  860. # leave the day and evening hours free for our use
  861. # -f = MIN Blocks on spool
  862. # -m = max bytes allowed for site
  863. # -s = batch size
  864. # -a = min Articles in batch file for site before batching
  865. #
  866. X
  867. if [ -f $REGULAR ] ; then
  868. X    rm -f $REGULAR
  869. X
  870. X    # Emory is our primary feed. I want them to get anything posted here asap.
  871. X    status "Preparing batch for emory"
  872. X    $LIBD/Sendbatch -c -f2500 -m4000000 emory
  873. X
  874. X    # do the Dynafeed sends
  875. X    for system in arg toolz
  876. X    do
  877. X        status "Preparing batch for $system"
  878. X        $LIBD/dofeeds $system
  879. X    done
  880. X    status
  881. X
  882. X    for system in kd4nc nanovx wa4mei slammer ke4zv
  883. X    do
  884. X        status "Preparing batch for $system"
  885. X        $LIBD/Sendbatch -c -a150 -f10000 -m12000000 -s250000 $system
  886. X    done
  887. X    status
  888. fi
  889. X
  890. SHAR_EOF
  891. chmod 0770 Hourly ||
  892. echo 'restore of Hourly failed'
  893. Wc_c="`wc -c < 'Hourly'`"
  894. test 3521 -eq "$Wc_c" ||
  895.     echo 'Hourly: original size 3521, current size' "$Wc_c"
  896. fi
  897. # ============= gettyclear ==============
  898. if test -f 'gettyclear' -a X"$1" != X"-c"; then
  899.     echo 'x - skipping gettyclear (File already exists)'
  900. else
  901. echo 'x - extracting gettyclear (Text)'
  902. sed 's/^X//' << 'SHAR_EOF' > 'gettyclear' &&
  903. X
  904. X
  905. # script to periodically kill the getty on the dialin ports, resetting modems
  906. X
  907. LCKDIR="/usr/spool/locks"
  908. TMP="/usr/tmp/gc.$$"
  909. X
  910. SETLOCK=/usr/local/bin/setlock
  911. X
  912. trap "rm -f $TMP" 0 1 2 3 15
  913. X
  914. for d in 01 04 05 06 07
  915. do
  916. X    ps -ef >$TMP &
  917. X
  918. X    $SETLOCK -R -l LCK..ttya$d
  919. X    $SETLOCK -R -l LCK..ttyA$d
  920. X
  921. X    wait
  922. X
  923. X    if [ -f "$LCKDIR/LCK..ttya$d" -o -f "$LCKDIR/LCK..ttyA$d" ] ; then
  924. X        : # if the lockfile still exists, then do nothing
  925. X    else
  926. X        pid=`grep [u]utty < $TMP | egrep 'tty[aA]'$d | awk ' { print $2 } '`
  927. X        if [ -n "$pid" ] ; then 
  928. X            kill -9 $pid
  929. X        fi
  930. X        chmod 666 /dev/ttya$d /dev/ttyA$d
  931. X        stty sane </dev/ttya$d
  932. X    fi
  933. done
  934. SHAR_EOF
  935. chmod 0760 gettyclear ||
  936. echo 'restore of gettyclear failed'
  937. Wc_c="`wc -c < 'gettyclear'`"
  938. test 614 -eq "$Wc_c" ||
  939.     echo 'gettyclear: original size 614, current size' "$Wc_c"
  940. fi
  941. # ============= log ==============
  942. if test -f 'log' -a X"$1" != X"-c"; then
  943.     echo 'x - skipping log (File already exists)'
  944. else
  945. echo 'x - extracting log (Text)'
  946. sed 's/^X//' << 'SHAR_EOF' > 'log' &&
  947. :
  948. # script to help with team logging
  949. #LOG=/usr1/foo/teamlog
  950. #LOGLOCK=/usr1/foo/LCK..teamlog
  951. X
  952. if [ -z "$LOG" ] ; then
  953. X    echo "You must set the LOG environment variable to set where the"
  954. X    echo "log file is to be located."
  955. X    exit 1;
  956. fi
  957. if [ -z "$LOGLOCK" ] ; then
  958. X    echo "You must set the LOGLOCK environment variable to set where the"
  959. X    echo "lock file is to be located."
  960. X    exit 1;
  961. fi
  962. X
  963. if setlock -s -p $$ -l $LOGLOCK ; then
  964. X    trap "rm -f $LOGLOCK" 0 1 2 3 15
  965. else
  966. X    echo "Log is currently being edited.  Try again later.\n"
  967. X    echo "The log is currently being edited by:"
  968. X    ps -fp `cat $LOGLOCK`
  969. X    exit 1
  970. fi
  971. X
  972. echo "------------------------------------------------------" >>${LOG}
  973. echo "Entry:  `date +'%A, %D, %R %p'`  `id`\n\n" >> ${LOG}
  974. chmod 0660 ${LOG}
  975. vi +\$  ${LOG}
  976. echo "" >>${LOG}
  977. X
  978. SHAR_EOF
  979. chmod 0570 log ||
  980. echo 'restore of log failed'
  981. Wc_c="`wc -c < 'log'`"
  982. test 778 -eq "$Wc_c" ||
  983.     echo 'log: original size 778, current size' "$Wc_c"
  984. fi
  985. exit 0
  986. -- 
  987. * Paul Anderson * Dixie Communications * (404) 578-9547 * pda@dixie.com *
  988.