|
|
1.1 root 1: /* @(#)uustat.c 1.14
2: */
3: #include "uucp.h"
4: VERSION(@(#)uustat.c 1.14)
5:
6: #ifdef V7
7: #define O_RDONLY 0
8: #endif
9:
10: #define USAGE1 "[-a] [-q] or [-m] or [-kJOB] or [-rJOB] or [-p]"
11: #define USAGE2 "[-sSYSTEM] [-uUSER]"
12:
13: #define STST_MAX 132
14: struct m {
15: char mach[15]; /* machine name */
16: char locked;
17: int ccount, xcount;
18: int count, type;
19: long retrytime;
20: time_t lasttime;
21: short c_age; /* age of oldest C. file */
22: short x_age; /* age of oldest X. file */
23: char stst[STST_MAX];
24: } M[UUSTAT_TBL+2];
25:
26: extern long atol();
27: extern void qsort(); /* qsort(3) and comparison test */
28: int sortcnt = -1;
29: extern int machcmp();
30: extern int _age(); /* find the age of a file */
31:
32: extern char Jobid[]; /* jobid for status or kill option */
33: short Kill; /* == 1 if -k specified */
34: short Rejuvenate; /* == 1 for -r specified */
35: short Uopt; /* == 1 if -u option specified */
36: short Sysopt; /* == 1 if -s option specified */
37: short Summary; /* == 1 if -q or -m is specified */
38: short Queue; /* == 1 if -q option set - queue summary */
39: short Machines; /* == 1 if -m option set - machines summary */
40: short Psopt; /* == 1 if -p option set - output "ps" of LCK pids */
41:
42: main(argc, argv, envp)
43: char *argv[];
44: char **envp;
45: {
46: struct m *m, *machine();
47: DIR *spooldir, *subdir;
48: char *str, *strrchr();
49: char f[256], subf[256];
50: char *c, lckdir[BUFSIZ];
51: char buf[BUFSIZ];
52: char chkname[MAXFULLNAME];
53: char *vec[7];
54: int i, chkid;
55:
56:
57: User[0] = '\0';
58: Rmtname[0] = '\0';
59: Jobid[0] = '\0';
60: Psopt=Machines=Summary=Queue=Kill=Rejuvenate=Uopt=Sysopt=0;
61: (void) strcpy(Progname, "uustat");
62: Uid = getuid();
63: Euid = geteuid();
64: guinfo(Uid, Loginuser);
65: uucpname(Myname);
66: while ((i = getopt(argc, argv, "ak:mpr:qs:u:x:")) != EOF) {
67: switch(i){
68: case 'a':
69: Sysopt = 1;
70: break;
71: case 'k':
72: (void) strncpy(Jobid, optarg, NAMESIZE);
73: Jobid[NAMESIZE] = '\0';
74: Kill = 1;
75: break;
76: case 'm':
77: Machines = Summary = 1;
78: break;
79: case 'p':
80: Psopt = 1;
81: break;
82: case 'r':
83: (void) strncpy(Jobid, optarg, NAMESIZE);
84: Jobid[NAMESIZE] = '\0';
85: Rejuvenate = 1;
86: break;
87: case 'q':
88: Queue = Summary = 1;
89: break;
90: case 's':
91: (void) strncpy(Rmtname, optarg, MAXBASENAME);
92: Rmtname[MAXBASENAME] = '\0';
93: #if NOTDEF
94: if (versys(Rmtname, 0)) {
95: fprintf(stderr, "Invalid system\n");
96: exit(1);
97: }
98: #endif
99: Sysopt = 1;
100: break;
101: case 'u':
102: (void) strncpy(User, optarg, 8);
103: User[8] = '\0';
104: if(gninfo(User, &chkid, chkname)) {
105: fprintf(stderr, "Invalid user\n");
106: exit(1);
107: }
108: Uopt = 1;
109: break;
110: case 'x':
111: Debug = atoi(optarg);
112: if (Debug <= 0)
113: Debug = 1;
114: break;
115: default:
116: (void) fprintf(stderr, "\tusage: %s %s\n",
117: Progname, USAGE1);
118: (void) fprintf(stderr, "or\n\tusage: %s %s\n",
119: Progname, USAGE2);
120: exit(1);
121: }
122: }
123:
124: if (argc != optind) {
125: (void) fprintf(stderr, "\tusage: %s %s\n", Progname, USAGE1);
126: (void) fprintf(stderr, "or\n\tusage: %s %s\n",
127: Progname, USAGE2);
128: exit(1);
129: }
130:
131: DEBUG(9, "Progname (%s): STARTED\n", Progname);
132: DEBUG(9, "User=%s, ", User);
133: DEBUG(9, "Loginuser=%s, ", Loginuser);
134: DEBUG(9, "Jobid=%s, ", Jobid);
135: DEBUG(9, "Rmtname=%s\n", Rmtname);
136:
137: if ((Psopt + Machines + Queue + Kill + Rejuvenate + (Uopt|Sysopt)) >1) {
138: /* only -u and -s can be used together */
139: printf("\tusage: %s %s\n", Progname, USAGE1);
140: printf("or\n\tusage: %s %s\n", Progname, USAGE2);
141: exit(1);
142: }
143: if ( !(Kill | Rejuvenate | Uopt | Sysopt | Queue | Machines) ) {
144: (void) strcpy(User, Loginuser);
145: Uopt = 1;
146: }
147:
148: if (Psopt) {
149: /* do "ps -flp" or pids in LCK files */
150: lckpid();
151: /* lckpid will not return */
152: }
153:
154: if (Summary) {
155: /* Gather data for Summary option report */
156: if (chdir(STATDIR) || (spooldir = opendir(STATDIR)) == NULL)
157: exit(101); /* good old code 101 */
158: while (gnamef(spooldir, f) == TRUE) {
159: if (freopen(f, "r", stdin) == NULL)
160: continue;
161: m = machine(f);
162: if (fgets(buf, sizeof(buf), stdin) == NULL)
163: continue;
164: if ((str = strchr(buf, '\n')) != NULL)
165: *str = 0;
166: if (getargs(buf, vec, 5) < 5)
167: continue;
168: m->type = atoi(vec[0]);
169: m->count = atoi(vec[1]);
170: m->lasttime = atol(vec[2]);
171: m->retrytime = atol(vec[3]);
172: (void) strncpy(m->stst, vec[4], STST_MAX);
173: str = strrchr(m->stst, ' ');
174: (void) machine(++str); /* longer name? */
175: *str = '\0';
176:
177: }
178: closedir(spooldir);
179: }
180:
181:
182: if (Summary) {
183: /* search for LCK machines */
184:
185: (void) strcpy(lckdir, LOCKPRE);
186: *strrchr(lckdir, '/') = '\0';
187: /* open lock directory */
188: if (chdir(lckdir) != 0 || (subdir = opendir(lckdir)) == NULL)
189: exit(101); /* good old code 101 */
190:
191: while (gnamef(subdir, f) == TRUE) {
192: if (EQUALSN("LCK..", f, 5)) {
193: if (!EQUALSN(f + 5, "cul", 3)
194: && !EQUALSN(f + 5, "tty", 3)
195: && !EQUALSN(f + 5, "dtsw", 4)
196: && !EQUALSN(f + 5, "vadic", 5)
197: && !EQUALSN(f + 5, "micom", 5))
198: machine(f + 5)->locked++;
199: }
200: }
201: }
202:
203: if (chdir(SPOOL) != 0 || (spooldir = opendir(SPOOL)) == NULL)
204: exit(101); /* good old code 101 */
205: while (gnamef(spooldir, f) == TRUE) {
206: if (EQUALSN("LCK..", f, 5))
207: continue;
208:
209: if (*Rmtname && !EQUALSN(Rmtname, f, SYSNSIZE))
210: continue;
211:
212: if ( (Kill || Rejuvenate)
213: && (!EQUALSN(f, Jobid, strlen(Jobid)-5)) )
214: continue;
215:
216: if (DIRECTORY(f) && (subdir = opendir(f))) {
217: m = machine(f);
218: while (gnamef(subdir, subf) == TRUE)
219: if (subf[1] == '.') {
220: if (subf[0] == CMDPRE) {
221: m->ccount++;
222: if (Kill || Rejuvenate)
223: kprocessC(f, subf);
224: else if (Uopt | Sysopt)
225: uprocessC(f, subf);
226: else /* get the age of the C. file */
227: if ( (i = _age(f, subf))>m->c_age)
228: m->c_age = i;
229: }
230:
231: else if (subf[0] == XQTPRE) {
232: m->xcount++;
233: if ( (i = _age(f, subf)) > m->x_age)
234: m->x_age = i;
235: }
236:
237: }
238: closedir(subdir);
239: }
240: }
241: /* for Kill or Rejuvenate - will not get here unless it failed */
242: if (Kill || Rejuvenate) {
243: printf("Can't find Job %s; Not %s\n", Jobid,
244: Kill ? "killed" : "rejuvenated");
245: exit(1);
246: }
247:
248: /* Make sure the overflow entry is null since it may be incorrect */
249: M[UUSTAT_TBL].mach[0] = NULLCHAR;
250: if (Summary) {
251: for((sortcnt = 0, m = &M[0]);*(m->mach) != NULL;(sortcnt++,m++))
252: ;
253: qsort((char *)M, (unsigned int)sortcnt, sizeof(struct m), machcmp);
254: for (m = M; m->mach[0] != NULLCHAR; m++)
255: printit(m);
256: }
257: exit(0);
258: }
259:
260:
261: /*
262: * uprocessC - get information about C. file
263: *
264: */
265:
266: uprocessC(dir, file)
267: char *file, *dir;
268: {
269: struct stat s;
270: register struct tm *tp;
271: char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
272: char xfullname[MAXFULLNAME];
273: char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
274: FILE *fp, *xfp;
275: short first = 1;
276: extern long fsize();
277:
278: DEBUG(9, "uprocessC(%s, ", dir);
279: DEBUG(9, "%s);\n", file);
280:
281: if (Jobid[0] != '\0' && (!EQUALS(Jobid, &file[2])) ) {
282: /* kill job - not this one */
283: return;
284: }
285:
286: (void) sprintf(fullname, "%s/%s", dir, file);
287: if (stat(fullname, &s) != 0) {
288: /* error - can't stat */
289: DEBUG(4, "Can't stat file (%s),", fullname);
290: DEBUG(4, " errno (%d) -- skip it!\n", errno);
291: }
292:
293: fp = fopen(fullname, "r");
294: if (fp == NULL) {
295: DEBUG(4, "Can't open file (%s), ", fullname);
296: DEBUG(4, "errno=%d -- skip it!\n", errno);
297: return;
298: }
299: tp = localtime(&s.st_mtime);
300:
301: if (s.st_size == 0 && User[0] == '\0') { /* dummy D. for polling */
302: printf("%-12s %2.2d/%2.2d-%2.2d:%2.2d:%2.2d (POLL)\n",
303: &file[2], tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
304: tp->tm_min, tp->tm_sec);
305: }
306: else while (fgets(buf, BUFSIZ, fp) != NULL) {
307: if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
308: user, opt, file3) <5) {
309: DEBUG(4, "short line (%s)\n", buf);
310: continue;
311: }
312: DEBUG(9, "type (%s), ", type);
313: DEBUG(9, "file1 (%s)", file1);
314: DEBUG(9, "file2 (%s)", file2);
315: DEBUG(9, "file3 (%s)", file3);
316: DEBUG(9, "user (%s)", user);
317:
318: if (User[0] != '\0' && (!EQUALS(User, user)) )
319: continue;
320:
321: /*
322: if ( (*file2 != 'X')
323: && (*file1 != '/' && *file1 != '~')
324: && (*file2 != '/' && *file2!= '~') )
325: continue;
326: */
327:
328: if (first)
329: printf("%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
330: &file[2], tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
331: tp->tm_min);
332: else
333: printf("%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
334: "", tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
335: tp->tm_min);
336: first = 0;
337:
338: printf("%s %s ", type, dir);
339: if (*type == 'R')
340: printf("%s %s\n", user, file1);
341: else if (file2[0] != 'X')
342: printf("%s %ld %s\n", user, fsize(dir, file3, file1), file1);
343: else if (*type == 'S' && file2[0] == 'X') {
344: (void) sprintf(xfullname, "%s/%s", dir, file1);
345: xfp = fopen(xfullname, "r");
346: if (xfp == NULL) { /* program error */
347: DEBUG(4, "Can't read %s, ", xfullname);
348: DEBUG(4, "errno=%d -- skip it!\n", errno);
349: printf("%s %s %s ", type, dir, user);
350: printf("????\n");
351: }
352: else {
353: char command[BUFSIZ], uline_u[BUFSIZ], uline_m[BUFSIZ];
354: char retaddr[BUFSIZ], *username;
355:
356: *retaddr = *uline_u = *uline_m = '\0';
357: while (fgets(buf, BUFSIZ, xfp) != NULL) {
358: switch(buf[0]) {
359: case 'C':
360: strcpy(command, buf + 2);
361: break;
362: case 'U':
363: sscanf(buf + 2, "%s%s", uline_u, uline_m);
364: break;
365: case 'R':
366: sscanf(buf+2, "%s", retaddr);
367: break;
368: }
369: }
370: username = user;
371: if (*uline_u != '\0')
372: username = uline_u;
373: if (*retaddr != '\0')
374: username = retaddr;
375: if (!EQUALS(uline_m, Myname))
376: printf("%s!", uline_m);
377: printf("%s %s", username, command);
378: }
379: if (xfp != NULL)
380: fclose(xfp);
381: }
382: }
383:
384: fclose(fp);
385: return;
386: }
387:
388:
389: /*
390: * kprocessC - process kill or rejuvenate job
391: */
392:
393: kprocessC(dir, file)
394: char *file, *dir;
395: {
396: struct stat s;
397: register struct tm *tp;
398: extern struct tm *localtime();
399: extern int errno;
400: char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
401: char rfullname[MAXFULLNAME];
402: char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
403: FILE *fp, *xfp;
404: time_t times[2];
405: short ret;
406: short first = 1;
407:
408: DEBUG(9, "kprocessC(%s, ", dir);
409: DEBUG(9, "%s);\n", file);
410:
411: if ((!EQUALS(Jobid, &file[2])) ) {
412: /* kill job - not this one */
413: return;
414: }
415:
416: (void) sprintf(fullname, "%s/%s", dir, file);
417: if (stat(fullname, &s) != 0) {
418: /* error - can't stat */
419: fprintf(stderr, "Can't stat:%s, errno (%d)--can't %s it!\n",
420: fullname, errno, Kill ? "kill" : "rejuvenate");
421: exit(1);
422: }
423:
424: fp = fopen(fullname, "r");
425: if (fp == NULL) {
426: fprintf(stderr, "Can't read:%s, errno (%d)--can't %s it!\n",
427: fullname, errno, Kill ? "kill" : "rejuvenate");
428: exit(1);
429: }
430:
431: times[0] = times[1] = time((time_t *)NULL);
432:
433: while (fgets(buf, BUFSIZ, fp) != NULL) {
434: if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
435: user, opt, file3) <6) {
436: fprintf(stderr, "Bad format:%s, errno (%d)--can't %s it!\n",
437: fullname, errno, Kill ? "kill" : "rejuvenate");
438: exit(1);
439: }
440: DEBUG(9, "type (%s) ", type);
441: DEBUG(9, "file1 (%s) ", file1);
442: DEBUG(9, "file2 (%s) ", file2);
443: DEBUG(9, "file3 (%s) ", file3);
444: DEBUG(9, "user (%s)\n", user);
445:
446:
447: if (first) {
448: if (Uid != 0
449: && !PREFIX(Loginuser, user)
450: && !PREFIX(user, Loginuser) ) {
451: /* not allowed - not owner or root */
452: fprintf(stderr,
453: "Not owner or root - can't %s job %s\n",
454: Kill ? "kill" : "rejuvenate", Jobid);
455: exit(1);
456: }
457: first = 0;
458: }
459:
460: /* remove D. file */
461: (void) sprintf(rfullname, "%s/%s", dir, file3);
462: DEBUG(4, "Remove %s\n", rfullname);
463: if (Kill)
464: ret = unlink(rfullname);
465: else /* Rejuvenate */
466: ret = utime(rfullname, times);
467: /*
468: * who cares if we can't?
469: * the C. is the file that matters,
470: * and the D. is sometimes a dummy
471: * we should check specifically but i'm lazy
472: */
473: #if NOTDEF
474: if (ret != 0 && errno != ENOENT) {
475: /* program error?? */
476: fprintf(stderr, "Error: Can't %s, File (%s), errno (%d)\n",
477: Kill ? "kill" : "rejuvenate", rfullname, errno);
478: exit(1);
479: }
480: #endif
481: }
482:
483: DEBUG(4, "Remove %s\n", fullname);
484: if (Kill)
485: ret = unlink(fullname);
486: else /* Rejuvenate */
487: ret = utime(fullname, times);
488:
489: if (ret != 0) {
490: /* program error?? */
491: fprintf(stderr, "Error: Can't %s, File ( %s), errno (%d)\n",
492: Kill ? "kill" : "rejuvenate", fullname, errno);
493: exit(1);
494: }
495: fclose(fp);
496: printf("Job: %s successfully %s\n", Jobid,
497: Kill ? "killed" : "rejuvenated");
498: exit(0);
499: }
500:
501: /*
502: * fsize - return the size of f1 or f2 (if f1 does not exist)
503: * f1 is the local name
504: *
505: */
506:
507: long
508: fsize(dir, f1, f2)
509: char *dir, *f1, *f2;
510: {
511: struct stat s;
512: char fullname[BUFSIZ];
513:
514: (void) sprintf(fullname, "%s/%s", dir, f1);
515: if (stat(fullname, &s) == 0) {
516: return(s.st_size);
517: }
518: if (stat(f2, &s) == 0) {
519: return(s.st_size);
520: }
521:
522: return(-99999);
523: }
524:
525: cleanup(){}
526: void logent(){} /* to load ulockf.c */
527: void systat(){} /* to load utility.c */
528:
529: struct m *
530: machine(name)
531: char *name;
532: {
533: struct m *m;
534: int namelen;
535:
536: DEBUG(9, "machine(%s), ", name);
537: namelen = strlen(name);
538: for (m = M; m->mach[0] != NULLCHAR; m++)
539: /* match on overlap? */
540: if (EQUALSN(name, m->mach, SYSNSIZE)) {
541: /* use longest name */
542: if (namelen > strlen(m->mach))
543: (void) strcpy(m->mach, name);
544: return(m);
545: }
546:
547: /*
548: * The table is set up with 2 extra entries
549: * When we go over by one, output error to errors log
550: * When more than one over, just reuse the previous entry
551: */
552: DEBUG(9, "m-M=%d\n", m-M);
553: if (m-M >= UUSTAT_TBL) {
554: if (m-M == UUSTAT_TBL) {
555: errent("MACHINE TABLE FULL", "", UUSTAT_TBL,
556: sccsid, __FILE__, __LINE__);
557: (void) fprintf(stderr,
558: "WARNING: Table Overflow--output not complete\n");
559: }
560: else
561: /* use the last entry - overwrite it */
562: m = &M[UUSTAT_TBL];
563: }
564:
565: (void) strcpy(m->mach, name);
566: m->c_age= m->x_age= m->lasttime= m->locked= m->ccount= m->xcount= 0;
567: m->stst[0] = '\0';
568: return(m);
569: }
570:
571: printit(m)
572: struct m *m;
573: {
574: register struct tm *tp;
575: time_t t;
576: int min;
577: extern struct tm *localtime();
578:
579: if (m->ccount == 0
580: && m->xcount == 0
581: /*&& m->stst[0] == '\0'*/
582: && m->locked == 0
583: && Queue
584: && m->type == 0)
585: return;
586: printf("%-10s", m->mach);
587: if (m->ccount)
588: printf("%3dC", m->ccount);
589: else
590: printf(" ");
591: if (m->c_age)
592: printf("(%d)", m->c_age);
593: else
594: printf(" ");
595: if (m->xcount)
596: printf("%4dX", m->xcount);
597: else
598: printf(" ");
599: if (m->x_age)
600: printf("(%d) ", m->x_age);
601: else
602: printf(" ");
603:
604: if (m->lasttime) {
605: tp = localtime(&m->lasttime);
606: printf("%2.2d/%2.2d-%2.2d:%2.2d ",
607: tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
608: tp->tm_min);
609: }
610: /* if (m->locked && m->type != SS_INPROGRESS) */
611: if (m->locked)
612: printf("Locked ");
613: if (m->stst[0] != '\0') {
614: printf("%s", m->stst);
615: switch (m->type) {
616: case SS_SEQBAD:
617: case SS_LOGIN_FAILED:
618: case SS_DIAL_FAILED:
619: case SS_BAD_LOG_MCH:
620: case SS_BADSYSTEM:
621: case SS_CANT_ACCESS_DEVICE:
622: case SS_DEVICE_FAILED:
623: case SS_WRONG_MCH:
624: case SS_RLOCKED:
625: case SS_RUNKNOWN:
626: case SS_RLOGIN:
627: case SS_UNKNOWN_RESPONSE:
628: case SS_STARTUP:
629: case SS_CHAT_FAILED:
630: case SS_CONVERSATION:
631: (void) time(&t);
632: t = m->retrytime - (t - m->lasttime);
633: if (t > 0) {
634: min = (t + 59) / 60;
635: printf("Retry: %d:%2.2d", min/60, min%60);
636: }
637: if (m->count > 1)
638: printf(" Count: %d", m->count);
639: }
640: }
641: putchar('\n');
642: }
643:
644: #define MAXLOCKS 100 /* Maximum number of lock files this will handle */
645:
646: lckpid()
647: {
648: register i;
649: long pid, ret, fd;
650: #ifdef ASCIILOCKS
651: char alpid[SIZEOFPID+2]; /* +2 for '\n' and null */
652: #endif
653: long list[MAXLOCKS];
654: char buf[BUFSIZ], f[MAXBASENAME];
655: char *c, lckdir[BUFSIZ];
656: DIR *dir;
657:
658: DEBUG(9, "lckpid() - entered\n", "");
659: for (i=0; i<MAXLOCKS; i++)
660: list[i] = -1;
661: (void) strcpy(lckdir, LOCKPRE);
662: *strrchr(lckdir, '/') = '\0';
663: DEBUG(9, "lockdir (%s)\n", lckdir);
664:
665: /* open lock directory */
666: if (chdir(lckdir) != 0 || (dir = opendir(lckdir)) == NULL)
667: exit(101); /* good old code 101 */
668: while (gnamef(dir, f) == TRUE) {
669: /* find all lock files */
670: DEBUG(9, "f (%s)\n", f);
671: if (EQUALSN("LCK.", f, 4)) {
672: /* read LCK file */
673: fd = open(f, O_RDONLY);
674: printf("%s: ", f);
675: #ifdef ASCIILOCKS
676: ret = read(fd, alpid, SIZEOFPID+2); /* +2 for '\n' and null */
677: pid = atoi(alpid);
678: #else
679: ret = read(fd, &pid, sizeof (int));
680: #endif
681: (void) close(fd);
682: if (ret != -1) {
683: printf("%d\n", pid);
684: for(i=0; i<MAXLOCKS; i++) {
685: if (list[i] == pid)
686: break;
687: if (list[i] == -1) {
688: list[i] = pid;
689: break;
690: }
691: }
692: }
693: else
694: printf("????\n");
695: }
696: }
697: fflush(stdout);
698: *buf = NULLCHAR;
699: for (i=0; i<MAXLOCKS; i++) {
700: if( list[i] == -1)
701: break;
702: (void) sprintf(&buf[strlen(buf)], "%d ", list[i]);
703: }
704:
705: if (i > 0)
706: #ifdef V7
707: execlp(UUPS, "uustat-ps", buf, 0);
708: #else
709: execl("/bin/ps", "ps", "-flp", buf, 0);
710: #endif
711: exit(0);
712: }
713:
714: int machcmp(a,b)
715: char *a,*b;
716: {
717: return(strcmp(((struct m *) a)->mach,((struct m *) b)->mach));
718: }
719:
720: static long _sec_per_day = 86400L;
721:
722: /*
723: * _age - find the age of "file" in days
724: * return:
725: * age of file
726: * 0 - if stat fails
727: */
728:
729: int
730: _age(dir, file)
731: char * file; /* the file name */
732: char * dir; /* system spool directory */
733: {
734: char fullname[MAXFULLNAME];
735: static time_t ptime = 0;
736: time_t time();
737: struct stat stbuf;
738:
739: if (!ptime)
740: (void) time(&ptime);
741: (void) sprintf(fullname, "%s/%s", dir, file);
742: if (stat(fullname, &stbuf) != -1) {
743: return ((int)((ptime - stbuf.st_mtime)/_sec_per_day));
744: }
745: else
746: return(0);
747: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.