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: }

Defined functions

anlwrk defined in line 34; used 2 times
bldflst defined in line 110; used 1 times
entflst defined in line 163; used 1 times
gtwrkf defined in line 229; used 3 times
gtwvec defined in line 253; used 1 times
newspool defined in line 343; used 1 times
pcompar defined in line 196; used 1 times

Defined variables

Filent defined in line 19; used 7 times
Nfiles defined in line 18; used 13 times
sccsid defined in line 2; never used

Defined macros

NITEMS defined in line 16; never used
TLIMIT defined in line 15; used 1 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1847
Valid CSS Valid XHTML 1.0 Strict