home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sources / 3b1 / 81 < prev    next >
Encoding:
Internet Message Format  |  1992-07-21  |  18.7 KB

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