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