Annotation of 42BSD/usr.bin/uucp/anlwrk.c, revision 1.1.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.