Annotation of 42BSD/usr.bin/uucp/anlwrk.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)anlwrk.c   5.2 (Berkeley) 7/2/83";
        !             3: #endif
        !             4: 
        !             5: #include "uucp.h"
        !             6: #include <sys/types.h>
        !             7: #include <sys/stat.h>
        !             8: #ifdef NDIR
        !             9: #include "ndir.h"
        !            10: #else
        !            11: #include <sys/dir.h>
        !            12: #endif
        !            13: 
        !            14: /* Re-written to be reasonable
        !            15:  * Mon Nov 15 17:19:52 EST 1982
        !            16:  * Alan S. Watt (ittvax!swatt)
        !            17:  *
        !            18:  * Tom Truscott (rti!trt):
        !            19:  * Priority ordering cleaned up.  New 'pcompar' subroutine.
        !            20:  * 'stat' removed (speeds things up).
        !            21:  * Possible infinite loop in gtwvec defended against.
        !            22:  * Feb 23, 1983
        !            23:  *
        !            24:  * Changes:
        !            25:  *
        !            26:  *  1) The check for work is much faster; the first filename
        !            27:  *     that matches the prefix causes a "yes" return.
        !            28:  *
        !            29:  *  2) The filename is not "stat" ed , so
        !            30:  *     there is no massive delay while the list of potential
        !            31:  *     names is built.
        !            32:  *
        !            33:  *  3) Requesting work for a new system is now detected so
        !            34:  *     internal variables are re-initialized properly.  In
        !            35:  *     particular, the stream pointer for the current work
        !            36:  *     file is properly closed so work for a system which
        !            37:  *     hangs up will not be sent to the next system called.
        !            38:  *
        !            39:  * Fri Dec  3 09:31:45 EST 1982
        !            40:  *
        !            41:  *  5) As new work files are requested, a check is made
        !            42:  *     every TLIMIT seconds (5 minutes at present) to see
        !            43:  *     if new files have entered the spool area.  Since
        !            44:  *     work file names are now cached up to LLEN, this can
        !            45:  *     represent a very long transmission time before new
        !            46:  *     work enters the list to be processed.  If people want
        !            47:  *     to use the "grade" character to specify a higher
        !            48:  *     priority, the list must be re-built and re-sorted for
        !            49:  *     higher priority stuff to have an immediate effect.
        !            50:  */
        !            51: 
        !            52: 
        !            53: #define LLEN 20
        !            54: #define MAXRQST 250
        !            55: #define TLIMIT (5*60L)
        !            56: #define NITEMS(X)      (sizeof (X) / sizeof ((X)[0]))
        !            57: 
        !            58: /* These are all used only locally
        !            59:  */
        !            60: static int Nfiles = 0;
        !            61: static char Filent[LLEN][NAMESIZE];
        !            62: 
        !            63: /*******
        !            64:  *     anlwrk(file, wvec)      create a vector of command arguments
        !            65:  *     char *file, **wvec;
        !            66:  *
        !            67:  *     return codes:
        !            68:  *             0  -  no more work in this file
        !            69:  *             positive number  -  number of arguments
        !            70:  */
        !            71: 
        !            72: /* LOCAL only */
        !            73: int
        !            74: anlwrk(file, wvec)
        !            75: register char *file, **wvec;
        !            76: {
        !            77:        static char str[MAXRQST];
        !            78:        static FILE *fp = NULL;
        !            79: 
        !            80:        /* If called with a null string, force a shutdown
        !            81:         * of the current work file.
        !            82:         * John Levine, ima.247, related change in cntl.c
        !            83:         */
        !            84:        if (file[0] == '\0') {
        !            85:                if (fp != NULL)
        !            86:                        fclose (fp);
        !            87:                fp = NULL;
        !            88:                return(0);
        !            89:        }
        !            90:        if (fp == NULL) {
        !            91:                fp = fopen(subfile(file), "r");
        !            92:                if (fp == NULL) {
        !            93:                        unlink(subfile(file));  /* Try to zap the thing. rti!trt */
        !            94:                        return(0);
        !            95:                }
        !            96:        }
        !            97: 
        !            98:        /* This is what deletes the current work file when EOF
        !            99:         * is reached.  As this is called from gtwvec, which is
        !           100:         * in turn called externally, it is not possible to save
        !           101:         * "C." files in case of error, except for line errors,
        !           102:         * which shuts down the whole system.
        !           103:         */
        !           104:        if (fgets(str, MAXRQST, fp) == NULL) {
        !           105:                fclose(fp);
        !           106:                unlink(subfile(file));
        !           107:                file[0] = '\0';
        !           108:                fp = NULL;
        !           109:                return(0);
        !           110:        }
        !           111:        return(getargs(str, wvec));
        !           112: }
        !           113: 
        !           114: 
        !           115: /***
        !           116:  *     bldflst - build list of work files for given system
        !           117:  *      Nfiles, Filent are global
        !           118:  *
        !           119:  *     return value - 1 if work was found, else 0
        !           120:  *
        !           121:  * Jul 26 19:17 1982 (ittvax!swatt). fixed this obnoxious
        !           122:  * routine to NOT read all the way through the damned directory
        !           123:  * "stat"'ing every file in sight just to get 10 names!!!
        !           124:  *
        !           125:  * It still reads through the directory from the beginning until
        !           126:  * the list is filled, but this is only once every LLEN names.
        !           127:  */
        !           128: 
        !           129: /* LOCAL only */
        !           130: int
        !           131: bldflst (reqst, dir, pre)
        !           132: char *reqst;
        !           133: register char *dir, *pre;
        !           134: {
        !           135:        static DIR  *dirp = NULL;
        !           136:        register nfound;
        !           137:        char filename[NAMESIZE];        /* @@@ NB: this needs new dir stuff */
        !           138:        int plen = strlen (pre);
        !           139: 
        !           140:        if (dirp == NULL) {
        !           141:                if ((dirp = opendir(subdir(dir,pre[0]), "r")) == NULL)
        !           142:                        return(0);
        !           143:        }
        !           144:        else
        !           145:                rewinddir(dirp);
        !           146:        for (nfound = 0, Nfiles = 0; gnamef(dirp, filename);) {
        !           147:                /* Check for two systems with the same prefix.
        !           148:                 * Magic number "5" is 1 for "grade" character plus
        !           149:                 * 4 for sequence number.  The point here is to not
        !           150:                 * send work for a system which has as a prefix the
        !           151:                 * name of the system called for.
        !           152:                 * Special case: prefix "X." does not do this check
        !           153:                 * so uuxqt can use bldflst.
        !           154:                 */
        !           155:                if (!prefix(pre, filename)
        !           156:                 || (plen != 2 && strlen(filename)-plen != 5))
        !           157:                        continue;
        !           158:                nfound++;
        !           159:                if (*reqst == 'c')
        !           160:                        return (1);
        !           161:                entflst(filename);
        !           162:        }
        !           163:        return (nfound? 1: 0);
        !           164: }
        !           165: 
        !           166: /***
        !           167:  *     entflst - put new name if list is not full
        !           168:  *               or new name is less than the MAX
        !           169:  *               now in the list.
        !           170:  *     Nfiles, Filent[] are modified.
        !           171:  *     return value - none
        !           172:  *
        !           173:  */
        !           174: 
        !           175: /* LOCAL only */
        !           176: int
        !           177: entflst(file)
        !           178: char *file;
        !           179: {
        !           180:        register int i;
        !           181:        register char *p;
        !           182: 
        !           183:        /* If there is room in the table, just add it. */
        !           184:        if (Nfiles < LLEN) {
        !           185:                strcpy(Filent[Nfiles++], file);
        !           186:                return;
        !           187:        }
        !           188: 
        !           189:        /* Find lowest priority file in table  */
        !           190:        p = Filent[0];
        !           191:        for (i = 1; i < Nfiles; i++)
        !           192:                if (pcompar(Filent[i], p) < 0)
        !           193:                        p = Filent[i];
        !           194: 
        !           195:        /*
        !           196:         * If new candidate is of higher priority
        !           197:         * that the lowest priority file in the table,
        !           198:         * replace the table entry.
        !           199:         */
        !           200:        if (pcompar(p, file) < 0)
        !           201:                strcpy(p, file);
        !           202: }
        !           203: 
        !           204: /*
        !           205:   Compare priority of filenames p1 and p2.  Return:
        !           206:  *     < 0     if p1 "has lower priority than" p2.
        !           207:  *     = 0     if p1 "has priority equal to" p2.
        !           208:  *     > 0     if p1 "has greater priority than" p2.
        !           209:  * Priority:
        !           210:  *     lower grade wins.
        !           211:  *     lower sequence number wins (unless wrap-around is suspected).
        !           212:  *
        !           213:  */
        !           214: /* LOCAL only */
        !           215: int
        !           216: pcompar(p1, p2)
        !           217: register char *p1, *p2;
        !           218: {
        !           219:        register int rc;
        !           220: 
        !           221:        /* assert: strlen(p1) and strlen(p2) are >= 5 */
        !           222:        p1 += strlen(p1)-5;
        !           223:        p2 += strlen(p2)-5;
        !           224:        /* check 'grade' */
        !           225:        if (rc = *p2++ - *p1++)
        !           226:                return(rc);
        !           227:        /* check for  sequence wrap-around */
        !           228:        if (rc = *p2++ - *p1++)
        !           229:                if (rc < -10 || rc > 10)
        !           230:                        return(-rc);
        !           231:                else
        !           232:                        return(rc);
        !           233:        /* check remaining digits */
        !           234:        return(strcmp(p2, p1));
        !           235: }
        !           236: 
        !           237: /***
        !           238:  *     gtwrkf - get next work file
        !           239:  *      Nfiles, Filent[] are modified.
        !           240:  *
        !           241:  *     return value:
        !           242:  *
        !           243:  *             0  - No file gotten
        !           244:  *             1  - File successfully gotten.
        !           245:  *
        !           246:  */
        !           247: 
        !           248: /* LOCAL only */
        !           249: gtwrkf(dir, file)
        !           250: char *file, *dir;
        !           251: {
        !           252:        register char *p;
        !           253:        register int i;
        !           254: 
        !           255:        if (Nfiles == 0)
        !           256:                return(0);
        !           257:        /* Find highest priority file in table */
        !           258:        p = Filent[0];
        !           259:        for (i = 1; i < Nfiles; i++) 
        !           260:                if (pcompar(Filent[i], p) > 0)
        !           261:                        p = Filent[i];
        !           262:        sprintf(file, "%s/%s", dir, p);
        !           263:        strcpy(p, Filent[--Nfiles]);
        !           264:        return(1);
        !           265: }
        !           266: 
        !           267: /***
        !           268:  *     gtwvec(file, dir, wkpre, wrkvec)        get work vector 
        !           269:  *     char *file, *dir, *wkpre, **wrkvec;
        !           270:  *
        !           271:  *     return codes:
        !           272:  *             positive number  -  number of arguments
        !           273:  *             0 -  no arguments - fail
        !           274:  */
        !           275: 
        !           276: /* EXTERNALLY CALLED */
        !           277: int
        !           278: gtwvec(file, dir, wkpre, wrkvec)
        !           279: char *dir, *wkpre, **wrkvec;
        !           280: register char *file;
        !           281: {
        !           282:        register int nargs, n;
        !           283: 
        !           284:        n = 0;          /* Break possible infinite loop.  rti!trt */
        !           285:        while ((nargs = anlwrk(file, wrkvec)) == 0) {
        !           286:                if (++n > 3 || !iswrk(file, "get", dir, wkpre))
        !           287:                        return(0);
        !           288:        }
        !           289:        return(nargs);
        !           290: }
        !           291: 
        !           292: /***
        !           293:  *     iswrk(file, reqst, dir, pre)
        !           294:  *     char *file, *reqst, *dir, *pre;
        !           295:  *
        !           296:  *     iswrk  -  this routine will check the work list (list).
        !           297:  *     If it is empty or the present work is exhausted, it
        !           298:  *     will call bldflst to generate a new list.
        !           299:  *     The "reqst" field will be the string "chk" or "get" to
        !           300:  *     check for work, or get the next work file respectively.
        !           301:  *
        !           302:  *     return codes:
        !           303:  *             0  -  no more work (or some error)
        !           304:  *             1  -  there is work
        !           305:  *
        !           306:  */
        !           307: 
        !           308: /* EXTERNALLY CALLED */
        !           309: int
        !           310: iswrk(file, reqst, dir, pre)
        !           311: register char *file, *reqst, *dir, *pre;
        !           312: {
        !           313:        static char *lastpre = 0;
        !           314:        register ret;
        !           315: 
        !           316:        /* Starting new system; re-init */
        !           317:        if (lastpre == 0 || strcmp(lastpre,pre) != 0) {
        !           318:                anlwrk ("", (char **)0);        /* Force close of work file */
        !           319: 
        !           320:                /* Save last worked-on prefix */
        !           321:                if (lastpre != 0)
        !           322:                        free (lastpre);
        !           323:                lastpre = malloc((unsigned)(strlen(pre)+1));
        !           324:                strcpy (lastpre, pre);
        !           325: 
        !           326:                /* Set the external indexes properly
        !           327:                 */
        !           328:                Nfiles = 0;
        !           329:        }
        !           330: 
        !           331:        /* If the list is empty or new files have entered
        !           332:         * the spool area, call "bldflst" to read
        !           333:         * some file names into it.  Because names can
        !           334:         * be put in the list that later turn out to
        !           335:         * be unusable (from "gtwrkf"), this operation
        !           336:         * continues until either "bldflst" can't find
        !           337:         * any new files, or "gtwrkf" signals success.
        !           338:         */
        !           339:        for (;;) {
        !           340:                ret = 0;
        !           341:                if (Nfiles == 0 || newspool((time_t)TLIMIT))
        !           342:                        ret = bldflst (reqst, dir, pre);
        !           343: 
        !           344:                /* If they only wanted to check, return
        !           345:                 * boolean list not empty.  NB: the list
        !           346:                 * will be forcibly emptied as soon as
        !           347:                 * a new system name is mentioned.
        !           348:                 */
        !           349:                if (*reqst == 'c')
        !           350:                        return (ret);
        !           351: 
        !           352:                if (Nfiles == 0)
        !           353:                        return(0);
        !           354: 
        !           355:                if (gtwrkf(dir, file))
        !           356:                        return (1);
        !           357:        }
        !           358: }
        !           359: 
        !           360: /* Return non-zero if there is new work in the spool
        !           361:  * area since last check.  Assumes that if the sequence
        !           362:  * file has been modified, there is new work. This is
        !           363:  * not absolutely correct, but should be close enough.
        !           364:  * Only checks every <limit> seconds at most.  Called
        !           365:  * from "iswrk()" when a new work file is requested.
        !           366:  */
        !           367: /* LOCAL only */
        !           368: int
        !           369: newspool(limit)
        !           370: time_t limit;
        !           371: {
        !           372:        static time_t lastcheck = 0, lastmod = 0;
        !           373:        time_t check;
        !           374:        struct stat mod;
        !           375:        register int ret = 0;
        !           376: 
        !           377:        /* (void) */ time (&check);
        !           378:        if (check - lastcheck > limit || lastcheck - check > limit) {
        !           379:                mod.st_mtime = 0;
        !           380:                /* (void) */ stat (SEQFILE, &mod);
        !           381:                if (mod.st_mtime != lastmod)
        !           382:                        ret = 1;
        !           383:                lastmod = mod.st_mtime;
        !           384:        }
        !           385:        lastcheck = check;
        !           386:        return (ret);
        !           387: }

unix.superglobalmegacorp.com

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