home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 1.91
-
- EXPIRE - expire news database articles by number of days since rx'd
-
-
- Copyright (C) 1991 John McCombs, PO Box 2708, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
-
- Modifications copyright (C) 1993 Daniel Fandrich
- <dan@fch.wimsey.bc.ca> or CompuServe 72365,306
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
-
- Source is formatted with a tab size of 4.
-
-
- usage: expire [-e <days> || -<days>] [-n] [group-pattern ...]
-
- where <days> is number of days of articles to expire
- group-pattern is an optionally wildcard group name to expire
- -e gives an alternate form for specifying days to expire
- -n is ignored
- */
-
- #include "defs.h"
- #include "expire.h"
- #include "amatch.h"
- #include <io.h>
- #include <ctype.h>
-
- INFO my_stuff;
-
- /*------------------------------- main --------------------------------*/
- void main(int argc, char *argv[])
- {
- /*
- * This routine expires the news database thus:
- * - copy the index and text files into new ones, omitting the old ones
- * - update the article counters
- * - delete the old articles and rename the new files
- * - print the totals
- *
- * TODO: It's too big a hunk break it up
- */
-
- ACTIVE *gp, *head;
- char *fn, buf[256], buf2[256], subject[256];
- struct stat st;
- time_t current;
- long secs, i, offset;
- int days;
- int no_space = FALSE;
- int cnt;
- int matches;
- long art_time;
- long where;
-
- FILE *index;
- FILE *old_index;
- FILE *text;
- FILE *old_text;
-
- long articles = 0;
- long articles_deleted = 0;
- long gp_art;
- long gp_art_deleted;
-
- long total_bytes = 0;
- long total_bytes_deleted = 0;
- long gp_bytes;
- long gp_bytes_deleted;
-
- signal(SIGINT, sig_break); /* turn control-break off */
-
- fprintf(stderr, "EXPIRE: (%s)\n\n", VERSION);
-
- if ((argc < 2) || ((argv[1][0] == '-') &&
- (!isdigit(argv[1][1]) && (argv[1][1] != 'e')))) {
- fprintf(stderr, "usage: expire [-e <days> || -<days>] [-n] [group-pattern ...]\n");
- exit(2);
- }
-
- argc--;
- argv++;
-
- time(¤t);
-
- /* get days to expire in -<days> format */
- if ((argv[0][0] == '-') && isdigit(argv[0][1])) {
- days = atoi(*argv + 1);
- secs = days * 86400l;
- argc--;
- argv++;
-
- /* get days to expire in -e <days> format */
- } else if ((argc >= 2) && (argv[0][0] == '-') && (argv[0][1] == 'e') &&
- isdigit(argv[1][0])) {
- argc--;
- argv++;
- days = atoi(*argv);
- secs = days * 86400l;
- argc--;
- argv++;
-
- } else {
- fprintf(stderr, "usage: expire [-e <days> || -<days>] [-n] [group-pattern ...]\n");
- exit(1);
- }
-
- /* ignore -n flag */
- if (argc && (argv[0][0] == '-') && (argv[0][1] == 'n')) {
- argc--;
- argv++;
- }
-
- if (!load_stuff()) {
- fprintf(stderr, "Couldn't read rc info\n");
- exit(1);
- }
-
- head = load_active_file();
-
-
-
- printf("%-40s : ARTICLES DELETED\n\n", "NEWSGROUP");
-
- for (gp = head; (gp != NULL) && !no_space && !break_hit; gp = gp->next) {
-
- gp_art = 0;
- gp_art_deleted = 0;
- gp_bytes = 0;
- gp_bytes_deleted = 0;
-
- if ((gp->hi_num - gp->lo_num) > 0) {
-
- printf("%-40s : ", gp->group);
- fflush(stdout);
-
- /*
- * Open all the files. First the old ones, then the new
- */
-
- fn = make_news_group_name(gp->group);
- stat(fn, &st);
-
- if (argc) {
- matches = FALSE;
- for (cnt = 0; cnt < argc; cnt++)
- if (amatch(argv[cnt], gp->group))
- matches = TRUE;
- }
- else
- matches = TRUE;
-
- if (!matches) {
- gp_art = gp->hi_num - gp->lo_num;
- printf("%4ld %5ld k\n", gp_art, (st.st_size+500)/1000);
- articles += gp_art;
- total_bytes += st.st_size;
- continue;
- }
-
- gp_bytes_deleted = st.st_size;
-
- if ((old_text = fopen(fn, "rb")) == NULL)
- crash("can't open old text", fn);
- setvbuf(old_text, NULL, _IOFBF, IOBUFSIZE);
- sprintf(buf, "%s.idx", fn);
- if ((old_index = fopen(buf, "rb")) == NULL)
- crash("can't open old index", buf);
- setvbuf(old_index, NULL, _IOFBF, IOBUFSIZE);
-
- sprintf(buf, "%s.new", fn);
- if ((text = fopen(buf, "wb")) == NULL)
- crash("can't create new text", buf);
- setvbuf(text, NULL, _IOFBF, IOBUFSIZE);
- sprintf(buf, "%s.ndx", fn);
- if ((index = fopen(buf, "wb")) == NULL)
- crash("can't create new index", buf);
- setvbuf(index, NULL, _IOFBF, IOBUFSIZE);
-
- /* numbers go chronologically -- unless an odd thing happened during
- unbatch, in which case this routine can make article numbers in
- the user's .nrc file not match up with actual articles */
-
- for (i = (gp->lo_num)+1; i <= gp->hi_num; i++) {
-
- fgets(buf, 255, old_index);
- if (i != atol(buf+9)) {
- fprintf(stderr, "\nsnews: article %ld found when %ld"
- " expected\n", atol(buf+9), i);
- exit(1);
- }
-
- /* get the time the article was processed */
- art_time = atol(buf+18);
- /* and the subject */
- strcpy(subject, buf+28);
-
- if ((current - art_time) > secs) {
-
- /*
- * Older than req'd - just count the totals
- */
-
- gp_art_deleted++;
- gp->lo_num++;
-
- } else {
-
- /*
- * Younger than limit, so keep the article
- */
- where = ftell(text);
-
- /* copy to new file */
- offset = atol(buf);
- fseek(old_text, offset, SEEK_SET);
-
- while (fgets(buf, 255, old_text)) {
-
- if (fputs(buf, text) == EOF) {
- no_space = TRUE;
- break;
- }
-
- if (strnicmp(buf, "@@@@END", 7) == 0)
- break;
- } /* while */
-
- /* save the header info */
- fprintf(index,"%08ld %08ld %09ld %s", where, i,
- art_time, subject);
- }
-
- if (no_space)
- break;
- } /* for */
-
- /*
- * Close and rename the files
- */
-
- fclose(old_text);
- fclose(old_index);
- if (fclose(text))
- no_space = TRUE;
- if (fclose(index))
- no_space = TRUE;
-
- if (!no_space)
- update_active_entry(gp);
-
- /* out of disk on expire, delete the temp files */
- if (no_space) {
- fprintf(stderr, "expire: no room to expire %s\n", gp->group);
- sprintf(buf2, "%s.NEW", fn);
- unlink(buf2);
- sprintf(buf2, "%s.NDX", fn);
- unlink(buf2);
-
- } else {
- unlink(fn);
- sprintf(buf2, "%s.NEW", fn);
- stat(buf2, &st);
- gp_bytes = st.st_size;
- rename(buf2, fn);
-
- sprintf(buf, "%s.IDX", fn);
- unlink(buf);
- sprintf(buf2, "%s.NDX", fn);
- rename(buf2, buf);
- }
-
- /* print all groups with articles */
-
- gp_art = gp->hi_num - gp->lo_num;
- gp_bytes_deleted -= gp_bytes;
-
- articles += gp_art;
- articles_deleted += gp_art_deleted;
- total_bytes += gp_bytes;
- total_bytes_deleted += gp_bytes_deleted;
-
- if ((gp_art > 0) || (gp_art_deleted > 0)) {
-
- if (gp_art_deleted > 0)
- printf("%4ld %5ld k %4ld %5ld k\n",
- gp_art, (gp_bytes+500)/1000,
- gp_art_deleted, (gp_bytes_deleted+500)/1000);
- else
- printf("%4ld %5ld k\n",
- gp_art, (gp_bytes+500)/1000);
-
- }
- }
-
- } /* for */
-
- close_active_file();
- if (!no_space)
- expire_history(current, secs);
-
- printf("\n%7ld articles deleted\n"
- "%7ld k of text deleted\n",
- articles_deleted,
- (total_bytes_deleted+500)/1000);
- if (!no_space)
- printf("%7ld articles remaining\n"
- "%7ld k of text remaining\n",
- articles,
- (total_bytes+500)/1000);
-
- exit(no_space);
- }
-
-
- /*----------------------------------------------------------------------*/
- void crash(char *msg, char *fn)
- {
- /*
- * Abort if file open error
- */
-
- fprintf(stderr, "\nexpire: %s, %s\n", msg, fn);
- exit(1);
- }
-
-
- /*--------------------------- expire history entries --------------------*/
- void expire_history(long current, long secs)
- {
- FILE *hist_file, *new_hist_file;
- long age;
- char buf[512], buf2[256];
-
-
- /* open the files */
- sprintf(buf, "%shistory", my_stuff.news_dir);
- if ((hist_file = fopen(buf, "rb")) == NULL) {
- fprintf(stderr, "expire: cannot open file %s for input\n", buf);
- exit(1);
- }
- setvbuf(hist_file, NULL, _IOFBF, IOBUFSIZE);
- sprintf(buf, "%shistory.new", my_stuff.news_dir);
- if ((new_hist_file = fopen(buf, "wb")) == NULL) {
- fprintf(stderr, "expire: cannot open file %s for output\n", buf);
- exit(1);
- }
- setvbuf(new_hist_file, NULL, _IOFBF, IOBUFSIZE);
-
- while (fgets(buf, 255, hist_file) != NULL) {
- sscanf(buf, "%*s %ld", &age);
- if ((current-age) < secs) {
- fputs(buf, new_hist_file);
- }
- }
-
- fclose(hist_file);
- fclose(new_hist_file);
-
- sprintf(buf, "%shistory.bak", my_stuff.news_dir);
- unlink(buf);
- sprintf(buf2, "%shistory", my_stuff.news_dir);
- rename(buf2, buf);
- sprintf(buf, "%shistory.new", my_stuff.news_dir);
- rename(buf, buf2);
- sprintf(buf, "%shistory.bak", my_stuff.news_dir);
- unlink(buf);
- }