home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / snews-20.zip / EXPIRE.C < prev    next >
C/C++ Source or Header  |  1992-08-02  |  8KB  |  341 lines

  1. /*
  2.     SNEWS 2.0
  3.  
  4.     EXPIRE - expire news database articles by number of days since rx'd
  5.  
  6.  
  7.     Copyright (C) 1991  John McCombs, PO Box 2708, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.  
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License, version 1, as
  12.     published by the Free Software Foundation.
  13.  
  14.     This program is distributed in the hope that it will be useful,
  15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.     GNU General Public License for more details.
  18.  
  19.     See the file COPYING, which contains a copy of the GNU General
  20.     Public License.
  21.  
  22.  
  23.     USAGE:  expires <days>
  24.  
  25.  */
  26.  
  27. #include "defs.h"
  28. #include <io.h>
  29. #include "expire.h"
  30.  
  31. INFO my_stuff;
  32.  
  33. /*------------------------------- main --------------------------------*/
  34. void main(int argc, char *argv[])
  35. {
  36.     /*
  37.      *  This routine expires the news database thus:
  38.      *    - copy the index and text files into new ones, omitting the old ones
  39.      *    - update the article counters
  40.      *    - delete the old articles and rename the new files
  41.      *    - print the totals
  42.      *
  43.      *  TODO: It's too big a hunk break it up
  44.      */
  45.  
  46.     ACTIVE *gp, *head;
  47.     char   *fn, buf[256], buf2[256], subject[256];
  48.     struct stat st;
  49.     time_t current;
  50.     long   secs, i, offset;
  51.     int    days;
  52.     int    no_space;
  53.     int    cnt;
  54.     int    matches;
  55.     long   art_time;
  56.     long   where;
  57.  
  58.     FILE   *index;
  59.     FILE   *old_index;
  60.     FILE   *text;
  61.     FILE   *old_text;
  62.  
  63.     long   articles = 0;
  64.     long   articles_deleted = 0;
  65.     long   gp_art;
  66.     long   gp_art_deleted;
  67.  
  68.     long   total_bytes = 0;
  69.     long   total_bytes_deleted = 0;
  70.     long   gp_bytes;
  71.     long   gp_bytes_deleted;
  72.  
  73.  
  74.     fprintf(stderr, "EXPIRE: (%s)\n\n", VERSION);
  75.  
  76.     if (argc < 2) {
  77.         fprintf(stderr, "usage: expire -<days> [group-pattern ...]\n");
  78.     exit(1);
  79.     }
  80.  
  81.     argc--;
  82.     argv++;
  83.  
  84.     time(¤t);
  85.  
  86.     if ( **argv == '-' ) {
  87.         days = atoi(*argv + 1);
  88.         secs = days * 86400l;
  89.     argc--;
  90.     argv++;
  91.     } else {
  92.         fprintf(stderr, "usage: expire -<days> [group-pattern ...]\n");
  93.     exit(1);
  94.     }
  95.  
  96.     if (!load_stuff()) {
  97.     fprintf(stderr, "Couldn't read rc info\n"); 
  98.     exit(1);
  99.     }
  100.  
  101.     head = load_active_file();
  102.     gp = head;
  103.  
  104.     printf("%-40s :      ARTICLES         DELETED\n\n", "NEWSGROUP");
  105.  
  106.     for (gp = head; gp != NULL; gp = gp->next) {
  107.  
  108.     no_space = FALSE;
  109.  
  110.     gp_art = 0;
  111.     gp_art_deleted = 0;
  112.     gp_bytes = 0;
  113.     gp_bytes_deleted = 0;
  114.  
  115.     if ((gp->hi_num - gp->lo_num) > 0) {
  116.  
  117.           printf("%-40s :  ", gp->group);
  118.           fflush(stdout);
  119.           
  120.         /*
  121.          *  Open all the files.  First the old ones, then the new
  122.          */
  123.  
  124.         fn = make_news_group_name(gp->group);
  125.         stat(fn, &st);
  126.  
  127.         if (argc) {
  128.         matches = FALSE;
  129.         for (cnt = 0; cnt < argc; cnt++)
  130.           if (amatch(argv[cnt], gp->group))
  131.             matches = TRUE;
  132.         } 
  133.         else
  134.           matches = TRUE;
  135.  
  136.         if (!matches) {
  137.         gp_art = gp->hi_num - gp->lo_num;
  138.         printf("%4ld %5ld k\n", gp_art, (st.st_size+500)/1000);
  139.         articles += gp_art;
  140.         total_bytes += st.st_size;
  141.         continue;
  142.         }
  143.  
  144.         gp_bytes_deleted = st.st_size;
  145.  
  146.         if ((old_text = fopen(fn, "rb")) == NULL) 
  147.           crash("can't open old text", fn);
  148.         setvbuf(old_text, NULL, _IOFBF, IOBUFSIZE);
  149.         sprintf(buf, "%s.idx", fn);
  150.         if ((old_index = fopen(buf, "rb")) == NULL) 
  151.           crash("can't open old index", buf);
  152.         setvbuf(old_index, NULL, _IOFBF, IOBUFSIZE);
  153.  
  154.         sprintf(buf, "%s.new", fn);
  155.         if ((text = fopen(buf, "wb")) == NULL) 
  156.           crash("can't create new text", buf);
  157.         setvbuf(text, NULL, _IOFBF, IOBUFSIZE);
  158.         sprintf(buf, "%s.ndx", fn);
  159.         if ((index = fopen(buf, "wb")) == NULL) 
  160.           crash("can't create new index", buf);
  161.         setvbuf(index, NULL, _IOFBF, IOBUFSIZE);
  162.  
  163.         /* numbers go chronologically */
  164.         for (i = (gp->lo_num)+1; i <= gp->hi_num; i++) {
  165.  
  166.         fgets(buf, 255, old_index);
  167.         if (i != atol(buf+9)) {
  168.             fprintf(stderr, "\nsnews: article %ld found when %ld"
  169.                 " expected\n", atol(buf+9), i);
  170.             exit(1);
  171.         }
  172.  
  173.         /* get the time the article was processed */
  174.         art_time = atol(buf+18);
  175.         /* and the subject */
  176.         strcpy(subject, buf+28);
  177.  
  178.         if ((current - art_time) > secs) {
  179.  
  180.             /*
  181.              *  Older than req'd - just count the totals
  182.              */
  183.  
  184.             gp_art_deleted++;
  185.  
  186.             gp->lo_num++;
  187.             update_active_entry(gp);
  188.  
  189.         } else {
  190.  
  191.             /*
  192.              *  Younger than limit, so keep the article
  193.              */
  194.             where = ftell(text);
  195.  
  196.             /* copy to new file */
  197.             offset = atol(buf);
  198.             fseek(old_text, offset, SEEK_SET);
  199.               
  200.             while (fgets(buf, 255, old_text)) {
  201.  
  202.             if (fputs(buf, text) == EOF) {
  203.                 no_space = TRUE;
  204.                 break;
  205.             }
  206.             
  207.             if (strnicmp(buf, "@@@@END", 7) == 0) break;
  208.             }
  209.  
  210.             /* save the header info */
  211.             fprintf(index,"%08ld %08ld %09ld %s", where, i,
  212.                 art_time, subject);
  213.         }
  214.  
  215.         if (no_space) break;
  216.         }
  217.  
  218.         /*
  219.          *  Close and rename the files
  220.          */
  221.  
  222.         fclose(old_text);
  223.         fclose(old_index);
  224.         fclose(text);
  225.         fclose(index);
  226.  
  227.         /* out of disk on expire, delete the temp files */
  228.         if (no_space) {
  229.         fprintf(stderr, "expire: no room to expire %s\n", gp->group);
  230.         sprintf(buf2, "%s.NEW", fn);
  231.         unlink(buf2);
  232.         sprintf(buf2, "%s.NDX", fn);
  233.         unlink(buf2);
  234.         } else {
  235.         unlink(fn);
  236.         sprintf(buf2, "%s.NEW", fn);
  237.         stat(buf2, &st);
  238.         gp_bytes = st.st_size;
  239.         rename(buf2, fn);
  240.  
  241.         sprintf(buf, "%s.IDX", fn);
  242.         unlink(buf);
  243.         sprintf(buf2, "%s.NDX", fn);
  244.         rename(buf2, buf);
  245.         }
  246.  
  247.         /* print all groups with articles */
  248.  
  249.         gp_art = gp->hi_num - gp->lo_num;
  250.         gp_bytes_deleted -= gp_bytes;
  251.  
  252.         articles += gp_art;
  253.         articles_deleted += gp_art_deleted;
  254.         total_bytes += gp_bytes;
  255.         total_bytes_deleted += gp_bytes_deleted;
  256.  
  257.         if ((gp_art > 0) || (gp_art_deleted > 0)) {
  258.  
  259.         if (gp_art_deleted > 0)
  260.           printf("%4ld %5ld k     %4ld %5ld k\n",
  261.              gp_art, (gp_bytes+500)/1000,
  262.              gp_art_deleted, (gp_bytes_deleted+500)/1000);
  263.         else
  264.           printf("%4ld %5ld k\n",
  265.              gp_art, (gp_bytes+500)/1000);
  266.  
  267.         }
  268.     }
  269.  
  270.     }
  271.  
  272.     close_active_file();
  273.     expire_history(current, secs);
  274.  
  275.     printf("\n%7ld articles deleted\n"
  276.        "%7ld k of text deleted\n"
  277.        "%7ld articles remaining\n"
  278.        "%7ld k of text remaining\n",
  279.        articles_deleted,
  280.        (total_bytes_deleted+500)/1000,
  281.        articles,
  282.        (total_bytes+500)/1000);
  283.  
  284.     exit(0);
  285. }
  286.  
  287.  
  288. /*----------------------------------------------------------------------*/
  289. void crash(char *msg, char *fn)
  290. {
  291.     /*
  292.      *  Abort if file open error
  293.      */
  294.  
  295.     fprintf(stderr, "\nexpire: %s, %s\n", msg, fn);
  296.     exit(1);
  297. }
  298.  
  299.  
  300. /*--------------------------- expire history entries --------------------*/
  301. void expire_history(long current, long secs)
  302. {
  303.     FILE *hist_file, *new_hist_file;
  304.     long age;
  305.     char buf[512], buf2[256];
  306.  
  307.  
  308.     /* open the files */
  309.     sprintf(buf, "%shistory", my_stuff.news_dir);
  310.     if ((hist_file = fopen(buf, "rb")) == NULL) {
  311.         fprintf(stderr, "expire: cannot open file %s for input\n", buf);
  312.         exit(1);
  313.     }
  314.     setvbuf(hist_file, NULL, _IOFBF, IOBUFSIZE);
  315.     sprintf(buf, "%shistory.new", my_stuff.news_dir);
  316.     if ((new_hist_file = fopen(buf, "wb")) == NULL) {
  317.         fprintf(stderr, "expire: cannot open file %s for output\n", buf);
  318.         exit(1);
  319.     }
  320.     setvbuf(new_hist_file, NULL, _IOFBF, IOBUFSIZE);
  321.  
  322.     while (fgets(buf, 255, hist_file) != NULL) {
  323.         sscanf(buf, "%*s %ld", &age);
  324.         if ((current-age) < secs) {
  325.             fputs(buf, new_hist_file);
  326.         }
  327.     }
  328.  
  329.     fclose(hist_file);
  330.     fclose(new_hist_file);
  331.  
  332.     sprintf(buf, "%shistory.bak", my_stuff.news_dir);
  333.     unlink(buf);
  334.     sprintf(buf2, "%shistory", my_stuff.news_dir);
  335.     rename(buf2, buf);
  336.     sprintf(buf, "%shistory.new", my_stuff.news_dir);
  337.     rename(buf, buf2);
  338.     sprintf(buf, "%shistory.bak", my_stuff.news_dir);
  339.     unlink(buf);
  340. }
  341.