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

Defined functions

anlwrk defined in line 73; used 2 times
bldflst defined in line 130; used 1 times
entflst defined in line 176; used 1 times
gtwrkf defined in line 249; used 2 times
gtwvec defined in line 277; used 1 times
iswrk defined in line 309; used 4 times
newspool defined in line 368; used 1 times
pcompar defined in line 215; used 3 times

Defined variables

Filent defined in line 61; used 8 times
Nfiles defined in line 60; used 10 times
sccsid defined in line 2; never used

Defined macros

LLEN defined in line 53; used 2 times
MAXRQST defined in line 54; used 2 times
NITEMS defined in line 56; never used
TLIMIT defined in line 55; used 1 times
Last modified: 1983-07-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1004
Valid CSS Valid XHTML 1.0 Strict