Annotation of 43BSD/usr.bin/uucp/anlwrk.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)anlwrk.c   5.5 (Berkeley) 6/19/85";
                      3: #endif
                      4: 
                      5: #include "uucp.h"
                      6: #include <sys/stat.h>
                      7: #include "uust.h"
                      8: #ifdef NDIR
                      9: #include "ndir.h"
                     10: #else
                     11: #include <sys/dir.h>
                     12: #endif
                     13: #include <ctype.h>
                     14: 
                     15: #define TLIMIT (5*60L)
                     16: #define NITEMS(X)      (sizeof (X) / sizeof ((X)[0]))
                     17: 
                     18: int Nfiles = 0;
                     19: char Filent[LLEN][NAMESIZE];
                     20: long fseek(), ftell();
                     21: extern int TransferSucceeded;
                     22: 
                     23: /*LINTLIBRARY*/
                     24: 
                     25: /*
                     26:  *     create a vector of command arguments
                     27:  *
                     28:  *     return codes:
                     29:  *             0  -  no more work in this file
                     30:  *             positive number  -  number of arguments
                     31:  */
                     32: 
                     33: /* LOCAL only */
                     34: int
                     35: anlwrk(file, wvec)
                     36: register char *file, **wvec;
                     37: {
                     38:        static char str[MAXRQST], nstr[MAXRQST], lastfile[MAXFULLNAME] = "";
                     39:        static FILE *fp = NULL;
                     40:        static long nextread, nextwrite;
                     41: 
                     42:        /*
                     43:         * If called with a null string, force a shutdown
                     44:         * of the current work file.
                     45:         */
                     46:        if (file[0] == '\0') {
                     47:                if (fp != NULL)
                     48:                        fclose (fp);
                     49:                fp = NULL;
                     50:                return 0;
                     51:        }
                     52:        if (fp == NULL) {
                     53:                if (strncmp(file, lastfile, MAXFULLNAME) == 0) { 
                     54:                        DEBUG(5,"Workfilename repeated: %s\n", file);
                     55:                        return 0;
                     56:                }
                     57:                strncpy(lastfile, file, MAXFULLNAME);
                     58:                fp = fopen(subfile(file), "r+w");
                     59:                if (fp == NULL) {
                     60:                        char *bnp, rqstr[MAXFULLNAME];
                     61:                        bnp = rindex(file, '/');
                     62:                        sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : file);
                     63:                        xmv(file, rqstr);
                     64:                        logent(subfile(file), "CMD FILE UNREADABLE");
                     65:                        unlink(subfile(file));
                     66:                        return 0;
                     67:                }
                     68:                Usrf = 0;
                     69:                nstr[0] = '\0';
                     70:                nextread = nextwrite = 0L;
                     71:        }
                     72: 
                     73:        if (nstr[0] != '\0' && TransferSucceeded) {
                     74:                fseek(fp, nextwrite, 0);
                     75:                fputs(nstr, fp);
                     76:                fseek(fp, nextread, 0);
                     77:        }
                     78: 
                     79:        do {
                     80:                nextwrite = ftell(fp);
                     81:                if (fgets(str, MAXRQST, fp) == NULL) {
                     82:                        fclose(fp);
                     83:                        if (TransferSucceeded)
                     84:                                unlink(subfile(file));
                     85:                        USRF(USR_COMP);
                     86:                        US_RRS(file, Usrf);
                     87:                        Usrf = 0;
                     88:                        file[0] = '\0';
                     89:                        nstr[0] = '\0';
                     90:                        fp = NULL;
                     91:                        return 0;
                     92:                }
                     93:        } while (!isupper(str[0]));
                     94: 
                     95:        nextread = ftell(fp);
                     96:        strncpy(nstr, str, MAXRQST);
                     97:        nstr[0] = tolower(nstr[0]);
                     98:        return getargs(str, wvec, 20);
                     99: }
                    100: 
                    101: 
                    102: /*
                    103:  *     build list of work files for given system
                    104:  *
                    105:  *     return value - 1 if work was found, else 0
                    106:  *
                    107:  */
                    108: 
                    109: /* LOCAL only */
                    110: int
                    111: bldflst (reqst, dir, pre)
                    112: char *reqst;
                    113: register char *dir, *pre;
                    114: {
                    115:        static DIR  *dirp = NULL;
                    116:        register nfound;
                    117:        char filename[NAMESIZE];
                    118:        int plen = strlen (pre);
                    119:        int flen;
                    120:        extern char MaxGrade;
                    121: 
                    122:        if (dirp == NULL) {
                    123:                if ((dirp = opendir(subdir(dir,pre[0]))) == NULL) {
                    124:                        DEBUG(1,"opendir(%s) FAILS\n",subdir(dir,pre[0]));
                    125:                        return 0;
                    126:                }
                    127:        }
                    128:        else
                    129:                rewinddir(dirp);
                    130:        for (nfound = 0, Nfiles = 0; gnamef(dirp, filename);) {
                    131:                /* Check for two systems with the same prefix.
                    132:                 * Magic number "5" is 1 for "grade" character plus
                    133:                 * 4 for sequence number.  The point here is to not
                    134:                 * send work for a system which has as a prefix the
                    135:                 * name of the system called for.
                    136:                 * Special case: prefix "X." does not do this check
                    137:                 * so uuxqt can use bldflst.
                    138:                 */
                    139:                flen = strlen(filename);
                    140:                if (!prefix(pre, filename) || (plen != 2 && flen-plen != 5)) {
                    141:                        DEBUG(99,"bldflst rejects %s\n",filename);
                    142:                        continue;
                    143:                }
                    144:                if (filename[flen-5] > MaxGrade ) {
                    145:                        DEBUG(8,"bldflst rejects %s, grade too low\n",filename);
                    146:                        continue;
                    147:                }
                    148:                nfound++;
                    149:                if (*reqst == 'c')
                    150:                        return 1;
                    151:                entflst(filename);
                    152:        }
                    153:        return  nfound? 1: 0;
                    154: }
                    155: 
                    156: /*
                    157:  *     put new name if list is not full  or new name is less than the MAX
                    158:  *               now in the list.
                    159:  *
                    160:  */
                    161: 
                    162: /* LOCAL only */
                    163: int
                    164: entflst(file)
                    165: register char *file;
                    166: {
                    167:        register int i;
                    168: 
                    169:        /* locate position for the new file and make room for it */
                    170:        for (i = Nfiles; i > 0; i--) {
                    171:                if (pcompar(file, Filent[i-1]) <= 0)
                    172:                        break;
                    173:                if (i <LLEN)
                    174:                        strcpy(Filent[i], Filent[i-1]);
                    175:        }
                    176: 
                    177:        /* add new file (if there is room), and increase Nfiles if need be */
                    178:        if (i < LLEN) {
                    179:                strcpy(Filent[i], file);
                    180:                if (Nfiles < LLEN)
                    181:                        Nfiles++;
                    182:        }
                    183: }
                    184: 
                    185: /*
                    186:   Compare priority of filenames p1 and p2.  Return:
                    187:  *     < 0     if p1 "has lower priority than" p2.
                    188:  *     = 0     if p1 "has priority equal to" p2.
                    189:  *     > 0     if p1 "has greater priority than" p2.
                    190:  * Priority:
                    191:  *     lower grade wins.
                    192:  *     lower sequence number wins (unless wrap-around is suspected).
                    193:  *
                    194:  */
                    195: /* LOCAL only */
                    196: int
                    197: pcompar(p1, p2)
                    198: register char *p1, *p2;
                    199: {
                    200:        register int rc;
                    201: 
                    202:        /* assert: strlen(p1) and strlen(p2) are >= 5 */
                    203:        p1 += strlen(p1)-5;
                    204:        p2 += strlen(p2)-5;
                    205:        /* check 'grade' */
                    206:        if (rc = *p2++ - *p1++)
                    207:                return rc;
                    208:        /* check for  sequence wrap-around */
                    209:        if (rc = *p2++ - *p1++)
                    210:                if (rc < -10 || rc > 10)
                    211:                        return -rc;
                    212:                else
                    213:                        return rc;
                    214:        /* check remaining digits */
                    215:        return strcmp(p2, p1);
                    216: }
                    217: 
                    218: /*
                    219:  *     get next work file
                    220:  *
                    221:  *     return value:
                    222:  *
                    223:  *             0  - No file gotten
                    224:  *             1  - File successfully gotten.
                    225:  *
                    226:  */
                    227: 
                    228: /* LOCAL only */
                    229: gtwrkf(dir, file)
                    230: char *file, *dir;
                    231: {
                    232:        register int i;
                    233: 
                    234:        if (Nfiles-- <= 0) {
                    235:                Nfiles = 0;
                    236:                return 0;
                    237:        }
                    238:        sprintf(file, "%s/%s", dir, Filent[0]);
                    239:        for (i=0; i<Nfiles;i++)
                    240:                strcpy(Filent[i], Filent[i+1]);
                    241:        return 1;
                    242: }
                    243: 
                    244: /*
                    245:  *     get work vector
                    246:  *
                    247:  *     return codes:
                    248:  *             positive number  -  number of arguments
                    249:  *             0 -  no arguments - fail
                    250:  */
                    251: 
                    252: /* EXTERNALLY CALLED */
                    253: int
                    254: gtwvec(file, dir, wkpre, wrkvec)
                    255: char *dir, *wkpre, **wrkvec;
                    256: register char *file;
                    257: {
                    258:        register int nargs, n;
                    259: 
                    260:        n = 0;
                    261:        while ((nargs = anlwrk(file, wrkvec)) == 0) {
                    262:                if (++n > 3 || !iswrk(file, "get", dir, wkpre))
                    263:                        return 0;
                    264:        }
                    265:        return nargs;
                    266: }
                    267: 
                    268: /*
                    269:  *     iswrk  -  this routine will check the work list (list).
                    270:  *     If it is empty or the present work is exhausted, it
                    271:  *     will call bldflst to generate a new list.
                    272:  *     The "reqst" field will be the string "chk" or "get" to
                    273:  *     check for work, or get the next work file respectively.
                    274:  *
                    275:  *     return codes:
                    276:  *             0  -  no more work (or some error)
                    277:  *             1  -  there is work
                    278:  *
                    279:  */
                    280: 
                    281: /* EXTERNALLY CALLED */
                    282: int
                    283: iswrk(file, reqst, dir, pre)
                    284: register char *file, *reqst, *dir, *pre;
                    285: {
                    286:        static char *lastpre = 0;
                    287:        register ret;
                    288: 
                    289:        /* Starting new system; re-init */
                    290:        if (lastpre == 0 || strcmp(lastpre,pre) != 0) {
                    291:                anlwrk ("", (char **)0);        /* Force close of work file */
                    292: 
                    293:                /* Save last worked-on prefix */
                    294:                if (lastpre != 0)
                    295:                        free (lastpre);
                    296:                lastpre = malloc((unsigned)(strlen(pre)+1));
                    297:                strcpy (lastpre, pre);
                    298: 
                    299:                /* Set the external indexes properly
                    300:                 */
                    301:                Nfiles = 0;
                    302:        }
                    303: 
                    304:        /* If the list is empty or new files have entered
                    305:         * the spool area, call "bldflst" to read
                    306:         * some file names into it.  Because names can
                    307:         * be put in the list that later turn out to
                    308:         * be unusable (from "gtwrkf"), this operation
                    309:         * continues until either "bldflst" can't find
                    310:         * any new files, or "gtwrkf" signals success.
                    311:         */
                    312:        for (;;) {
                    313:                ret = 0;
                    314:                if (Nfiles <= 0 || newspool((time_t)TLIMIT)) {
                    315:                        ret = bldflst (reqst, dir, pre);
                    316:                        DEBUG(99,"bldflst returns %d\n",ret);
                    317:                }
                    318: 
                    319:                /* If they only wanted to check, return
                    320:                 * boolean list not empty.  NB: the list
                    321:                 * will be forcibly emptied as soon as
                    322:                 * a new system name is mentioned.
                    323:                 */
                    324:                if (*reqst == 'c')
                    325:                        return ret;
                    326: 
                    327:                if (Nfiles <= 0)
                    328:                        return 0;
                    329: 
                    330:                if (gtwrkf(dir, file))
                    331:                        return 1;
                    332:        }
                    333: }
                    334: 
                    335: /* Return non-zero if there is new work in the spool
                    336:  * area since last check.  Assumes that if the sequence
                    337:  * file has been modified, there is new work. This is
                    338:  * not absolutely correct, but should be close enough.
                    339:  * Only checks every <limit> seconds at most.  Called
                    340:  * from "iswrk()" when a new work file is requested.
                    341:  */
                    342: /* LOCAL only */
                    343: int
                    344: newspool(limit)
                    345: time_t limit;
                    346: {
                    347:        static time_t lastcheck = 0, lastmod = 0;
                    348:        time_t check;
                    349:        struct stat mod;
                    350:        register int ret = 0;
                    351: 
                    352:        /* (void) */ time (&check);
                    353:        if (check - lastcheck > limit || lastcheck - check > limit) {
                    354:                mod.st_mtime = 0;
                    355:                /* (void) */ stat (SEQFILE, &mod);
                    356:                if (mod.st_mtime != lastmod)
                    357:                        ret = 1;
                    358:                lastmod = mod.st_mtime;
                    359:        }
                    360:        lastcheck = check;
                    361:        return ret;
                    362: }

unix.superglobalmegacorp.com

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