expire.c
rick
rick
Tue Oct 26 21:10:31 AEST 1982
/*
* expire - expire daemon runs around and nails all articles that
* have expired.
*/
static char *SccsId = "@(#) expire.c 2.10 6/21/82";
#include "params.h"
#include <ndir.h>
extern char groupdir[BUFSIZ], rcbuf[BUFLEN];
extern char *ACTIVE;
extern char *SPOOL;
extern char *CAND;
char ARTFILE[BUFSIZ], NARTFILE[BUFSIZ], OARTFILE[BUFSIZ];
extern char filename[];
char *OLDNEWS = "/usr/spool/oldnews";
int verbose = 0;
int ignorexp = 0;
int doarchive = 0;
int nohistory = 0;
int rebuild = 0;
#define NART 100
struct multhist {
char mh_ident[14];
char *mh_file;
}multhist[NART];
long expincr;
long atol();
time_t cgtdate(), time();
FILE *popen();
main(argc, argv)
int argc;
char **argv;
{
register int i;
register FILE *fp = NULL, *actfp;
register char *ptr;
struct hbuf h;
struct stat statbuf;
register time_t now, newtime;
char ngpat[LBUFLEN];
char afline[BUFLEN];
char *p1, *p2;
FILE *ohfd, *nhfd;
DIR *ngdirp;
static struct direct *ngdir;
expincr = DFLTEXP;
ngpat[0] = '\0';
while (argc > 1) {
switch (argv[1][1]) {
case 'v':
if (isdigit(argv[1][2]))
verbose = argv[1][2] - '0';
else
verbose = 1;
break;
case 'e': /* Use this as default expiration time */
if (argc > 2 && argv[2][0] != '-') {
argv++;
argc--;
expincr = atol(argv[1]) * DAYS;
}
break;
case 'I': /* Ignore any existing expiration date */
ignorexp = 2;
break;
case 'i': /* Ignore any existing expiration date */
ignorexp = 1;
break;
case 'n':
if (argc > 2) {
argv++;
argc--;
while (argc > 1 && argv[1][0] != '-') {
strcat(ngpat, argv[1]);
ngcat(ngpat);
argv++;
argc--;
}
argv--;
argc++;
}
break;
case 'a': /* archive expired articles */
doarchive++;
break;
case 'h': /* ignore history */
nohistory++;
break;
case 'r': /* rebuild history file */
rebuild++;
nohistory++;
break;
default:
printf("Usage: expire [ -v [level] ] [-e days ] [-i] [-n newsgroups]\n");
exit(1);
}
argc--; argv++;
}
if (ngpat[0] == 0)
strcpy(ngpat, "all,");
now = time(0);
if (chdir(SPOOL))
xerror("Cannot chdir %s", SPOOL);
sprintf(OARTFILE, "%s/%s", LIB, "ohistory");
sprintf(ARTFILE, "%s/%s", LIB, "history");
sprintf(NARTFILE, "%s/%s", LIB, "nhistory");
if (nohistory) {
ohfd = xfopen(ACTIVE, "r");
if (rebuild){
sprintf(afline,"sort +2 >%s",NARTFILE);
if ((nhfd=popen(afline,"w")) == NULL)
xerror("Cannot exec %s",NARTFILE);
} else
nhfd = xfopen("/dev/null", "w");
} else {
ohfd = xfopen(ARTFILE, "r");
nhfd = xfopen(NARTFILE, "w");
}
while (TRUE) {
if (nohistory){
do {
if (ngdir == NULL) {
if( ngdirp != NULL )
closedir(ngdirp);
if (fgets(afline, BUFLEN, ohfd) == NULL)
goto out;
strcpy(groupdir,afline);
p1 = index(groupdir, '\n');
if (p1)
*p1 = NULL;
ngcat(groupdir);
if (!ngmatch(groupdir,ngpat))
continue;
ngdel(groupdir);
if ((ngdirp=opendir(groupdir)) == NULL)
continue;
}
ngdir = readdir(ngdirp);
} while ( ngdir == NULL || ngdir->d_name[0] == '.' );
sprintf(filename,"%s/%s",groupdir,ngdir->d_name);
p2 = filename;
if (verbose > 2)
printf("article: %s\t", filename);
} else {
if (fgets(afline, BUFLEN, ohfd) == NULL)
break;
if (verbose > 2)
printf("article: %s", afline);
p1 = index(afline, '\t');
if (p1)
p2 = index(p1+1, '\t');
else
continue;
if (!p2)
continue;
p2++;
strcpy(groupdir, p2);
p1 = index(groupdir, '/');
if (p1)
*p1 = 0;
else
continue;
ngcat(groupdir);
if (!ngmatch(groupdir, ngpat)) {
fputs(afline, nhfd);
continue;
}
ngdel(groupdir);
strcpy(filename, p2);
p1 = index(filename, ' ');
if (p1 == 0)
p1 = index(filename, '\n');
if (p1)
*p1 = 0;
}
if (access(filename, 4) || (fp = fopen(filename, "r")) == NULL) {
if (verbose > 3)
printf("Can't open %s.\n", filename);
continue;
}
if (hread(&h, fp) == NULL) {
if (verbose)
printf("Garbled article %s.\n", filename);
fclose(fp);
continue;
}
if (rebuild){
register char *cp;
register struct multhist *mhp;
if ((cp=index(h.nbuf,NGDELIM)) == NULL) {
saveit:
fprintf(nhfd,"%s\t%s\t%s \n",h.ident,h.recdate,filename);
fclose(fp);
continue;
}
for (mhp=multhist;mhp->mh_ident[0]!=NULL&&mhp<&multhist[NART];mhp++) {
if (mhp->mh_file == NULL)
continue;
if (strcmp(mhp->mh_ident,h.ident) != 0)
continue;
if (index(mhp->mh_file,' ') != NULL)
cp = index(++cp,NGDELIM);
strcat(filename," ");
strcat(filename,mhp->mh_file);
free(mhp->mh_file);
if (*cp == NULL || (cp=index(++cp,NGDELIM)) == NULL) {
mhp->mh_file = NULL;
goto saveit;
} else
break;
}
if (mhp>=&multhist[NART])
xerror("Too many articles with multiple newsgroups");
strcpy(mhp->mh_ident,h.ident);
cp = malloc(strlen(filename)+1);
if ( cp == NULL)
xerror("Out of memory");
strcpy(cp,filename);
mhp->mh_file = cp;
fclose(fp);
continue;
}
if (h.expdate[0])
h.exptime = cgtdate(h.expdate);
newtime = cgtdate(h.recdate) + expincr;
if (!h.expdate[0] || ignorexp==2 ||
(ignorexp==1 && newtime < h.exptime))
h.exptime = newtime;
if (now >= h.exptime) {
#ifdef DEBUG
printf("cancel %s\n", filename);
#else
if (verbose)
printf("cancel %s\n", filename);
ulall(p2,&h);
#endif
}
else {
fputs(afline, nhfd);
if (verbose > 2)
printf("Good article %s\n", rcbuf);
}
fclose(fp);
}
out:
if (rebuild){
register struct multhist *mhp;
for (mhp=multhist;mhp->mh_ident[0]!=NULL&&mhp<&multhist[NART];mhp++)
/* should "never" happen */
if (mhp->mh_file != NULL )
printf("Article: %s %s Cannot find all links\n",mhp->mh_ident,mhp->mh_file);
pclose(nhfd);
}
if (rebuild || !nohistory){
unlink(OARTFILE);
link(ARTFILE, OARTFILE);
unlink(ARTFILE);
link(NARTFILE, ARTFILE);
unlink(NARTFILE);
}
exit(0);
}
ulall(artlist,h)
char *artlist;
struct hbuf *h;
{
char *p;
int last = 0;
char newname[BUFLEN];
char newgroup[BUFLEN];
time_t timep[2];
if (nohistory){
last = 1;
} else {
while (*artlist == ' ' || *artlist == '\n' || *artlist == ',')
artlist++;
if (*artlist == 0)
return;
p = index(artlist, ' ');
if (p == 0) {
last = 1;
p = index(artlist, '\n');
}
if (p == 0) {
last = 1;
p = index(artlist, ',');
}
if (p == 0) {
last = 1;
unlink(artlist);
return;
}
if (p)
*p = 0;
}
if (doarchive && access(OLDNEWS, 0) == 0) {
strcpy(newgroup, artlist);
p = index(newgroup, '/');
*p = 0;
sprintf(newname, "%s/%s/%s", OLDNEWS, newgroup, h->ident);
if (verbose > 1)
printf("link %s to %s\n", newname, filename);
if (link(artlist, newname) == -1) {
if (mkdir(newgroup) == 0)
link(artlist, newname);
}
timep[0] = timep[1] = cgtdate(h->subdate);
utime(newname,timep);
}
if (verbose)
printf("unlink %s\n", artlist);
unlink(artlist);
if (!last)
ulall(p+1,h);
}
xerror(message)
char *message;
{
printf("expire: %s.\n", message);
fflush(stdout);
exit(1);
}
mkdir(groupdir)
register char *groupdir;
{
char buf[BUFLEN];
register struct passwd *pw;
extern char *NEWSU;
int rc;
if (access(OLDNEWS, 2) < 0)
return -1;
sprintf(buf, "mkdir %s/%s", OLDNEWS, groupdir);
rc = system(buf);
sprintf(buf, "%s/%s", OLDNEWS, groupdir);
if (verbose)
printf("mkdir %s, rc %d\n", buf, rc);
chmod(buf, 0755);
if ((pw = getpwnam(NEWSU)) != NULL)
chown(buf, pw->pw_uid, pw->pw_gid);
return rc;
}
More information about the Comp.sources.unix
mailing list