1: #if !defined(lint) && defined(DOSCCS)
   2: static char sccsid[] = "@(#)anlwrk.c	5.5.1 (2.11BSD) 1997/10/2";
   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: extern int TransferSucceeded;
  21: 
  22: /*LINTLIBRARY*/
  23: 
  24: /*
  25:  *	create a vector of command arguments
  26:  *
  27:  *	return codes:
  28:  *		0  -  no more work in this file
  29:  *		positive number  -  number of arguments
  30:  */
  31: 
  32: /* LOCAL only */
  33: int
  34: anlwrk(file, wvec)
  35: register char *file, **wvec;
  36: {
  37:     static char str[MAXRQST], nstr[MAXRQST], lastfile[MAXFULLNAME] = "";
  38:     static FILE *fp = NULL;
  39:     static long nextread, nextwrite;
  40: 
  41:     /*
  42: 	 * If called with a null string, force a shutdown
  43: 	 * of the current work file.
  44: 	 */
  45:     if (file[0] == '\0') {
  46:         if (fp != NULL)
  47:             fclose (fp);
  48:         fp = NULL;
  49:         return 0;
  50:     }
  51:     if (fp == NULL) {
  52:         if (strncmp(file, lastfile, MAXFULLNAME) == 0) {
  53:             DEBUG(5,"Workfilename repeated: %s\n", file);
  54:             return 0;
  55:         }
  56:         strncpy(lastfile, file, MAXFULLNAME);
  57:         fp = fopen(subfile(file), "r+w");
  58:         if (fp == NULL) {
  59:             char *bnp, rqstr[MAXFULLNAME];
  60:             bnp = rindex(file, '/');
  61:             sprintf(rqstr, "%s/%s", CORRUPT, bnp ? bnp + 1 : file);
  62:             xmv(file, rqstr);
  63:             logent(subfile(file), "CMD FILE UNREADABLE");
  64:             unlink(subfile(file));
  65:             return 0;
  66:         }
  67:         Usrf = 0;
  68:         nstr[0] = '\0';
  69:         nextread = nextwrite = 0L;
  70:     }
  71: 
  72:     if (nstr[0] != '\0' && TransferSucceeded) {
  73:         fseek(fp, nextwrite, 0);
  74:         fputs(nstr, fp);
  75:         fseek(fp, nextread, 0);
  76:     }
  77: 
  78:     do {
  79:         nextwrite = ftell(fp);
  80:         if (fgets(str, MAXRQST, fp) == NULL) {
  81:             fclose(fp);
  82:             if (TransferSucceeded)
  83:                 unlink(subfile(file));
  84:             USRF(USR_COMP);
  85:             US_RRS(file, Usrf);
  86:             Usrf = 0;
  87:             file[0] = '\0';
  88:             nstr[0] = '\0';
  89:             fp = NULL;
  90:             return 0;
  91:         }
  92:     } while (!isupper(str[0]));
  93: 
  94:     nextread = ftell(fp);
  95:     strncpy(nstr, str, MAXRQST);
  96:     nstr[0] = tolower(nstr[0]);
  97:     return getargs(str, wvec, 20);
  98: }
  99: 
 100: 
 101: /*
 102:  *	build list of work files for given system
 103:  *
 104:  *	return value - 1 if work was found, else 0
 105:  *
 106:  */
 107: 
 108: /* LOCAL only */
 109: int
 110: bldflst (reqst, dir, pre)
 111: char *reqst;
 112: register char *dir, *pre;
 113: {
 114:     static DIR  *dirp = NULL;
 115:     register nfound;
 116:     char filename[NAMESIZE];
 117:     int plen = strlen (pre);
 118:     int flen;
 119:     extern char MaxGrade;
 120: 
 121:     if (dirp == NULL) {
 122:         if ((dirp = opendir(subdir(dir,pre[0]))) == NULL) {
 123:             DEBUG(1,"opendir(%s) FAILS\n",subdir(dir,pre[0]));
 124:             return 0;
 125:         }
 126:     }
 127:     else
 128:         rewinddir(dirp);
 129:     for (nfound = 0, Nfiles = 0; gnamef(dirp, filename);) {
 130:         /* Check for two systems with the same prefix.
 131: 		 * Magic number "5" is 1 for "grade" character plus
 132: 		 * 4 for sequence number.  The point here is to not
 133: 		 * send work for a system which has as a prefix the
 134: 		 * name of the system called for.
 135: 		 * Special case: prefix "X." does not do this check
 136: 		 * so uuxqt can use bldflst.
 137: 		 */
 138:         flen = strlen(filename);
 139:         if (!prefix(pre, filename) || (plen != 2 && flen-plen != 5)) {
 140:             DEBUG(99,"bldflst rejects %s\n",filename);
 141:             continue;
 142:         }
 143:         if (filename[flen-5] > MaxGrade ) {
 144:             DEBUG(8,"bldflst rejects %s, grade too low\n",filename);
 145:             continue;
 146:         }
 147:         nfound++;
 148:         if (*reqst == 'c')
 149:             return 1;
 150:         entflst(filename);
 151:     }
 152:     return  nfound? 1: 0;
 153: }
 154: 
 155: /*
 156:  *	put new name if list is not full  or new name is less than the MAX
 157:  *		  now in the list.
 158:  *
 159:  */
 160: 
 161: /* LOCAL only */
 162: int
 163: entflst(file)
 164: register char *file;
 165: {
 166:     register int i;
 167: 
 168:     /* locate position for the new file and make room for it */
 169:     for (i = Nfiles; i > 0; i--) {
 170:         if (pcompar(file, Filent[i-1]) <= 0)
 171:             break;
 172:         if (i <LLEN)
 173:             strcpy(Filent[i], Filent[i-1]);
 174:     }
 175: 
 176:     /* add new file (if there is room), and increase Nfiles if need be */
 177:     if (i < LLEN) {
 178:         strcpy(Filent[i], file);
 179:         if (Nfiles < LLEN)
 180:             Nfiles++;
 181:     }
 182: }
 183: 
 184: /*
 185:   Compare priority of filenames p1 and p2.  Return:
 186:  *	< 0	if p1 "has lower priority than" p2.
 187:  *	= 0	if p1 "has priority equal to" p2.
 188:  *	> 0	if p1 "has greater priority than" p2.
 189:  * Priority:
 190:  *	lower grade wins.
 191:  *	lower sequence number wins (unless wrap-around is suspected).
 192:  *
 193:  */
 194: /* LOCAL only */
 195: int
 196: pcompar(p1, p2)
 197: register char *p1, *p2;
 198: {
 199:     register int rc;
 200: 
 201:     /* assert: strlen(p1) and strlen(p2) are >= 5 */
 202:     p1 += strlen(p1)-5;
 203:     p2 += strlen(p2)-5;
 204:     /* check 'grade' */
 205:     if (rc = *p2++ - *p1++)
 206:         return rc;
 207:     /* check for  sequence wrap-around */
 208:     if (rc = *p2++ - *p1++)
 209:         if (rc < -10 || rc > 10)
 210:             return -rc;
 211:         else
 212:             return rc;
 213:     /* check remaining digits */
 214:     return strcmp(p2, p1);
 215: }
 216: 
 217: /*
 218:  *	get next work file
 219:  *
 220:  *	return value:
 221:  *
 222:  *		0  - No file gotten
 223:  *		1  - File successfully gotten.
 224:  *
 225:  */
 226: 
 227: /* LOCAL only */
 228: gtwrkf(dir, file)
 229: char *file, *dir;
 230: {
 231:     register int i;
 232: 
 233:     if (Nfiles-- <= 0) {
 234:         Nfiles = 0;
 235:         return 0;
 236:     }
 237:     sprintf(file, "%s/%s", dir, Filent[0]);
 238:     for (i=0; i<Nfiles;i++)
 239:         strcpy(Filent[i], Filent[i+1]);
 240:     return 1;
 241: }
 242: 
 243: /*
 244:  *	get work vector
 245:  *
 246:  *	return codes:
 247:  *		positive number  -  number of arguments
 248:  *		0 -  no arguments - fail
 249:  */
 250: 
 251: /* EXTERNALLY CALLED */
 252: int
 253: gtwvec(file, dir, wkpre, wrkvec)
 254: char *dir, *wkpre, **wrkvec;
 255: register char *file;
 256: {
 257:     register int nargs, n;
 258: 
 259:     n = 0;
 260:     while ((nargs = anlwrk(file, wrkvec)) == 0) {
 261:         if (++n > 3 || !iswrk(file, "get", dir, wkpre))
 262:             return 0;
 263:     }
 264:     return nargs;
 265: }
 266: 
 267: /*
 268:  *	iswrk  -  this routine will check the work list (list).
 269:  *	If it is empty or the present work is exhausted, it
 270:  *	will call bldflst to generate a new list.
 271:  *	The "reqst" field will be the string "chk" or "get" to
 272:  *	check for work, or get the next work file respectively.
 273:  *
 274:  *	return codes:
 275:  *		0  -  no more work (or some error)
 276:  *		1  -  there is work
 277:  *
 278:  */
 279: 
 280: /* EXTERNALLY CALLED */
 281: int
 282: iswrk(file, reqst, dir, pre)
 283: register char *file, *reqst, *dir, *pre;
 284: {
 285:     static char *lastpre = 0;
 286:     register ret;
 287: 
 288:     /* Starting new system; re-init */
 289:     if (lastpre == 0 || strcmp(lastpre,pre) != 0) {
 290:         anlwrk ("", (char **)0);    /* Force close of work file */
 291: 
 292:         /* Save last worked-on prefix */
 293:         if (lastpre != 0)
 294:             free (lastpre);
 295:         lastpre = (char *)malloc((unsigned)(strlen(pre)+1));
 296:         strcpy (lastpre, pre);
 297: 
 298:         /* Set the external indexes properly
 299: 		 */
 300:         Nfiles = 0;
 301:     }
 302: 
 303:     /* If the list is empty or new files have entered
 304: 	 * the spool area, call "bldflst" to read
 305: 	 * some file names into it.  Because names can
 306: 	 * be put in the list that later turn out to
 307: 	 * be unusable (from "gtwrkf"), this operation
 308: 	 * continues until either "bldflst" can't find
 309: 	 * any new files, or "gtwrkf" signals success.
 310: 	 */
 311:     for (;;) {
 312:         ret = 0;
 313:         if (Nfiles <= 0 || newspool((time_t)TLIMIT)) {
 314:             ret = bldflst (reqst, dir, pre);
 315:             DEBUG(99,"bldflst returns %d\n",ret);
 316:         }
 317: 
 318:         /* If they only wanted to check, return
 319: 		 * boolean list not empty.  NB: the list
 320: 		 * will be forcibly emptied as soon as
 321: 		 * a new system name is mentioned.
 322: 		 */
 323:         if (*reqst == 'c')
 324:             return ret;
 325: 
 326:         if (Nfiles <= 0)
 327:             return 0;
 328: 
 329:         if (gtwrkf(dir, file))
 330:             return 1;
 331:     }
 332: }
 333: 
 334: /* Return non-zero if there is new work in the spool
 335:  * area since last check.  Assumes that if the sequence
 336:  * file has been modified, there is new work. This is
 337:  * not absolutely correct, but should be close enough.
 338:  * Only checks every <limit> seconds at most.  Called
 339:  * from "iswrk()" when a new work file is requested.
 340:  */
 341: /* LOCAL only */
 342: int
 343: newspool(limit)
 344: time_t  limit;
 345: {
 346:     static time_t lastcheck = 0, lastmod = 0;
 347:     time_t check;
 348:     struct stat mod;
 349:     register int ret = 0;
 350: 
 351:     /* (void) */ time (&check);
 352:     if (check - lastcheck > limit || lastcheck - check > limit) {
 353:         mod.st_mtime = 0;
 354:         /* (void) */ stat (SEQFILE, &mod);
 355:         if (mod.st_mtime != lastmod)
 356:             ret = 1;
 357:         lastmod = mod.st_mtime;
 358:     }
 359:     lastcheck = check;
 360:     return ret;
 361: }

Defined functions

anlwrk defined in line 33; used 2 times
bldflst defined in line 109; used 1 times
entflst defined in line 162; used 1 times
gtwrkf defined in line 228; used 3 times
gtwvec defined in line 252; used 1 times
newspool defined in line 342; used 1 times
pcompar defined in line 195; 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: 1997-10-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3036
Valid CSS Valid XHTML 1.0 Strict