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