Annotation of researchv10dc/cmd/netnews/src/expire.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * expire - expire daemon runs around and nails all articles that
                      3:  *              have expired.
                      4:  *
                      5:  * Note: This version of expire contains some code to implement new
                      6:  * history features, e.g. to work without a history file or to rebuild
                      7:  * the history file.  This code was written for B news 2.9 and would
                      8:  * need some conversion to deal with the 2.10 heirarchical subgroups
                      9:  * in subdirectories.  This would imply a recursive traversal of the
                     10:  * tree.  Such code could be written but I didn't have the energy to
                     11:  * convert this 2.9 style code.
                     12:  */
                     13: 
                     14: static char    *SccsId = "@(#)expire.c 2.16    6/24/83";
                     15: 
                     16: #include "params.h"
                     17: #include "ndir.h"
                     18: 
                     19: #define NART   100
                     20: 
                     21: extern char    groupdir[BUFSIZ], rcbuf[BUFLEN];
                     22: extern char    ACTIVE[];
                     23: extern char    SPOOL[];
                     24: extern char    ARTFILE[];
                     25: extern char    filename[];
                     26: char   NARTFILE[BUFSIZ], OARTFILE[BUFSIZ];
                     27: char   OLDNEWS[BUFLEN];
                     28: int    verbose = 0;
                     29: int    ignorexp = 0;
                     30: int    doarchive = 0;
                     31: int    nohistory = 0;
                     32: int    rebuild = 0;
                     33: 
                     34: /*
                     35:  * The code dealing with this is ifdeffed out.
                     36:  * However, it should be redone to malloc the mh_ident
                     37:  * fields, and realloc the multhist array, so that the
                     38:  * fixed constant NART can be done away with.  Apparently
                     39:  * when rebuilding the history file, 100 is much too small.
                     40:  */
                     41: struct multhist {
                     42:        char    mh_ident[BUFLEN];
                     43:        char    *mh_file;
                     44: } multhist[NART];
                     45: 
                     46: typedef struct {
                     47:        char *dptr;
                     48:        int dsize;
                     49: } datum;
                     50: 
                     51: long   expincr;
                     52: long   atol();
                     53: time_t cgtdate(), time();
                     54: FILE *popen();
                     55: 
                     56: main(argc, argv)
                     57: int    argc;
                     58: char   **argv;
                     59: {
                     60:        register int    i;
                     61:        register FILE *fp = NULL, *actfp;
                     62:        register char   *ptr;
                     63:        struct hbuf h;
                     64:        struct stat statbuf;
                     65:        register time_t now, newtime;
                     66:        char    ngpat[LBUFLEN];
                     67:        char    afline[BUFLEN];
                     68:        char    *p1, *p2, *p3;
                     69:        FILE    *ohfd, *nhfd;
                     70:        DIR     *ngdirp;
                     71:        static struct direct *ngdir;
                     72:        char fn[BUFLEN];
                     73:        datum   key;
                     74: 
                     75:        pathinit();
                     76:        umask(N_UMASK);
                     77:        expincr = DFLTEXP;
                     78:        ngpat[0] = '\0';
                     79:        while (argc > 1) {
                     80:                switch (argv[1][1]) {
                     81:                case 'v':
                     82:                        if (isdigit(argv[1][2]))
                     83:                                verbose = argv[1][2] - '0';
                     84:                        else
                     85:                                verbose = 1;
                     86:                        if (verbose < 3)
                     87:                                setbuf(stdout, NULL);
                     88:                        break;
                     89:                case 'e':       /* Use this as default expiration time */
                     90:                        if (argc > 2 && argv[2][0] != '-') {
                     91:                                argv++;
                     92:                                argc--;
                     93:                                expincr = atol(argv[1]) * DAYS;
                     94:                        }
                     95:                        break;
                     96:                case 'I':       /* Ignore any existing expiration date */
                     97:                        ignorexp = 2;
                     98:                        break;
                     99:                case 'i':       /* Ignore any existing expiration date */
                    100:                        ignorexp = 1;
                    101:                        break;
                    102:                case 'n':
                    103:                        if (argc > 2) {
                    104:                                argv++;
                    105:                                argc--;
                    106:                                while (argc > 1 && argv[1][0] != '-') {
                    107:                                        strcat(ngpat, argv[1]);
                    108:                                        ngcat(ngpat);
                    109:                                        argv++;
                    110:                                        argc--;
                    111:                                }
                    112:                                argv--;
                    113:                                argc++;
                    114:                        }
                    115:                        break;
                    116:                case 'a':       /* archive expired articles */
                    117:                        doarchive++;
                    118:                        break;
                    119: #ifdef notdef
                    120: /*
                    121:  * Nohistory and Rebuild are broken by the new directory format.
                    122:  * A recursive directory traversal needs to be made.  I don't
                    123:  * have the energy to do this - hopefully someone else will.
                    124:  */
                    125:                case 'h':       /* ignore history */
                    126:                        nohistory++;
                    127:                        break;
                    128:                case 'r':       /* rebuild history file */
                    129:                        rebuild++;
                    130:                        nohistory++;
                    131:                        break;
                    132: #endif
                    133:                default:
                    134:                        printf("Usage: expire [ -v [level] ] [-e days ] [-i] [-n newsgroups]\n");
                    135:                        exit(1);
                    136:                }
                    137:                argc--; 
                    138:                argv++;
                    139:        }
                    140:        if (ngpat[0] == 0)
                    141:                strcpy(ngpat, "all,");
                    142:        now = time(0);
                    143:        if (chdir(SPOOL))
                    144:                xerror("Cannot chdir %s", SPOOL);
                    145: 
                    146:        sprintf(OARTFILE, "%s/%s", LIB, "ohistory");
                    147:        sprintf(ARTFILE, "%s/%s", LIB, "history");
                    148:        sprintf(NARTFILE, "%s/%s", LIB, "nhistory");
                    149: #ifdef DBM
                    150:        dbminit(ARTFILE);
                    151: #endif
                    152:        if (verbose)
                    153:                printf("expire: nohistory %d, rebuild %d, doarchive %d\n",
                    154:                        nohistory, rebuild, doarchive);
                    155: 
                    156:        if (nohistory) {
                    157:                ohfd = xfopen(ACTIVE, "r");
                    158:                if (rebuild) {
                    159:                        sprintf(afline, "sort +2 >%s", NARTFILE);
                    160:                        if ((nhfd = popen(afline, "w")) == NULL)
                    161:                                xerror("Cannot exec %s", NARTFILE);
                    162:                } else
                    163:                        nhfd = xfopen("/dev/null", "w");
                    164:        } else {
                    165:                ohfd = xfopen(ARTFILE, "r");
                    166:                nhfd = xfopen(NARTFILE, "w");
                    167:        }
                    168: 
                    169:        while (TRUE) {
                    170:                if (nohistory) {
                    171: #ifdef notdef
                    172:                        do {
                    173:                                if (ngdir == NULL) {
                    174:                                        if ( ngdirp != NULL )
                    175:                                                closedir(ngdirp);
                    176:                                        if (fgets(afline, BUFLEN, ohfd) == NULL)
                    177:                                                goto out;
                    178:                                        strcpy(groupdir, afline);
                    179:                                        p1 = index(groupdir, ' ');
                    180:                                        if (p1 == NULL)
                    181:                                                p1 = index(groupdir, '\n');
                    182:                                        if (p1 != NULL)
                    183:                                                *p1 = NULL;
                    184:                                        ngcat(groupdir);
                    185:                                        if (!ngmatch(groupdir, ngpat))
                    186:                                                continue;
                    187:                                        ngdel(groupdir);
                    188:                                        if ((ngdirp = opendir(groupdir)) == NULL)
                    189:                                                continue;
                    190:                                }
                    191:                                ngdir = readdir(ngdirp);
                    192:                        } while ( ngdir == NULL || ngdir->d_name[0] == '.' );
                    193:                        sprintf(fn, "%s/%s", groupdir, ngdir->d_name);
                    194:                        p2 = fn;
                    195:                        if (verbose > 2)
                    196:                                printf("article: %s\t", fn);
                    197: #endif
                    198:                } else {
                    199:                        if (fgets(afline, BUFLEN, ohfd) == NULL)
                    200:                                break;
                    201:                        if (verbose > 2)
                    202:                                printf("article: %s", afline);
                    203:                        p1 = index(afline, '\t');
                    204:                        if (p1)
                    205:                                p2 = index(p1 + 1, '\t');
                    206:                        else
                    207:                                continue;
                    208:                        if (!p2)
                    209:                                continue;
                    210:                        p2++;
                    211:                        strcpy(groupdir, p2);
                    212:                        p3 = index(groupdir, '/');
                    213:                        if (p3)
                    214:                                *p3 = 0;
                    215:                        else {
                    216:                                /*
                    217:                                 * Nothing after the 2nd tab.  This happens
                    218:                                 * when a control message is stored in the
                    219:                                 * history file.  Use the date in the history
                    220:                                 * file to decide expiration.
                    221:                                 */
                    222:                                h.expdate[0] = 0;
                    223:                                strcpy(h.recdate, p1+1);
                    224:                                goto checkdate;
                    225:                        }
                    226:                        ngcat(groupdir);
                    227:                        if (!ngmatch(groupdir, ngpat)) {
                    228:                                fputs(afline, nhfd);
                    229:                                continue;
                    230:                        }
                    231:                        ngdel(groupdir);
                    232:                        strcpy(fn, p2);
                    233:                        p1 = index(fn, ' ');
                    234:                        if (p1 == 0)
                    235:                                p1 = index(fn, '\n');
                    236:                        if (p1)
                    237:                                *p1 = 0;
                    238:                }
                    239: 
                    240:                strcpy(filename, dirname(fn));
                    241:                if (access(filename, 4)
                    242:                || (fp = fopen(filename, "r")) == NULL) {
                    243:                        if (verbose > 3)
                    244:                                printf("Can't open %s.\n", filename);
                    245:                        continue;
                    246:                }
                    247:                if (hread(&h, fp, TRUE) == NULL) {
                    248:                        if (verbose)
                    249:                                printf("Garbled article %s.\n", filename);
                    250:                        fclose(fp);
                    251:                        continue;
                    252:                }
                    253: #ifdef notdef
                    254:                if (rebuild) {
                    255:                        register char   *cp;
                    256:                        register struct multhist *mhp;
                    257: 
                    258:                        if ((cp = index(h.nbuf, NGDELIM)) == NULL) {
                    259: saveit:
                    260:                                fprintf(nhfd, "%s\t%s\t%s \n", h.ident, h.recdate, filename);
                    261:                                fclose(fp);
                    262:                                continue;
                    263:                        }
                    264:                        for (mhp = multhist; mhp->mh_ident[0] != NULL && mhp < &multhist[NART]; mhp++) {
                    265:                                if (mhp->mh_file == NULL)
                    266:                                        continue;
                    267:                                if (strcmp(mhp->mh_ident, h.ident) != 0)
                    268:                                        continue;
                    269:                                if (index(mhp->mh_file, ' ') != NULL)
                    270:                                        cp = index(++cp, NGDELIM);
                    271:                                strcat(filename, " ");
                    272:                                strcat(filename, mhp->mh_file);
                    273:                                free(mhp->mh_file);
                    274:                                if (*cp == NULL || (cp = index(++cp, NGDELIM)) == NULL) {
                    275:                                        mhp->mh_file = NULL;
                    276:                                        goto saveit;
                    277:                                } else
                    278:                                        break;
                    279:                        }
                    280:                        if (mhp >= &multhist[NART])
                    281:                                xerror("Too many articles with multiple newsgroups");
                    282:                        strcpy(mhp->mh_ident, h.ident);
                    283:                        cp = malloc(strlen(filename) + 1);
                    284:                        if ( cp == NULL)
                    285:                                xerror("Out of memory");
                    286:                        strcpy(cp, filename);
                    287:                        mhp->mh_file = cp;
                    288:                        fclose(fp);
                    289:                        continue;
                    290:                }
                    291: #endif
                    292: 
                    293:                fclose(fp);
                    294: checkdate:
                    295:                if (h.expdate[0])
                    296:                        h.exptime = cgtdate(h.expdate);
                    297:                newtime = cgtdate(h.recdate) + expincr;
                    298:                if (!h.expdate[0] || ignorexp == 2 || 
                    299:                    (ignorexp == 1 && newtime < h.exptime))
                    300:                        h.exptime = newtime;
                    301:                if (now >= h.exptime) {
                    302: #ifdef DEBUG
                    303:                        printf("cancel %s\n", filename);
                    304: #else
                    305:                        if (verbose)
                    306:                                printf("cancel %s\n", filename);
                    307:                        ulall(p2, &h);
                    308: # ifdef DBM
                    309:                        key.dptr = h.ident;
                    310:                        key.dsize = strlen(key.dptr) +1;
                    311:                        delete(key);
                    312: # endif
                    313: #endif
                    314:                } else {
                    315:                        fputs(afline, nhfd);
                    316:                        if (verbose > 2)
                    317:                                printf("Good article %s\n", rcbuf);
                    318:                }
                    319:        }
                    320: 
                    321: out:
                    322: #ifdef notdef
                    323:        if (rebuild) {
                    324:                register struct multhist *mhp;
                    325:                for (mhp = multhist; mhp->mh_ident[0] != NULL && mhp < &multhist[NART]; mhp++)
                    326:                        /* should "never" happen */
                    327:                        if (mhp->mh_file != NULL )
                    328:                                printf("Article: %s %s Cannot find all links\n", mhp->mh_ident, mhp->mh_file);
                    329:                pclose(nhfd);
                    330:        }
                    331: #endif
                    332: 
                    333:        if (rebuild || !nohistory) {
                    334:                unlink(OARTFILE);
                    335:                link(ARTFILE, OARTFILE);
                    336:                unlink(ARTFILE);
                    337:                link(NARTFILE, ARTFILE);
                    338:                unlink(NARTFILE);
                    339:        }
                    340:        exit(0);
                    341: }
                    342: 
                    343: /* Unlink (using tail recursion) all the articles in 'artlist'. */
                    344: ulall(artlist, h)
                    345: char   *artlist;
                    346: struct hbuf *h;
                    347: {
                    348:        char    *p;
                    349:        int     last = 0;
                    350:        char    newname[BUFLEN];
                    351:        char    newgroup[BUFLEN];
                    352:        time_t  timep[2];
                    353:        char *fn;
                    354: 
                    355:        if (nohistory) {
                    356:                last = 1;
                    357:        } else {
                    358:                while (*artlist == ' ' || *artlist == '\n' || *artlist == ',')
                    359:                        artlist++;
                    360:                if (*artlist == 0)
                    361:                        return;
                    362:                p = index(artlist, ' ');
                    363:                if (p == 0) {
                    364:                        last = 1;
                    365:                        p = index(artlist, '\n');
                    366:                }
                    367:                if (p == 0) {
                    368:                        last = 1;
                    369:                        p = index(artlist, ',');
                    370:                }
                    371:                if (p == 0) {
                    372:                        last = 1;
                    373:                        fn = dirname(artlist);
                    374:                        unlink(fn);
                    375:                        return;
                    376:                }
                    377:                if (p)
                    378:                        *p = 0;
                    379:        }
                    380:        fn = dirname(artlist);
                    381:        if (doarchive && access(OLDNEWS, 0) == 0) {
                    382:                p = fn + strlen(SPOOL) + 1;
                    383:                sprintf(newname, "%s/%s", OLDNEWS, p);
                    384:                if (verbose > 1)
                    385:                        printf("link %s to %s\n", fn, newname);
                    386:                if (link(fn, newname) == -1) {
                    387:                        if (mkparents(newname) == 0)
                    388:                                link(fn, newname);
                    389:                }
                    390:                timep[0] = timep[1] = cgtdate(h->subdate);
                    391:                utime(newname, timep);
                    392:        }
                    393: 
                    394:        if (verbose)
                    395:                printf("unlink %s\n", fn);
                    396:        unlink(fn);
                    397:        if (!last)
                    398:                ulall(p + 1, h);
                    399: }
                    400: 
                    401: 
                    402: xerror(message)
                    403: char   *message;
                    404: {
                    405:        printf("expire: %s.\n", message);
                    406:        fflush(stdout);
                    407:        exit(1);
                    408: }
                    409: 
                    410: /*
                    411:  * If any parent directories of this dir don't exist, create them.
                    412:  */
                    413: mkparents(dirname)
                    414: char *dirname;
                    415: {
                    416:        char buf[200], sysbuf[200];
                    417:        register char *p;
                    418:        int rc;
                    419:        struct passwd *pw;
                    420: 
                    421:        strcpy(buf, dirname);
                    422:        p = rindex(buf, '/');
                    423:        if (p)
                    424:                *p = '\0';
                    425:        if (exists(buf))
                    426:                return;
                    427:        mkparents(buf);
                    428:        sprintf(sysbuf, "mkdir %s", buf);
                    429:        rc = system(sysbuf);
                    430:        strcpy(sysbuf, buf);
                    431:        if (verbose)
                    432:                printf("mkdir %s, rc %d\n", sysbuf, rc);
                    433:        chmod(sysbuf, 0755);
                    434:        if ((pw = getpwnam(NEWSU)) != NULL)
                    435:                chown(sysbuf, pw->pw_uid, pw->pw_gid);
                    436: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.