home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / unix_c / sysadmin / prune.c < prev    next >
C/C++ Source or Header  |  1989-03-21  |  5KB  |  195 lines

  1. 24-Jan-86 23:53:43-MST,5553;000000000001
  2. Return-Path: <unix-sources-request@BRL.ARPA>
  3. Received: from BRL-TGR.ARPA by SIMTEL20.ARPA with TCP; Fri 24 Jan 86 23:53:31-MST
  4. Received: from usenet by TGR.BRL.ARPA id a007733; 25 Jan 86 0:00 EST
  5. From: sources-request@panda.uucp
  6. Newsgroups: mod.sources
  7. Subject: prune.c - prunes log files
  8. Message-ID: <1341@panda.UUCP>
  9. Date: 24 Jan 86 14:04:13 GMT
  10. Sender: jpn@panda.uucp
  11. Approved: jpn@panda.UUCP
  12. To:       unix-sources@BRL-TGR.ARPA
  13.  
  14. Mod.sources:  Volume 3, Issue 95
  15. Submitted by: genrad!ihnp4!infoswx!bees (Ray Davis)
  16.  
  17.  
  18. John,
  19.  
  20. The following is a program I wrote to "prune" log files.  The purpose
  21. of this is to keep files that keep getting larger from getting too
  22. large.  I became annoyed at having to search and remember where these
  23. files are, then make them smaller by hand, every time disk space gets
  24. tight.  I also didn't like the idea of having a separate cron entry for
  25. every log file I wanted to deal with.
  26.  
  27. While prune is not extremely robust, it is very functional.  It
  28. compiles and runs as is under 4.2BSD.  I have not tested it under
  29. System * or Xenix, however I believe it should run as is or with little
  30. modification.
  31.  
  32.     Ray Davis        Teknekron Infoswitch Corporation
  33.     ihnp4!infoswx!bees    1784 Firman Drive
  34.     (214)644-0570        Richardson, Texas   75081
  35.  
  36. . . . . . . . . . . . . . . . . . Clip Here . . . . . . . . . . . . . . . . .
  37. /*
  38.  *    prune - clips off the tops of a list of files described in the
  39.  *        file /etc/prune_list. Designed to be run periodically
  40.  *        from cron, the idea is to automatically shorten log
  41.  *        files that grow forever. This file contains a list of
  42.  *        files (full pathname), and the number of blocks that
  43.  *        should be retained.  To retain some sanity, prune will
  44.  *        clip the file after the next newline. The file
  45.  *        /etc/prune_list should look something like:
  46.  *
  47.  *            /usr/adm/aculog        10
  48.  *            /usr/adm/leo.log    5
  49.  *            /usr/adm/messages    200
  50.  *            /usr/adm/sup_log    5
  51.  *
  52.  *        The crontab entry on infoswx for prune looks like:
  53.  *
  54.  *            0 5 * * * /etc/prune >/usr/adm/prune.log 2>&1
  55.  *
  56.  *        Compile with:  cc -O -o prune prune.c
  57.  *
  58.  *        The following defines may be adjusted to suit your taste
  59.  *        and your system block size.
  60.  *
  61.  *    Ray Davis  infoswx!bees  09/25/85
  62.  */
  63.  
  64. #define    PRUNELIST    "/etc/prune_list"
  65. #define    BLOCKSIZE    1024
  66.  
  67. #ifdef USG    /* for System III, System V, or Xenix */
  68. #define    index        strchr
  69. #endif
  70.  
  71. #define    FALSE        (0)
  72. #define    TRUE        (~0)
  73. #define    REWIND(F)    (lseek(F,0,0))
  74.  
  75. #include    <sys/types.h>
  76. #include    <sys/stat.h>
  77. #include    <sys/file.h>
  78. #include    <stdio.h>
  79.  
  80. extern    int    errno;
  81. extern    char    *index();
  82. char    tempfile[] = "/usr/tmp/prune:XXXXXX";
  83.  
  84. main(argc, argv)
  85. int    argc;
  86. char    **argv;
  87. {
  88.     int    pfd,
  89.         tfd,
  90.         cfd,
  91.         nblocks,
  92.         new_line_found,
  93.         bytes_read,
  94.         nlbytes;
  95.     char    file[128],
  96.         block[BLOCKSIZE+1],
  97.         *nl;
  98.     long    nbytes;
  99.     FILE    *pstream;
  100.     struct    stat    cstat;
  101.  
  102.     block[BLOCKSIZE] = '\0';
  103.  
  104.     /* open prune list */
  105.     if ((pfd = open(PRUNELIST, O_RDONLY)) < 0)
  106.         errabort(*argv, "open", PRUNELIST, TRUE);
  107.     pstream = fdopen(pfd, "r");
  108.  
  109.     /* create unique tempfile */
  110.     mktemp(tempfile);
  111.  
  112.     /* while read each filename & #blocks */
  113.     while ((fscanf(pstream, "%s%d", file, &nblocks)) != EOF) {
  114.         fprintf(stderr, "pruning %s to %d blocks\n", file, nblocks);
  115.         /* open filename */
  116.         if ((cfd = open(file, O_RDWR)) < 0) {
  117.             errabort(*argv, "open", file, FALSE);
  118.             continue;
  119.         }
  120.         /* seek #blocks from the end of file */
  121.         nbytes = - (nblocks * BLOCKSIZE);
  122.         if ((fstat(cfd, &cstat)) < 0) {
  123.             errabort(*argv, "fstat", file, FALSE);
  124.         } else {
  125.             if (cstat.st_size <= -(nbytes)) {
  126.                 fprintf(stderr, "%s: %s: not large enough to prune\n", *argv, file);
  127.             } else {
  128.                 if ((lseek(cfd, nbytes, 2)) < 0) {
  129.                     fprintf(stderr, "%s: %s: error on seek\n", *argv, file);
  130.                 } else {
  131.                     /* open tempfile */
  132.                     if ((tfd = open(tempfile, O_CREAT|O_RDWR|O_TRUNC, 0600)) < 0)
  133.                         errabort(*argv, "open", tempfile, TRUE);
  134.                     /* copy to tempfile */
  135.                     new_line_found = FALSE;
  136.                     while ((bytes_read = read(cfd, block, BLOCKSIZE)) > 0) {
  137.                         if (new_line_found) {
  138.                             if ((write(tfd, block, bytes_read)) != bytes_read)
  139.                                 errabort(*argv, "write", tempfile, FALSE);
  140.                         } else {
  141.                             if ((nl = index(block, '\n')) == NULL) {
  142.                                 nl = block;
  143.                             } else {
  144.                                 nl++;
  145.                                 new_line_found = TRUE;
  146.                             }
  147.                             nlbytes = bytes_read - (nl - block);
  148.                             if ((write(tfd, nl, nlbytes)) != nlbytes)
  149.                                 errabort(*argv, "write", tempfile, FALSE);
  150.                         }
  151.                     }
  152.                     if (bytes_read < 0) {
  153.                         errabort(*argv, "read", file, FALSE);
  154.                     } else {
  155.                         /* re-open filename to truncate */
  156.                         close(cfd);
  157.                         if ((cfd = open(file, O_RDWR|O_TRUNC)) < 0) {
  158.                             errabort(*argv, "re-open", file, FALSE);
  159.                             continue;
  160.                         }
  161.                         /* overwrite file with tempfile */
  162.                         REWIND(tfd);
  163.                         while ((bytes_read = read(tfd, block, BLOCKSIZE)) > 0) {
  164.                             if ((write(cfd, block, bytes_read)) != bytes_read)
  165.                                 errabort(*argv, "write", file, FALSE);
  166.                         }
  167.                         if (bytes_read < 0)
  168.                             errabort(*argv, "read", tempfile, FALSE);
  169.                     }
  170.                 }
  171.             }
  172.         }
  173.         close(cfd);
  174.         close(tfd);
  175.     }
  176.     /* remove tempfile */
  177.     unlink(tempfile);
  178.     exit(0);
  179. }
  180.  
  181. errabort(program, function, filename, should_exit)
  182. char    *program,
  183.     *function,
  184.     *filename;
  185. int    should_exit;
  186. {
  187.     char    errbuff[128];
  188.  
  189.     sprintf(errbuff, "%s: %s(%s)", program, function, filename);
  190.     perror(errbuff);
  191.     if (should_exit)
  192.         exit(errno);
  193. }
  194. /* end of prune.c */
  195.