home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / wtrim / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-07-20  |  18.5 KB

  1. Path: comp-sources-3b1
  2. From: dave@galaxia.network23.com (David H. Brierley)
  3. Subject:  v02i028:  Trim wtmp file to a manageable size, Part01/01
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: eb2b7a6f 8fa448ad 75249185 aa982262
  7.  
  8. Submitted-by: dave@galaxia.network23.com (David H. Brierley)
  9. Posting-number: Volume 2, Issue 28
  10. Archive-name: wtrim/part01
  11.  
  12. This is the README file for the Dave Brierley collection of miscellaneous
  13. source programs.  The collection is posted in seven separate pieces but
  14. all of the source came from the "misc" directory on my machine.  As a result
  15. of this, there is only one README file and only one Makefile, although each
  16. of the seven postings will contain a copy of these two files.  I suggest
  17. that you obtain (or save) as many of these postings as you are interested
  18. in, unpack them all in a single directory, and then compile the sources.
  19. Note that some of the programs are actually shell scripts and therefore do
  20. not need compilation.
  21.  
  22. wclipper.c
  23.  A program to read in the wtmp file and output the tail end of it.  Useful
  24.  if you want to maintain an N-day history of who has been using your system.
  25.  The output size can be specified in terms of days or kbytes.
  26.  
  27. wtmp.fix.sh
  28.  A shell script to control the operation of wclipper.
  29.  
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of archive 1 (of 1)."
  37. # Contents:  MANIFEST Makefile README wclipper.c wtmp.fix.sh
  38. # Wrapped by dave@galaxia on Tue Jul 21 10:48:15 1992
  39. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  40. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  41.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  42. else
  43. echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
  44. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  45. X   File Name        Archive #    Description
  46. X-----------------------------------------------------------
  47. X MANIFEST                   1    
  48. X Makefile                   1    
  49. X README                     1    
  50. X wclipper.c                 1    
  51. X wtmp.fix.sh                1    
  52. END_OF_FILE
  53. if test 251 -ne `wc -c <'MANIFEST'`; then
  54.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  55. fi
  56. # end of 'MANIFEST'
  57. fi
  58. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  59.   echo shar: Will not clobber existing file \"'Makefile'\"
  60. else
  61. echo shar: Extracting \"'Makefile'\" \(374 characters\)
  62. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  63. XCFLAGS    = -O
  64. X
  65. Xall:        bsdln disktest email ndf techo wclipper
  66. X
  67. Xbsdln:        bsdln.o
  68. X        $(CC) bsdln.o
  69. X        mv a.out bsdln
  70. X
  71. Xdisktest:    disktest.o
  72. X        $(CC) disktest.o
  73. X        mv a.out disktest
  74. X
  75. Xemail:        email.o
  76. X        $(CC) email.o
  77. X        mv a.out email
  78. X
  79. Xndf:        ndf.o
  80. X        $(CC) ndf.o
  81. X        mv a.out ndf
  82. X
  83. Xtecho:        techo.o
  84. X        $(CC) techo.o
  85. X        mv a.out techo
  86. X
  87. Xwclipper:    wclipper.o
  88. X        $(CC) wclipper.o
  89. X        mv a.out wclipper
  90. X
  91. END_OF_FILE
  92. if test 374 -ne `wc -c <'Makefile'`; then
  93.     echo shar: \"'Makefile'\" unpacked with wrong size!
  94. fi
  95. # end of 'Makefile'
  96. fi
  97. if test -f 'README' -a "${1}" != "-c" ; then 
  98.   echo shar: Will not clobber existing file \"'README'\"
  99. else
  100. echo shar: Extracting \"'README'\" \(4280 characters\)
  101. sed "s/^X//" >'README' <<'END_OF_FILE'
  102. XThis is the README file for the Dave Brierley collection of miscellaneous
  103. Xsource programs.  The collection is posted in seven separate pieces but
  104. Xall of the source came from the "misc" directory on my machine.  As a result
  105. Xof this, there is only one README file and only one Makefile, although each
  106. Xof the seven postings will contain a copy of these two files.  I suggest
  107. Xthat you obtain (or save) as many of these postings as you are interested
  108. Xin, unpack them all in a single directory, and then compile the sources.
  109. XNote that some of the programs are actually shell scripts and therefore do
  110. Xnot need compilation.
  111. X
  112. XINSTALLATION INSTRUCTIONS:
  113. X1. Compile all the source programs by typing "make all".  Edit the Makefile
  114. X   if you did not unpack all seven of the pieces.  Note that the Makefile
  115. X   does not contain explicit commands for using the shared library.  I always
  116. X   depend on "ccc" to do this for me.
  117. X2. Copy the resultant executables to your favorite bin directory.  I always
  118. X   use "/usr/local/bin".
  119. X3. Copy the various shell scripts to the bin directory and make then executable
  120. X   using the chmod command.  The shell scripts are all distributed with a
  121. X   suffix of ".sh".  I suggest you remove this suffix when you install it, but
  122. X   that is entirely up to you.
  123. X
  124. X
  125. XDescription of programs included in this package.  There is a line of dashes
  126. Xseparating each of the seven pieces.
  127. X
  128. Xbsdln.c
  129. X A version of the ln command that follows the BSD behaviour.  I.e. if the
  130. X target file exists, the command will fail.  The standard 3b1 version will
  131. X remove the target.
  132. X
  133. X--------------------------------------------------------------------------
  134. X
  135. Xinstall.sh
  136. X A shell script version of the BSD install command.
  137. X
  138. Xnull.sh
  139. X Zero out one or more files.
  140. X
  141. Xtolower.sh
  142. X Convert file names to lower case.  Requires ksh.
  143. X
  144. Xtoupper.sh
  145. X Convert file names to upper case.  Requires ksh.
  146. X
  147. X--------------------------------------------------------------------------
  148. X
  149. Xndf.c
  150. X Almost emulates the BSD df command.  I say "almost" because I chose to
  151. X display the numbers in terms of blocks instead of kbytes since everything
  152. X else on the machine displays sizes in blocks.  Supports the "-i" option
  153. X to displays inode information.  Also supports specifying any random
  154. X directory as an argument and it will figure out what file system it is.
  155. X
  156. X--------------------------------------------------------------------------
  157. X
  158. Xdisktest.c
  159. X A program used by the format script to test the floppy disk to be doubly
  160. X sure that it is usable.
  161. X
  162. Xformat.sh
  163. X Format a floppy disk.  Asks questions to determine desired parameters, such
  164. X as number of cylinders and number of sectors.  Will optionally run an
  165. X intensive surface test of the floppy (see disktest.c), build a file system
  166. X structure, and make the floppy bootable.  The main processing is done in a
  167. X loop so you can format multiple floppies easily.
  168. X
  169. Xnewfs.sh
  170. X Reads the VHB from the floppy and then builds a file system structure on it.
  171. X
  172. X--------------------------------------------------------------------------
  173. X
  174. Xtecho.c
  175. X A version of echo that allows direct access to termcap capabilities.  A lot
  176. X easier to use than intermixing calls to echo with calls to tput.
  177. X
  178. Xtecho.1
  179. X Hey, I actually wrote a man page for this one!
  180. X
  181. X--------------------------------------------------------------------------
  182. X
  183. Xwclipper.c
  184. X A program to read in the wtmp file and output the tail end of it.  Useful
  185. X if you want to maintain an N-day history of who has been using your system.
  186. X The output size can be specified in terms of days or kbytes.
  187. X
  188. Xwtmp.fix.sh
  189. X A shell script to control the operation of wclipper.
  190. X
  191. X--------------------------------------------------------------------------
  192. X
  193. Xemail.c
  194. X A version of the "email" program.  This program should be installed as
  195. X /usr/bin/email and it will be used by pcmgr (or by smgr) when you click
  196. X on the envelope icon.  It provides a safe interface to the mail program
  197. X by making sure the uid is set correctly and by doing a chdir to the
  198. X users home directory (both of which are already being done by pcmgr).
  199. X This version also provides a unique feature of reading an "rc" file
  200. X from the users home directory (~/.email.rc), which can be used to specify
  201. X what mail program to use.  See the sample provided.
  202. X
  203. Xemail.rc
  204. X Sample .email.rc file.
  205. END_OF_FILE
  206. if test 4280 -ne `wc -c <'README'`; then
  207.     echo shar: \"'README'\" unpacked with wrong size!
  208. fi
  209. # end of 'README'
  210. fi
  211. if test -f 'wclipper.c' -a "${1}" != "-c" ; then 
  212.   echo shar: Will not clobber existing file \"'wclipper.c'\"
  213. else
  214. echo shar: Extracting \"'wclipper.c'\" \(8993 characters\)
  215. sed "s/^X//" >'wclipper.c' <<'END_OF_FILE'
  216. X/*--------------------------------------------------------------
  217. X*
  218. X* Program: wclipper
  219. X*
  220. X* This program is used to sanely trim the wtmp file by removing
  221. X* entries from the beginning.  Options allow for trimming the
  222. X* file based on the time stamps in the entries or simply keeping
  223. X* the last N blocks of the file.
  224. X*
  225. X* David H. Brierley
  226. X* Raytheon Submarine Signal Division
  227. X* Portsmouth, RI 02871
  228. X*
  229. X*--------------------------------------------------------------*/
  230. X
  231. X#include <stdio.h>
  232. X#include <sys/types.h>
  233. X#include <sys/stat.h>
  234. X#include <utmp.h>
  235. X#ifdef    BSD
  236. X# include <strings.h>
  237. X# include <sys/time.h>
  238. X#else
  239. X# include <string.h>
  240. X# include <time.h>
  241. X#endif
  242. X
  243. X#define    UBLOCK        4096
  244. X#define UBUFSIZ        UBLOCK * sizeof (struct utmp)
  245. X#define WTMPFILE    "/usr/adm/wtmp"
  246. X
  247. Xstruct utmp    *utmp;
  248. Xstruct utmp     ubuffer[UBLOCK];
  249. X
  250. X#ifndef lint
  251. Xextern char    *optarg;
  252. X#else
  253. Xstatic char    *optarg;
  254. X#endif
  255. X
  256. Xextern char    *malloc ();
  257. Xextern long     lseek ();
  258. Xextern time_t   time ();
  259. Xextern void     exit ();
  260. Xextern void     perror ();
  261. X
  262. Xmain (argc, argv)
  263. Xint             argc;
  264. Xchar           *argv[];
  265. X{
  266. X    int             optch;
  267. X    int             skip_size;
  268. X    int             verbose;
  269. X    time_t          now;
  270. X    time_t          clip_time;
  271. X    long            clip_size;
  272. X    char           *infile;
  273. X    char           *outfile;
  274. X
  275. X    skip_size = 10240;
  276. X    (void) time (&now);
  277. X    clip_time = 0;
  278. X    clip_size = 0;
  279. X    verbose = 0;
  280. X    infile = WTMPFILE;
  281. X    outfile = NULL;
  282. X
  283. X    /*
  284. X     * Scan the argument list 
  285. X     */
  286. X    while ((optch = getopt (argc, argv, "i:o:d:h:k:s:v")) != EOF) {
  287. X    switch (optch) {
  288. X    case 'd':        /* trim at this many days */
  289. X        clip_time = atoi (optarg) * 24;
  290. X        break;
  291. X    case 'h':        /* trim at this many hours */
  292. X        clip_time = atoi (optarg);
  293. X        break;
  294. X    case 'k':        /* keep this many Kbytes of data */
  295. X        clip_size = atoi (optarg);
  296. X        break;
  297. X    case 's':        /* number of entries to skip while scanning */
  298. X        skip_size = atoi (optarg);
  299. X        break;
  300. X    case 'i':        /* name of input file */
  301. X        infile = malloc ((unsigned) strlen (optarg) + 1);
  302. X        (void) strcpy (infile, optarg);
  303. X        break;
  304. X    case 'o':        /* name of output file */
  305. X        outfile = malloc ((unsigned) strlen (optarg) + 1);
  306. X        (void) strcpy (outfile, optarg);
  307. X        break;
  308. X    case 'v':        /* produce verbose output */
  309. X        verbose = 1;
  310. X        break;
  311. X    default:
  312. X        (void) printf ("Usage: %s: %s\n",
  313. X               "-ofilename [-ifilename] [-dN] [-hN] [-kN] [-sN]",
  314. X               argv[0]);
  315. X        exit (1);
  316. X    }
  317. X    }
  318. X
  319. X    /*
  320. X     * Error if no output file was specified. Input file defaults to
  321. X     * /usr/adm/wtmp. 
  322. X     */
  323. X    if (outfile == NULL) {
  324. X    (void) printf ("Error: no output file specified\n");
  325. X    exit (1);
  326. X    }
  327. X
  328. X    /*
  329. X     * If no clip time or clip size is given, default action is to clip file
  330. X     * at seven days. 
  331. X     */
  332. X    if ((clip_time == 0) && (clip_size == 0)) {
  333. X    clip_time = 7 * 24;
  334. X    }
  335. X
  336. X    /*
  337. X     * Make sure the user did not give both a time and size clip amount 
  338. X     */
  339. X    if ((clip_size > 0) && (clip_time > 0)) {
  340. X    (void) printf ("Error: -s option conflicts with -d/-h\n");
  341. X    exit (1);
  342. X    }
  343. X
  344. X    /*
  345. X     * Do the size clipping.  This is the easiest case 
  346. X     */
  347. X    if (clip_size > 0) {
  348. X    size_clipper (infile, outfile, clip_size, verbose);
  349. X    exit (0);
  350. X    }
  351. X
  352. X    /*
  353. X     * Convert the time spec into seconds and do the clipping 
  354. X     */
  355. X    if (clip_time > 0) {
  356. X    clip_time *= 3600;    /* convert hours to seconds */
  357. X    if (clip_time > now) {
  358. X        (void) printf ("Error: time spec is greater than current time\n");
  359. X        exit (1);
  360. X    }
  361. X    clip_time = now - clip_time;    /* keep records newer than clip_time */
  362. X    time_clipper (infile, outfile, clip_time, skip_size, verbose);
  363. X    exit (0);
  364. X    }
  365. X
  366. X    /*
  367. X     * If I get to here, something is wrong so print a message 
  368. X     */
  369. X    (void) printf ("Error: invalid combo of options, no action performed\n");
  370. X    return (1);
  371. X
  372. X}
  373. X
  374. Xsize_clipper (infile, outfile, size, verbose)
  375. Xchar           *infile;
  376. Xchar           *outfile;
  377. Xlong            size;
  378. Xint             verbose;
  379. X{
  380. X    struct stat     sbuf;
  381. X    int             nbytes;
  382. X    int             fd1;
  383. X    int             fd2;
  384. X
  385. X    size *= 1024;        /* convert Kbytes to bytes */
  386. X    size /= sizeof (struct utmp);    /* How many utmp records is that? */
  387. X    size *= sizeof (struct utmp);    /* convert back to bytes */
  388. X
  389. X    if (verbose) {
  390. X    (void) printf ("trimming file to %d bytes (%d records)\n",
  391. X               size, size / sizeof (struct utmp));
  392. X    }
  393. X    if (stat (infile, &sbuf) == -1) {
  394. X    perror ("wclipper");
  395. X    (void) printf ("Unable to stat file '%s'\n",
  396. X               infile);
  397. X    exit (1);
  398. X    }
  399. X    if ((fd1 = open (infile, 0)) == -1) {
  400. X    perror ("wclipper");
  401. X    (void) printf ("Unable to open file '%s' for input\n",
  402. X               infile);
  403. X    exit (1);
  404. X    }
  405. X    (void) umask (0);        /* make sure umask does not interfere */
  406. X    if ((fd2 = creat (outfile, (int) (sbuf.st_mode & 0777))) == -1) {
  407. X    perror ("wclipper");
  408. X    (void) printf ("Unable to create output file '%s'\n",
  409. X               outfile);
  410. X    exit (1);
  411. X    }
  412. X    if (sbuf.st_size > size) {
  413. X    size = sbuf.st_size - size;
  414. X    if (lseek (fd1, size, 0) == -1) {
  415. X        perror ("wclipper");
  416. X        (void) printf ("I/O error seeking to position %ld in file %s\n",
  417. X               size, infile);
  418. X        (void) close (fd1);
  419. X        (void) close (fd2);
  420. X        exit (1);
  421. X    }
  422. X    }
  423. X    while ((nbytes = read (fd1, (char *) ubuffer, UBUFSIZ)) > 0) {
  424. X    if (write (fd2, (char *) ubuffer, (unsigned) nbytes) != nbytes) {
  425. X        perror ("wclipper");
  426. X        (void) printf ("I/O error writing %d bytes to file %s\n",
  427. X               nbytes, outfile);
  428. X        (void) close (fd1);
  429. X        (void) close (fd2);
  430. X        exit (1);
  431. X    }
  432. X    }
  433. X
  434. X    if (close (fd1) == -1) {
  435. X    perror ("wclipper");
  436. X    (void) printf ("I/O error reported while closing file %s\n",
  437. X               infile);
  438. X    (void) close (fd2);
  439. X    exit (1);
  440. X    }
  441. X    if (close (fd2) == -1) {
  442. X    perror ("wclipper");
  443. X    (void) printf ("I/O error reported while closing file %s\n",
  444. X               outfile);
  445. X    exit (1);
  446. X    }
  447. X    if (verbose) {
  448. X    (void) printf ("copy completed successfully\n");
  449. X    }
  450. X}
  451. X
  452. Xtime_clipper (infile, outfile, clip_time, skip_size, verbose)
  453. Xchar           *infile;
  454. Xchar           *outfile;
  455. Xtime_t          clip_time;
  456. Xint             skip_size;
  457. Xint             verbose;
  458. X{
  459. X    struct stat     sbuf;
  460. X    long            seekamt;
  461. X    long            seekpos;
  462. X    int             fd1;
  463. X    int             fd2;
  464. X    int             nbytes;
  465. X
  466. X    if (verbose) {
  467. X    (void) printf ("trimming file at %s",
  468. X               ctime (&clip_time));
  469. X    }
  470. X    if ((fd1 = open (infile, 0)) == -1) {
  471. X    (void) printf ("Unable to open file '%s' for input\n",
  472. X               infile);
  473. X    exit (1);
  474. X    }
  475. X    if (stat (infile, &sbuf) == -1) {
  476. X    (void) printf ("Unable to stat file '%s'\n",
  477. X               infile);
  478. X    exit (1);
  479. X    }
  480. X    (void) umask (0);        /* make sure umask does not interfere */
  481. X    if ((fd2 = creat (outfile, (int) (sbuf.st_mode & 0777))) == -1) {
  482. X    (void) printf ("Unable to create output file '%s'\n",
  483. X               outfile);
  484. X    exit (1);
  485. X    }
  486. X    seekamt = skip_size * sizeof (struct utmp);
  487. X    seekpos = 0;
  488. X    while (1) {
  489. X    if (verbose) {
  490. X        (void) printf ("seeking to record %d: ",
  491. X               seekpos / sizeof (struct utmp));
  492. X        (void) fflush (stdout);
  493. X    }
  494. X    if (lseek (fd1, seekpos, 0) == -1) {
  495. X        (void) printf ("I/O error seeking to position %ld in file %s\n",
  496. X               seekpos, infile);
  497. X        exit (1);
  498. X    }
  499. X    nbytes = read (fd1, (char *) ubuffer, sizeof (struct utmp));
  500. X    if (nbytes != sizeof (struct utmp)) {
  501. X        (void) printf ("I/O error reading input file %s\n",
  502. X               infile);
  503. X        exit (1);
  504. X    }
  505. X    utmp = ubuffer;
  506. X    if (verbose) {
  507. X        (void) printf ("time stamp = %s",
  508. X               ctime (&utmp -> ut_time));
  509. X    }
  510. X    if (utmp -> ut_time >= clip_time) {
  511. X        if ((skip_size == 1) || (seekpos == 0)) {
  512. X        break;
  513. X        }
  514. X        skip_size /= 2;
  515. X        seekpos -= seekamt;
  516. X        if (seekpos < 0) {
  517. X        seekpos = 0;
  518. X        }
  519. X        if (skip_size < 1) {
  520. X        skip_size = 1;
  521. X        }
  522. X        seekamt = skip_size * sizeof (struct utmp);
  523. X    }
  524. X    while ((seekpos + seekamt > sbuf.st_size) && (skip_size > 1)) {
  525. X        skip_size /= 2;
  526. X        seekamt = skip_size * sizeof (struct utmp);
  527. X    }
  528. X    seekpos += seekamt;
  529. X    }
  530. X
  531. X    if (lseek (fd1, seekpos, 0) == -1) {
  532. X    (void) printf ("I/O error seeking to position %ld in file %s\n",
  533. X               seekpos, infile);
  534. X    exit (1);
  535. X    }
  536. X
  537. X    if (verbose) {
  538. X    (void) printf ("begin copying at record number %d\n",
  539. X               seekpos / sizeof (struct utmp));
  540. X    }
  541. X
  542. X    while ((nbytes = read (fd1, (char *) ubuffer, UBUFSIZ)) > 0) {
  543. X    if (write (fd2, (char *) ubuffer, (unsigned) nbytes) != nbytes) {
  544. X        perror ("wclipper");
  545. X        (void) printf ("I/O error writing %d bytes to file %s\n",
  546. X               nbytes, outfile);
  547. X        (void) close (fd1);
  548. X        (void) close (fd2);
  549. X        exit (1);
  550. X    }
  551. X    }
  552. X
  553. X    if (close (fd1) == -1) {
  554. X    perror ("wclipper");
  555. X    (void) printf ("I/O error reported while closing file %s\n",
  556. X               infile);
  557. X    (void) close (fd2);
  558. X    exit (1);
  559. X    }
  560. X    if (close (fd2) == -1) {
  561. X    perror ("wclipper");
  562. X    (void) printf ("I/O error reported while closing file %s\n",
  563. X               outfile);
  564. X    exit (1);
  565. X    }
  566. X    if (verbose) {
  567. X    (void) printf ("copy completed successfully\n");
  568. X    }
  569. X}
  570. END_OF_FILE
  571. if test 8993 -ne `wc -c <'wclipper.c'`; then
  572.     echo shar: \"'wclipper.c'\" unpacked with wrong size!
  573. fi
  574. # end of 'wclipper.c'
  575. fi
  576. if test -f 'wtmp.fix.sh' -a "${1}" != "-c" ; then 
  577.   echo shar: Will not clobber existing file \"'wtmp.fix.sh'\"
  578. else
  579. echo shar: Extracting \"'wtmp.fix.sh'\" \(362 characters\)
  580. sed "s/^X//" >'wtmp.fix.sh' <<'END_OF_FILE'
  581. X: 'sh or ksh'
  582. Xtrap ':' ERR
  583. Xif test $(/bin/who | wc -l) -ne 0; then exit 0; fi
  584. Xgetoff.sh 000
  585. Xsleep 30
  586. Xif test $(/bin/who | wc -l) -ne 0; then exit 0; fi
  587. X/usr/local/bin/wclipper -i/etc/wtmp -o/tmp/wtmp -d14 -v
  588. XST=$?
  589. Xgeton.sh 000
  590. Xif test ${ST} -ne 0; then exit ${ST}; fi
  591. Xmv /etc/wtmp /etc/wtmp.old;mv /tmp/wtmp /etc/wtmp
  592. Xchmod 644 /etc/wtmp
  593. Xrm /etc/wtmp.old
  594. Xexit 0
  595. END_OF_FILE
  596. if test 362 -ne `wc -c <'wtmp.fix.sh'`; then
  597.     echo shar: \"'wtmp.fix.sh'\" unpacked with wrong size!
  598. fi
  599. chmod +x 'wtmp.fix.sh'
  600. # end of 'wtmp.fix.sh'
  601. fi
  602. echo shar: End of archive 1 \(of 1\).
  603. cp /dev/null ark1isdone
  604. MISSING=""
  605. for I in 1 ; do
  606.     if test ! -f ark${I}isdone ; then
  607.     MISSING="${MISSING} ${I}"
  608.     fi
  609. done
  610. if test "${MISSING}" = "" ; then
  611.     echo You have the archive.
  612.     rm -f ark[1-9]isdone
  613. else
  614.     echo You still need to unpack the following archives:
  615.     echo "        " ${MISSING}
  616. fi
  617. ##  End of shell archive.
  618. exit 0
  619. -- 
  620. David H. Brierley
  621. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  622. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  623. %% Can I be excused, my brain is full. **
  624.