|
|
1.1 root 1: /*
2: * Copyright (c) 1988 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Rick Adams.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that the above copyright notice and this paragraph are
10: * duplicated in all such forms and that any documentation,
11: * advertising materials, and other materials related to such
12: * distribution and use acknowledge that the software was developed
13: * by the University of California, Berkeley. The name of the
14: * University may not be used to endorse or promote products derived
15: * from this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: */
20:
21: #ifndef lint
22: char copyright[] =
23: "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
24: All rights reserved.\n";
25: #endif /* not lint */
26:
27: #ifndef lint
28: static char sccsid[] = "@(#)uuq.c 4.11 (Berkeley) 9/2/88";
29: #endif /* not lint */
30:
31: /*
32: * uuq - looks at uucp queues
33: *
34: * Lou Salkind
35: * New York University
36: *
37: */
38:
39: #include "uucp.h"
40: #include <stdio.h>
41:
42: #ifdef NDIR
43: #include "libndir/ndir.h"
44: #else !NDIR
45: #include <sys/dir.h>
46: #endif !NDIR
47: #include <sys/stat.h>
48:
49: #define NOSYS (struct sys *)0
50:
51: #define W_TYPE wrkvec[0]
52: #define W_FILE1 wrkvec[1]
53: #define W_FILE2 wrkvec[2]
54: #define W_USER wrkvec[3]
55: #define W_OPTNS wrkvec[4]
56: #define W_DFILE wrkvec[5]
57: #define W_MODE wrkvec[6]
58: #define WSUFSIZE 5 /* work file name suffix size */
59:
60: struct sys {
61: char s_name[8];
62: int s_njobs;
63: off_t s_bytes;
64: struct job *s_jobp;
65: struct sys *s_sysp;
66: };
67:
68: struct job {
69: int j_files;
70: int j_flags;
71: char j_jobno[WSUFSIZE];
72: char j_user[22];
73: char j_fname[128];
74: char j_grade;
75: off_t j_bytes;
76: time_t j_date;
77: struct job *j_jobp;
78: };
79:
80: struct sys *syshead;
81: struct sys *getsys();
82: int jcompare();
83: char *sysname;
84: char *user;
85: char *rmjob;
86: int hflag;
87: int lflag;
88:
89: char *malloc(), *calloc();
90: double atof();
91: float baudrate = 2400.;
92: char Username[BUFSIZ];
93: char Filename[BUFSIZ];
94: int Maxulen = 0;
95: struct timeb Now;
96:
97: main(argc, argv)
98: int argc;
99: char **argv;
100: {
101: register int i;
102: register struct sys *sp;
103: register struct job *jp;
104: struct job **sortjob;
105: int nsys;
106: extern char *optarg;
107: extern int optind;
108:
109: strcpy(Progname, "uuq");
110: uucpname(Myname);
111:
112: while ((i = getopt(argc, argv, "r:S:s:u:d:b:hl")) != EOF)
113: switch (i) {
114: case 'r':
115: case 'S':
116: Spool = optarg;
117: break;
118: case 's':
119: sysname = optarg;
120: if (strlen(sysname) > SYSNSIZE)
121: sysname[SYSNSIZE] = '\0';
122: break;
123: case 'u':
124: user = optarg;
125: break;
126: case 'd':
127: rmjob = optarg;
128: break;
129: case 'b':
130: baudrate = atof(optarg);
131: break;
132: case 'h':
133: hflag++;
134: break;
135: case 'l':
136: lflag++;
137: break;
138: default:
139: fprintf(stderr,
140: "usage: uuq [-l] [-h] [-ssystem] [-uuser] [-djobno] [-rspool] [-bbaudrate]\n");
141: exit(0);
142: }
143:
144: subchdir(Spool);
145: baudrate *= 0.7; /* reduce speed because of protocol overhead */
146: baudrate *= 7.5; /* convert to chars/minute (60/8) */
147: gather();
148: nsys = 0;
149: for (sp = syshead; sp; sp = sp->s_sysp) {
150: if (sp->s_njobs == 0)
151: continue;
152: if (!hflag && nsys++ > 0)
153: putchar('\n');
154: printf("%s: %d %s", sp->s_name,
155: sp->s_njobs, sp->s_njobs > 1 ? "jobs" : "job");
156: if (lflag) {
157: float minutes;
158: int hours;
159: /* The 80 * njobs is because of the uucp handshaking */
160: minutes = (float)(sp->s_bytes + 80 * sp->s_njobs)/baudrate;
161: hours = minutes/60;
162: printf(", %ld bytes, ", sp->s_bytes);
163: if (minutes > 60){
164: printf("%d hour%s, ",hours,
165: hours > 1 ? "s": "");
166: minutes -= 60 * hours;
167: }
168: printf("%3.1f minutes (@ effective baudrate of %d)",
169: minutes,(int)(baudrate/6));
170: }
171: putchar('\n');
172: if (hflag)
173: continue;
174: /* sort them babies! */
175: sortjob = (struct job **)calloc(sp->s_njobs, sizeof (struct job *));
176: for (i=0, jp=sp->s_jobp; i < sp->s_njobs; i++, jp=jp->j_jobp)
177: sortjob[i] = jp;
178: qsort(sortjob, sp->s_njobs, sizeof (struct job *), jcompare);
179: for (i = 0; i < sp->s_njobs; i++) {
180: jp = sortjob[i];
181: if (lflag) {
182: printf("%s %2d %-*s%7ld%5.1f %-12.12s %c %.*s\n",
183: jp->j_jobno, jp->j_files, Maxulen, jp->j_user, jp->j_bytes, jp->j_bytes/baudrate,
184: ctime(&jp->j_date) + 4, jp->j_flags, sizeof (jp->j_fname), jp->j_fname
185: );
186: } else {
187: printf("%s", jp->j_jobno);
188: putchar((i+1)%10 ? '\t' : '\n');
189: }
190: /* There's no need to keep the force poll if jobs > 1*/
191: if (sp->s_njobs > 1 && strcmp("POLL", jp->j_jobno)==0) {
192: char pbuf[BUFSIZ];
193: sprintf(pbuf,"%s/%c.%s%cPOLL",
194: subdir(Spool, CMDPRE), CMDPRE,
195: sp->s_name, jp->j_grade);
196: (void) unlink(pbuf);
197: }
198: }
199: if (!lflag && (sp->s_njobs%10))
200: putchar('\n');
201: }
202: exit(0);
203: }
204:
205: jcompare(j1, j2)
206: struct job **j1, **j2;
207: {
208: int delta;
209:
210: delta = (*j1)->j_grade - (*j2)->j_grade;
211: if (delta)
212: return delta;
213: return(strcmp((*j1)->j_jobno,(*j2)->j_jobno));
214: }
215:
216: /*
217: * Get all the command file names
218: */
219: gather()
220: {
221: struct direct *d;
222: DIR *df;
223:
224: /*
225: * Find all the spool files in the spooling directory
226: */
227: if ((df = opendir(subdir(Spool, CMDPRE))) == NULL) {
228: fprintf(stderr, "can't examine spooling area\n");
229: exit(1);
230: }
231: for (;;) {
232: if ((d = readdir(df)) == NULL)
233: break;
234: if (d->d_namlen <= 2 || d->d_name[0] != CMDPRE ||
235: d->d_name[1] != '.')
236: continue;
237: if (analjob(d->d_name) < 0) {
238: fprintf(stderr, "out of memory\n");
239: break;
240: }
241: }
242: closedir(df);
243: }
244:
245: /*
246: * analjob does the grunge work of verifying jobs
247: */
248: #include <pwd.h>
249: analjob(filename)
250: char *filename;
251: {
252: struct job *jp;
253: struct sys *sp;
254: char sbuf[MAXNAMLEN+1], str[256], nbuf[256];
255: char *jptr, *wrkvec[20];
256: char grade;
257: FILE *fp, *df;
258: struct stat statb;
259: int files, gotname, i;
260: off_t bytes;
261:
262: strncpy(sbuf, filename, MAXNAMLEN);
263: sbuf[MAXNAMLEN] = '\0';
264: jptr = sbuf + strlen(sbuf) - WSUFSIZE;
265: grade = *jptr;
266: *jptr++ = 0;
267: /*
268: * sbuf+2 now points to sysname name (null terminated)
269: * jptr now points to job number (null terminated)
270: */
271: if (rmjob) {
272: if (strcmp(rmjob, jptr))
273: return(0);
274: } else {
275: if ((sp = getsys(sbuf+2)) == NOSYS)
276: return(0);
277: if (!lflag) {
278: /* SHOULD USE A SMALLER STRUCTURE HERE */
279: jp = (struct job *)malloc(sizeof(struct job));
280: if (jp == (struct job *)0)
281: return(-1);
282: strcpy(jp->j_jobno, jptr);
283: jp->j_jobp = sp->s_jobp;
284: jp->j_grade = grade;
285: sp->s_jobp = jp;
286: sp->s_njobs++;
287: return(1);
288: }
289: }
290: if ((fp = fopen(subfile(filename), "r")) == NULL) {
291: perror(subfile(filename));
292: return(0);
293: }
294: files = 0;
295: bytes = 0;
296: gotname = 0;
297: while (fgets(str, sizeof str, fp)) {
298: if (getargs(str, wrkvec, 20) <= 0)
299: continue;
300: if (rmjob) {
301: int myuid;
302: struct passwd *pw;
303: /*
304: * Make sure person who is removing data files is
305: * the person who created it or root.
306: */
307: myuid = getuid();
308: pw = getpwnam(W_USER);
309: if (myuid && (pw == NULL || myuid != pw->pw_uid)) {
310: fprintf(stderr, "Permission denied.\n");
311: exit(1);
312: }
313: if (W_TYPE[0] == 'S' && !index(W_OPTNS, 'c')) {
314: unlink(subfile(W_DFILE));
315: fprintf(stderr, "Removing data file %s\n", W_DFILE);
316: }
317: continue;
318: }
319: if (user && (W_TYPE[0] == 'X' || !prefix(user, W_USER))) {
320: fclose(fp);
321: return(0);
322: }
323: files++;
324: if (W_TYPE[0] == 'S') {
325: if (strcmp(W_DFILE, "D.0") &&
326: stat(subfile(W_DFILE), &statb) >= 0)
327: bytes += statb.st_size;
328: else if (stat(subfile(W_FILE1), &statb) >= 0)
329: bytes += statb.st_size;
330: }
331: /* amusing heuristic */
332: #define isXfile(s) (s[0]=='D' && s[strlen(s)-WSUFSIZE]=='X')
333: if (gotname == 0 && isXfile(W_FILE1)) {
334: if ((df = fopen(subfile(W_FILE1), "r")) == NULL)
335: continue;
336: while (fgets(nbuf, sizeof nbuf, df)) {
337: nbuf[strlen(nbuf) - 1] = '\0';
338: if (nbuf[0] == 'C' && nbuf[1] == ' ') {
339: strcpy(Filename, nbuf+2);
340: gotname++;
341: } else if (nbuf[0] == 'R' && nbuf[1] == ' ') {
342: register char *p, *q, *r;
343: r = q = p = nbuf+2;
344: do {
345: if (*p == '!' || *p == '@'){
346: r = q;
347: q = p+1;
348: }
349: } while (*p++);
350:
351: strcpy(Username, r);
352: W_USER = Username;
353: }
354: }
355: fclose(df);
356: }
357: }
358: fclose(fp);
359: if (rmjob) {
360: unlink(subfile(filename));
361: fprintf(stderr, "Removing command file %s\n", filename);
362: exit(0);
363: }
364: if (files == 0) {
365: static char *wtype = "X";
366: static char *wfile = "forced poll";
367: if (strcmp("POLL", &filename[strlen(filename)-4])) {
368: fprintf(stderr, "%.14s: empty command file\n", filename);
369: return(0);
370: }
371: W_TYPE = wtype;
372: W_FILE1 = wfile;
373: }
374: jp = (struct job *)malloc(sizeof(struct job));
375: if (jp == (struct job *)0)
376: return(-1);
377: strcpy(jp->j_jobno, jptr);
378: jp->j_files = files;
379: jp->j_bytes = bytes;
380: jp->j_grade = grade;
381: jp->j_flags = W_TYPE[0];
382: strncpy(jp->j_user, W_TYPE[0]=='X' ? "---" : W_USER, 20 );
383: jp->j_user[20] = '\0';
384: i = strlen(jp->j_user);
385: if (i > Maxulen)
386: Maxulen = i;
387: /* SHOULD ADD ALL INFORMATION IN THE WHILE LOOP */
388: if (gotname)
389: strncpy(jp->j_fname, Filename, sizeof jp->j_fname);
390: else
391: strncpy(jp->j_fname, W_FILE1, sizeof jp->j_fname);
392: stat(subfile(filename), &statb);
393: jp->j_date = statb.st_mtime;
394: jp->j_jobp = sp->s_jobp;
395: sp->s_jobp = jp;
396: sp->s_njobs++;
397: sp->s_bytes += jp->j_bytes;
398: return(1);
399: }
400:
401: struct sys *
402: getsys(s)
403: register char *s;
404: {
405: register struct sys *sp;
406:
407: for (sp = syshead; sp; sp = sp->s_sysp)
408: if (strcmp(s, sp->s_name) == 0)
409: return(sp);
410: if (sysname && !prefix(sysname, s))
411: return(NOSYS);
412: sp = (struct sys *)malloc(sizeof(struct sys));
413: if (sp == NOSYS)
414: return(NOSYS);
415: strcpy(sp->s_name, s);
416: sp->s_njobs = 0;
417: sp->s_jobp = (struct job *)0;
418: sp->s_sysp = syshead;
419: sp->s_bytes = 0;
420: syshead = sp;
421: return(sp);
422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.