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

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)anlwrk.c   5.7     (Berkeley) 4/5/88";
                      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 (15*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:                        syslog(LOG_WARNING, "fopen(%s) failed: %m",
                     65:                                subfile(file));
                     66:                        unlink(subfile(file));
                     67:                        return 0;
                     68:                }
                     69:                Usrf = 0;
                     70:                nstr[0] = '\0';
                     71:                nextread = nextwrite = 0L;
                     72:        }
                     73: 
                     74:        if (nstr[0] != '\0' && TransferSucceeded) {
                     75:                fseek(fp, nextwrite, 0);
                     76:                fputs(nstr, fp);
                     77:                fseek(fp, nextread, 0);
                     78:        }
                     79: 
                     80:        do {
                     81:                nextwrite = ftell(fp);
                     82:                if (fgets(str, MAXRQST, fp) == NULL) {
                     83:                        fclose(fp);
                     84:                        if (TransferSucceeded)
                     85:                                unlink(subfile(file));
                     86:                        USRF(USR_COMP);
                     87:                        US_RRS(file, Usrf);
                     88:                        Usrf = 0;
                     89:                        file[0] = '\0';
                     90:                        nstr[0] = '\0';
                     91:                        fp = NULL;
                     92:                        return 0;
                     93:                }
                     94:        } while (!isupper(str[0]));
                     95: 
                     96:        nextread = ftell(fp);
                     97:        strncpy(nstr, str, MAXRQST);
                     98:        nstr[0] = tolower(nstr[0]);
                     99:        return getargs(str, wvec, 20);
                    100: }
                    101: 
                    102: 
                    103: /*
                    104:  *     build list of work files for given system
                    105:  *
                    106:  *     return value - 1 if work was found, else 0
                    107:  *
                    108:  */
                    109: 
                    110: /* LOCAL only */
                    111: int
                    112: bldflst (reqst, dir, pre)
                    113: char *reqst;
                    114: register char *dir, *pre;
                    115: {
                    116:        static DIR  *dirp = NULL;
                    117:        register struct direct *dentp;
                    118:        register int i;
                    119:        int plen = strlen(pre);
                    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:        } else
                    128:                rewinddir(dirp);
                    129: 
                    130:        Nfiles = 0;
                    131:        while ((dentp = readdir(dirp)) != NULL && Nfiles < LLEN) {
                    132:                /* Check for two systems with the same prefix.
                    133:                 * Magic number "5" is 1 for "grade" character plus
                    134:                 * 4 for sequence number.  The point here is to not
                    135:                 * send work for a system which has as a prefix the
                    136:                 * name of the system called for.
                    137:                 * Special case: prefix "X." does not do this check
                    138:                 * so uuxqt can use bldflst.
                    139:                 */
                    140:                if (!prefix(pre, dentp->d_name) ||
                    141:                        (plen != 2 && (dentp->d_namlen-plen) != 5)) {
                    142:                        DEBUG(99,"bldflst rejects %s\n",dentp->d_name);
                    143:                        continue;
                    144:                }
                    145:                if (dentp->d_name[dentp->d_namlen-5] > MaxGrade) {
                    146:                        DEBUG(8, "bldflst rejects %s, grade too low\n",
                    147:                                dentp->d_name);
                    148:                        continue;
                    149:                }
                    150:                if (*reqst == 'c')
                    151:                        return 1;
                    152: 
                    153:                /* locate position for the new file and make room for it */
                    154:                for (i = Nfiles; i > 0; i--) {
                    155:                        if (pcompar(dentp->d_name, Filent[i-1]) <= 0)
                    156:                                break;
                    157:                        if (i <LLEN)
                    158:                                strcpy(Filent[i], Filent[i-1]);
                    159:                }
                    160: 
                    161:                /* add new file (if there is room), and increase Nfiles if need be */
                    162:                if (i < LLEN) {
                    163:                        DEBUG(99,"bldflst accepts %s",dentp->d_name);
                    164:                        DEBUG(99," as Filent[%d]\n", i);
                    165:                        strcpy(Filent[i], dentp->d_name);
                    166:                        if (Nfiles < LLEN)
                    167:                                Nfiles++;
                    168:                } else
                    169:                        DEBUG(99,"Filent full, %s rejected by bldflst\n", dentp->d_name);
                    170:                
                    171: 
                    172:        }
                    173:        if (Debug >99)
                    174:                for(i=0;i<Nfiles;i++)
                    175:                        fprintf(stderr,"Filent[%d]=%s\n",i,Filent[i]);
                    176: 
                    177:        return Nfiles > 0;
                    178: }
                    179: 
                    180: /*
                    181:   Compare priority of filenames p1 and p2.  Return:
                    182:  *     < 0     if p1 "has lower priority than" p2.
                    183:  *     = 0     if p1 "has priority equal to" p2.
                    184:  *     > 0     if p1 "has greater priority than" p2.
                    185:  * Priority:
                    186:  *     lower grade wins.
                    187:  *     lower sequence number wins (unless wrap-around is suspected).
                    188:  *
                    189:  */
                    190: /* LOCAL only */
                    191: pcompar(p1, p2)
                    192: register char *p1, *p2;
                    193: {
                    194:        register int rc;
                    195: 
                    196:        /* strlen(p1) and strlen(p2) are >= 5 */
                    197:        p1 += strlen(p1)-5;
                    198:        p2 += strlen(p2)-5;
                    199:        /* check 'grade' */
                    200:        if (rc = *p2++ - *p1++)
                    201:                return rc;
                    202:        /* check for  sequence wrap-around */
                    203:        if (rc = *p2++ - *p1++)
                    204:                if (rc < -10 || rc > 10)
                    205:                        return -rc;
                    206:                else
                    207:                        return rc;
                    208:        /* check remaining digits */
                    209:        return strcmp(p2, p1);
                    210: }
                    211: 
                    212: /*
                    213:  *     get work vector
                    214:  *
                    215:  *     return codes:
                    216:  *             positive number  -  number of arguments
                    217:  *             0 -  no arguments - fail
                    218:  */
                    219: 
                    220: /* EXTERNALLY CALLED */
                    221: int
                    222: gtwvec(file, dir, wkpre, wrkvec)
                    223: char *dir, *wkpre, **wrkvec;
                    224: register char *file;
                    225: {
                    226:        register int nargs, n;
                    227: 
                    228:        n = 0;
                    229:        while ((nargs = anlwrk(file, wrkvec)) == 0) {
                    230:                if (++n > 3 || !iswrk(file, "get", dir, wkpre))
                    231:                        return 0;
                    232:        }
                    233:        return nargs;
                    234: }
                    235: 
                    236: /*
                    237:  *     iswrk  -  this routine will check the work list (list).
                    238:  *     If it is empty or the present work is exhausted, it
                    239:  *     will call bldflst to generate a new list.
                    240:  *     The "reqst" field will be the string "chk" or "get" to
                    241:  *     check for work, or get the next work file respectively.
                    242:  *
                    243:  *     return codes:
                    244:  *             0  -  no more work (or some error)
                    245:  *             1  -  there is work
                    246:  *
                    247:  */
                    248: 
                    249: /* EXTERNALLY CALLED */
                    250: int
                    251: iswrk(file, reqst, dir, pre)
                    252: register char *file, *reqst, *dir, *pre;
                    253: {
                    254:        static char *lastpre = 0;
                    255:        register ret = 0;
                    256:        int i;
                    257: 
                    258:        /* Starting new system; re-init */
                    259:        if (lastpre == 0 || strcmp(lastpre, pre) != SAME) {
                    260:                /* Force close of work file */
                    261:                anlwrk("", (char **)0);
                    262: 
                    263:                /* Save last worked-on prefix */
                    264:                if (lastpre != 0)
                    265:                        free(lastpre);
                    266:                lastpre = malloc((unsigned)(strlen(pre)+1));
                    267:                strcpy(lastpre, pre);
                    268: 
                    269:                /* Set the external indexes properly */
                    270:                Nfiles = 0;
                    271:        }
                    272: 
                    273:        /*
                    274:         * If the list is empty or new files have entered
                    275:         * the spool area, call "bldflst" to read
                    276:         * some file names into it. 
                    277:         */
                    278:        if (Nfiles <= 0 || newspool((time_t)TLIMIT)) {
                    279:                ret = bldflst(reqst, dir, pre);
                    280:                DEBUG(99, "bldflst returns %d\n", ret);
                    281:        }
                    282: 
                    283:        /* If they only wanted to check, return
                    284:         * boolean list not empty.  NB: the list
                    285:         * will be forcibly emptied as soon as
                    286:         * a new system name is mentioned.
                    287:         */
                    288:        if (*reqst == 'c')
                    289:                return ret;
                    290: 
                    291:        if (Nfiles-- <= 0) {
                    292:                /* Didn't find any files in the spool area */
                    293:                Nfiles = 0;
                    294:                return 0;
                    295:        }
                    296:        /* Found some files, return the first one */
                    297:        sprintf(file, "%s/%s", dir, Filent[0]);
                    298:        for (i = 0; i < Nfiles; i++)
                    299:                strcpy(Filent[i], Filent[i+1]);
                    300:        return 1;
                    301: }
                    302: 
                    303: /* Return non-zero if there is new work in the spool
                    304:  * area since last check.  Assumes that if the sequence
                    305:  * file has been modified, there is new work. This is
                    306:  * not absolutely correct, but should be close enough.
                    307:  * Only checks every <limit> seconds at most.  Called
                    308:  * from "iswrk()" when a new work file is requested.
                    309:  */
                    310: /* LOCAL only */
                    311: int
                    312: newspool(limit)
                    313: time_t limit;
                    314: {
                    315:        static time_t lastcheck = 0, lastmod = 0;
                    316:        time_t check;
                    317:        struct stat mod;
                    318:        register int ret = 0;
                    319: 
                    320:        /* (void) */ time (&check);
                    321:        if (check - lastcheck > limit || lastcheck - check > limit) {
                    322:                mod.st_mtime = 0;
                    323:                /* (void) */ stat (SEQFILE, &mod);
                    324:                if (mod.st_mtime != lastmod)
                    325:                        ret = 1;
                    326:                lastmod = mod.st_mtime;
                    327:        }
                    328:        lastcheck = check;
                    329:        return ret;
                    330: }

unix.superglobalmegacorp.com

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