home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beijing Paradise BBS Backup
/
PARADISE.ISO
/
software
/
BBSDOORW
/
SNWS191S.ZIP
/
EXPIRE.C
< prev
next >
Wrap
Text File
|
1993-08-16
|
10KB
|
383 lines
/*
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);
}