|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.