Annotation of researchv10no/cmd/netnews/src/expire.c, revision 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.