home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
snws190s.zip
/
EXPIRE.C
< prev
next >
Wrap
Text File
|
1992-03-19
|
11KB
|
341 lines
/*
Simple NEWS
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
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.
USAGE: expires <days>
*/
#include "defs.h"
#include <io.h>
#include "expire.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], inchar = ' ';
struct stat st;
time_t current;
long secs, i, offset;
int days;
int no_space;
int no_msgs;
int subdone;
long art_time;
long where;
FILE *index;
FILE *old_index;
FILE *text;
FILE *old_text;
int articles;
int articles_deleted;
int gp_art;
int gp_art_deleted;
long total_bytes;
long total_bytes_deleted;
long gp_bytes;
long gp_bytes_deleted;
articles = 0;
articles_deleted = 0;
total_bytes = 0;
total_bytes_deleted = 0;
fprintf(stderr, "NEWSBASE EXPIRE\n%s\n\n", VERSION);
if (argc == 2) {
if (!load_stuff()) {
fprintf(stderr, "Couldn't read rc info\n");
}
head = load_active_file();
time(¤t);
days = atoi(argv[1]);
secs = days * 86400l;
gp = head;
printf("NEWSGROUP : ARTICLES DELETED\n\n");
while (gp != NULL) {
no_space = FALSE;
gp_art = 0;
gp_art_deleted = 0;
gp_bytes = 0;
gp_bytes_deleted = 0;
if ((gp->hi_num - gp->lo_num) <= 0) {
printf("%-35s is empty. Next newsgroup.",gp->group);
no_msgs = TRUE;
inchar = 'e';
}
if ((gp->hi_num - gp->lo_num) > 0) {
no_msgs = FALSE;
printf("%-35s, process it: ",gp->group);
inchar = getch();
if (inchar == 'y' || inchar == 'Y') {
/*
* Open all the files. First the old ones, then the new
*/
fn = make_news_group_name(gp->group);
stat(fn, &st);
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, 16384);
sprintf(buf, "%s.IDX", fn);
if ((old_index = fopen(buf, "rb")) == NULL) crash("can't open old index", buf);
sprintf(buf, "%s.NEW", fn);
if ((text = fopen(buf, "wb")) == NULL) crash("can't create new text", buf);
setvbuf(text, NULL, _IOFBF, 16384);
sprintf(buf, "%s.NDX", fn);
if ((index = fopen(buf, "wb")) == NULL) crash("can't create new index", buf);
/* numbers go chronologically */
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);
if ((current - art_time) > secs) {
/*
* Older than req'd - just count the totals
*/
gp_art_deleted++;
gp->lo_num++;
update_active_entry(gp);
} else {
/*
* Younger than limit, so keep the article
*/
subdone = FALSE;
where = ftell(text);
/* copy to new file */
offset = atol(buf);
fseek(old_text, offset, SEEK_SET);
while (fgets(buf, 255, old_text)) {
if ((strnicmp(buf,"Subject:",8) == 0) &&
(subdone == FALSE)) {
strcpy(subject, buf+8);
subdone = TRUE;
}
if (fputs(buf, text) == EOF) {
no_space = TRUE;
break;
}
if (strnicmp(buf, "@@@@END", 7) == 0) break;
}
/* save the header info */
fprintf(index,"%08ld %08ld %09ld %s", where, i,
art_time, subject);
}
if (no_space) break;
}
/*
* Close and rename the files
*/
fclose(old_text);
fclose(old_index);
fclose(text);
fclose(index);
fn = make_news_group_name(gp->group);
/* 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 = (int)(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("\r%-35s : %4d %5ldKb %4d %5ldKb",
gp->group,
gp_art, (gp_bytes+500)/1000,
gp_art_deleted, (gp_bytes_deleted+500)/1000);
else
printf("\r%-35s : %4d %5ldKb",
gp->group,
gp_art, (gp_bytes+500)/1000);
}
}
} else { if (!no_msgs)
printf(" Area skipped... Next area.");
}
if (inchar != 'y' && inchar != 'Y' && inchar != 'q' && inchar != 'Q' && inchar != 'e')
{ printf("\r%-35s Area skipped...",gp->group);}
if (inchar == 'q' || inchar == 'Q') {
printf("\r%-35s Area skipped... Quit requested.",gp->group);
while (gp != NULL)
gp = gp->next;}
else
{gp = gp->next;}
printf("\n");
}
close_active_file();
expire_history(current, secs);
printf("\nOf the newsgroups that were altered:\n"
"\n%7d articles were deleted\n"
"%7ld Kb were deleted\n"
"%7d articles are remaining\n"
"%7ld Kb of text is remaining\n",
articles_deleted,
(total_bytes_deleted+500)/1000,
articles,
(total_bytes+500)/1000);
} else {
fprintf(stderr, "usage: expire <days>\n");
}
}
/*----------------------------------------------------------------------*/
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);
}
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);
}
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);
}