117829Sralph #ifndef lint 2*25144Sbloom static char sccsid[] = "@(#)uuq.c 4.6 (Berkeley) 10/09/85"; 317829Sralph #endif 417829Sralph 517829Sralph /* 617829Sralph * uuq - looks at uucp queues 717829Sralph * 817829Sralph * Lou Salkind 917829Sralph * New York University 1017829Sralph * 1117829Sralph */ 1217829Sralph 1317829Sralph #include "uucp.h" 1417829Sralph #include <stdio.h> 1517829Sralph 1617829Sralph #ifdef NDIR 1717829Sralph #include "libndir/ndir.h" 1817829Sralph #else !NDIR 1917829Sralph #include <sys/dir.h> 2017829Sralph #endif !NDIR 2117829Sralph #include <sys/stat.h> 2217829Sralph 2317829Sralph #define NOSYS (struct sys *)0 2417829Sralph 2517829Sralph #define W_TYPE wrkvec[0] 2617829Sralph #define W_FILE1 wrkvec[1] 2717829Sralph #define W_FILE2 wrkvec[2] 2817829Sralph #define W_USER wrkvec[3] 2917829Sralph #define W_OPTNS wrkvec[4] 3017829Sralph #define W_DFILE wrkvec[5] 3117829Sralph #define W_MODE wrkvec[6] 3217829Sralph #define WSUFSIZE 5 /* work file name suffix size */ 3317829Sralph 3417829Sralph struct sys { 3517829Sralph char s_name[8]; 3617829Sralph int s_njobs; 3717829Sralph off_t s_bytes; 3817829Sralph struct job *s_jobp; 3917829Sralph struct sys *s_sysp; 4017829Sralph }; 4117829Sralph 4217829Sralph struct job { 4317829Sralph int j_files; 4417829Sralph int j_flags; 4517829Sralph char j_jobno[WSUFSIZE]; 4617829Sralph char j_user[22]; 4717829Sralph char j_fname[128]; 4817829Sralph char j_grade; 4917829Sralph off_t j_bytes; 5017829Sralph time_t j_date; 5117829Sralph struct job *j_jobp; 5217829Sralph }; 5317829Sralph 5417829Sralph struct sys *syshead; 5517829Sralph struct sys *getsys(); 5617829Sralph int jcompare(); 5717829Sralph char *sysname; 5817829Sralph char *user; 5917829Sralph char *rmjob; 6017829Sralph int hflag; 6117829Sralph int lflag; 6217829Sralph 6317829Sralph char *malloc(), *calloc(); 6417829Sralph float atof(); 6523689Sbloom float baudrate = 1200.; 6617829Sralph char Username[BUFSIZ]; 6717829Sralph char Filename[BUFSIZ]; 6817829Sralph int Maxulen = 0; 69*25144Sbloom struct timeb Now; 7017829Sralph 7117829Sralph main(argc, argv) 7217829Sralph char **argv; 7317829Sralph { 7417829Sralph register i; 7517829Sralph register struct sys *sp; 7617829Sralph register struct job *jp; 7717829Sralph struct job **sortjob; 7817829Sralph int nsys; 7917829Sralph 8017829Sralph strcpy(Progname, "uuq"); 8117829Sralph uucpname(Myname); 8217829Sralph 8317829Sralph while (--argc > 0) { 8417829Sralph argv++; 8517829Sralph if (argv[0][0] == '-') switch (argv[0][1]) { 8617829Sralph case 'r': 8717829Sralph Spool = &argv[0][2]; 8817829Sralph break; 8917829Sralph case 's': 9017829Sralph sysname = &argv[0][2]; 9123689Sbloom if (strlen(sysname) > SYSNSIZE) 9223689Sbloom sysname[SYSNSIZE] = '\0'; 9317829Sralph break; 9417829Sralph case 'u': 9517829Sralph user = &argv[0][2]; 9617829Sralph break; 9717829Sralph case 'd': 9817829Sralph rmjob = &argv[0][2]; 9917829Sralph break; 10017829Sralph case 'b': 10117829Sralph baudrate = atof(&argv[0][2]); 10217829Sralph break; 10317829Sralph case 'h': 10417829Sralph hflag++; 10517829Sralph break; 10617829Sralph case 'l': 10717829Sralph lflag++; 10817829Sralph break; 10917829Sralph default: 11017829Sralph fprintf(stderr, 11117829Sralph "usage: uuq [-l] [-h] [-ssystem] [-uuser] [-djobno] [-rspool] [-bbaudrate]\n"); 11217829Sralph exit(0); 11317829Sralph } 11417829Sralph } 11517829Sralph 11617829Sralph subchdir(Spool); 11723689Sbloom baudrate *= 0.7; /* reduce speed because of protocol overhead */ 11823689Sbloom baudrate *= 6.; /* convert to chars/minute (60/10) */ 11917829Sralph gather(); 12017829Sralph nsys = 0; 12117829Sralph for (sp = syshead; sp; sp = sp->s_sysp) { 12217829Sralph if (sp->s_njobs == 0) 12317829Sralph continue; 12417829Sralph if (!hflag && nsys++ > 0) 12517829Sralph putchar('\n'); 12617829Sralph printf("%s: %d %s", sp->s_name, 12717829Sralph sp->s_njobs, sp->s_njobs > 1 ? "jobs" : "job"); 12817829Sralph if (lflag) { 12917829Sralph float minutes; 13017829Sralph int hours; 13117829Sralph /* The 80 * njobs is because of the uucp handshaking */ 13217829Sralph minutes = (float)(sp->s_bytes + 80 * sp->s_njobs)/baudrate; 13317829Sralph hours = minutes/60; 13417829Sralph printf(", %d bytes, ", sp->s_bytes); 13517829Sralph if (minutes > 60){ 13617829Sralph printf("%d hour%s, ",hours, 13717829Sralph hours > 1 ? "s": ""); 13817829Sralph minutes -= 60 * hours; 13917829Sralph } 14023729Sbloom printf("%3.1f minutes (@ effective baudrate of %d)", 14123729Sbloom minutes,(int)baudrate/6); 14217829Sralph } 14317829Sralph putchar('\n'); 14417829Sralph if (hflag) 14517829Sralph continue; 14617829Sralph /* sort them babies! */ 14717829Sralph sortjob = (struct job **)calloc(sp->s_njobs, sizeof (struct job 14817829Sralph *)); 14917829Sralph for (i=0, jp=sp->s_jobp; i < sp->s_njobs; i++, jp=jp->j_jobp) 15017829Sralph sortjob[i] = jp; 15117829Sralph qsort(sortjob, sp->s_njobs, sizeof (struct job *), jcompare); 15217829Sralph for (i = 0; i < sp->s_njobs; i++) { 15317829Sralph jp = sortjob[i]; 15417829Sralph if (lflag) { 15517829Sralph printf("%s %2d %-*s%7d%5.1f %-12.12s %c %.*s\n", 15617829Sralph jp->j_jobno, jp->j_files, Maxulen, jp->j_user, jp->j_bytes, jp->j_bytes/baudrate, 15717829Sralph ctime(&jp->j_date) + 4, jp->j_flags, sizeof (jp->j_fname), jp->j_fname 15817829Sralph ); 15917829Sralph } else { 16017829Sralph printf("%s", jp->j_jobno); 16117829Sralph putchar((i+1)%10 ? '\t' : '\n'); 16217829Sralph } 16317829Sralph /* There's no need to keep the force poll if jobs > 1*/ 16417829Sralph if (sp->s_njobs > 1 && strcmp("POLL", jp->j_jobno)==0) { 16517829Sralph char pbuf[BUFSIZ]; 16617829Sralph sprintf(pbuf,"%s/%c.%szPOLL", subdir(Spool, CMDPRE), CMDPRE,sp->s_name); 16717829Sralph unlink(pbuf); 16817829Sralph } 16917829Sralph } 17017829Sralph if (!lflag && (sp->s_njobs%10)) 17117829Sralph putchar('\n'); 17217829Sralph } 17317829Sralph exit(0); 17417829Sralph } 17517829Sralph 17617829Sralph jcompare(j1, j2) 17717829Sralph struct job **j1, **j2; 17817829Sralph { 17917829Sralph int delta; 18017829Sralph 18117829Sralph delta = (*j1)->j_grade - (*j2)->j_grade; 18217829Sralph if (delta) 18317829Sralph return delta; 18417829Sralph return(strcmp((*j1)->j_jobno,(*j2)->j_jobno)); 18517829Sralph } 18617829Sralph 18717829Sralph /* 18817829Sralph * Get all the command file names 18917829Sralph */ 19017829Sralph gather() 19117829Sralph { 19217829Sralph struct direct *d; 19317829Sralph DIR *df; 19417829Sralph 19517829Sralph /* 19617829Sralph * Find all the spool files in the spooling directory 19717829Sralph */ 19817829Sralph if ((df = opendir(subdir(Spool, CMDPRE))) == NULL) { 19923689Sbloom fprintf(stderr, "can't examine spooling area"); 20017829Sralph exit(1); 20117829Sralph } 20217829Sralph for (;;) { 20317829Sralph if ((d = readdir(df)) == NULL) 20417829Sralph break; 20517829Sralph if (d->d_namlen <= 2 || d->d_name[0] != CMDPRE || 20617829Sralph d->d_name[1] != '.') 20717829Sralph continue; 20817829Sralph if (analjob(d->d_name) < 0) { 20917829Sralph fprintf(stderr, "out of memory\n"); 21017829Sralph break; 21117829Sralph } 21217829Sralph } 21317829Sralph closedir(df); 21417829Sralph } 21517829Sralph 21617829Sralph /* 21717829Sralph * analjob does the grunge work of verifying jobs 21817829Sralph */ 21917829Sralph analjob(filename) 22017829Sralph char *filename; 22117829Sralph { 22217829Sralph struct job *jp; 22317829Sralph struct sys *sp; 22417829Sralph char sbuf[MAXNAMLEN+1], str[256], nbuf[256]; 22517829Sralph char *jptr, *wrkvec[20]; 22617829Sralph char grade; 22717829Sralph FILE *fp, *df; 22817829Sralph struct stat statb; 22917829Sralph int files, gotname, i; 23017829Sralph off_t bytes; 23117829Sralph 23217829Sralph strncpy(sbuf, filename, MAXNAMLEN); 23317829Sralph sbuf[MAXNAMLEN] = '\0'; 23417829Sralph jptr = sbuf + strlen(sbuf) - WSUFSIZE; 23517829Sralph grade = *jptr; 23617829Sralph *jptr++ = 0; 23717829Sralph /* 23817829Sralph * sbuf+2 now points to sysname name (null terminated) 23917829Sralph * jptr now points to job number (null terminated) 24017829Sralph */ 24117829Sralph if (rmjob) { 24217829Sralph if (strcmp(rmjob, jptr)) 24317829Sralph return(0); 24417829Sralph } else { 24517829Sralph if ((sp = getsys(sbuf+2)) == NOSYS) 24617829Sralph return(0); 24717829Sralph if (!lflag) { 24817829Sralph /* SHOULD USE A SMALLER STRUCTURE HERE */ 24917829Sralph jp = (struct job *)malloc(sizeof(struct job)); 25017829Sralph if (jp == (struct job *)0) 25117829Sralph return(-1); 25217829Sralph strcpy(jp->j_jobno, jptr); 25317829Sralph jp->j_jobp = sp->s_jobp; 25417829Sralph jp->j_grade = grade; 25517829Sralph sp->s_jobp = jp; 25617829Sralph sp->s_njobs++; 25717829Sralph return(1); 25817829Sralph } 25917829Sralph } 26017829Sralph if ((fp = fopen(subfile(filename), "r")) == NULL) { 26117829Sralph perror(subfile(filename)); 26217829Sralph return(0); 26317829Sralph } 26417829Sralph files = 0; 26517829Sralph bytes = 0; 26617829Sralph gotname = 0; 26717829Sralph while (fgets(str, sizeof str, fp)) { 26817829Sralph if (getargs(str, wrkvec, 20) <= 0) 26917829Sralph continue; 27017829Sralph if (rmjob) { 27117829Sralph if (W_TYPE[0] == 'S' && !index(W_OPTNS, 'c')) { 27217829Sralph unlink(subfile(W_DFILE)); 27317829Sralph fprintf(stderr, "Removing data file %s\n", W_DFILE); 27417829Sralph } 27517829Sralph continue; 27617829Sralph } 27717829Sralph if (user && (W_TYPE[0] == 'X' || !prefix(user, W_USER))) { 27817829Sralph fclose(fp); 27917829Sralph return(0); 28017829Sralph } 28117829Sralph files++; 28217829Sralph if (W_TYPE[0] == 'S') { 28317829Sralph if (strcmp(W_DFILE, "D.0") && 28417829Sralph stat(subfile(W_DFILE), &statb) >= 0) 28517829Sralph bytes += statb.st_size; 28617829Sralph else if (stat(subfile(W_FILE1), &statb) >= 0) 28717829Sralph bytes += statb.st_size; 28817829Sralph } 28917829Sralph /* amusing heuristic */ 29017829Sralph #define isXfile(s) (s[0]=='D' && s[strlen(s)-WSUFSIZE]=='X') 29117829Sralph if (gotname == 0 && isXfile(W_FILE1)) { 29217829Sralph if ((df = fopen(subfile(W_FILE1), "r")) == NULL) 29317829Sralph continue; 29417829Sralph while (fgets(nbuf, sizeof nbuf, df)) { 29517829Sralph nbuf[strlen(nbuf) - 1] = '\0'; 29617829Sralph if (nbuf[0] == 'C' && nbuf[1] == ' ') { 29717829Sralph strcpy(Filename, nbuf+2); 29817829Sralph gotname++; 29917829Sralph } else if (nbuf[0] == 'R' && nbuf[1] == ' ') { 30017829Sralph register char *p, *q, *r; 30117829Sralph r = q = p = nbuf+2; 30217829Sralph do { 30317829Sralph if (*p == '!' || *p == '@'){ 30417829Sralph r = q; 30517829Sralph q = p+1; 30617829Sralph } 30717829Sralph } while (*p++); 30817829Sralph 30917829Sralph strcpy(Username, r); 31017829Sralph W_USER = Username; 31117829Sralph } 31217829Sralph } 31317829Sralph fclose(df); 31417829Sralph } 31517829Sralph } 31617829Sralph fclose(fp); 31717829Sralph if (rmjob) { 31817829Sralph unlink(subfile(filename)); 31917829Sralph fprintf(stderr, "Removing command file %s\n", filename); 32017829Sralph exit(0); 32117829Sralph } 32217829Sralph if (files == 0) { 32317829Sralph static char *wtype = "X"; 32417829Sralph static char *wfile = "forced poll"; 32517829Sralph if (strcmp("POLL", &filename[strlen(filename)-4])) { 32617829Sralph fprintf(stderr, "%.14s: empty command file\n", filename); 32717829Sralph return(0); 32817829Sralph } 32917829Sralph W_TYPE = wtype; 33017829Sralph W_FILE1 = wfile; 33117829Sralph } 33217829Sralph jp = (struct job *)malloc(sizeof(struct job)); 33317829Sralph if (jp == (struct job *)0) 33417829Sralph return(-1); 33517829Sralph strcpy(jp->j_jobno, jptr); 33617829Sralph jp->j_files = files; 33717829Sralph jp->j_bytes = bytes; 33817829Sralph jp->j_grade = grade; 33917829Sralph jp->j_flags = W_TYPE[0]; 34017829Sralph strncpy(jp->j_user, W_TYPE[0]=='X' ? "---" : W_USER, 20 ); 34117829Sralph jp->j_user[20] = '\0'; 34217829Sralph i = strlen(jp->j_user); 34317829Sralph if (i > Maxulen) 34417829Sralph Maxulen = i; 34517829Sralph /* SHOULD ADD ALL INFORMATION IN THE WHILE LOOP */ 34617829Sralph if (gotname) 34717829Sralph strncpy(jp->j_fname, Filename, sizeof jp->j_fname); 34817829Sralph else 34917829Sralph strncpy(jp->j_fname, W_FILE1, sizeof jp->j_fname); 35017829Sralph stat(subfile(filename), &statb); 35117829Sralph jp->j_date = statb.st_mtime; 35217829Sralph jp->j_jobp = sp->s_jobp; 35317829Sralph sp->s_jobp = jp; 35417829Sralph sp->s_njobs++; 35517829Sralph sp->s_bytes += jp->j_bytes; 35617829Sralph return(1); 35717829Sralph } 35817829Sralph 35917829Sralph struct sys * 36017829Sralph getsys(s) 36117829Sralph register char *s; 36217829Sralph { 36317829Sralph register struct sys *sp; 36417829Sralph 36517829Sralph for (sp = syshead; sp; sp = sp->s_sysp) 36617829Sralph if (strcmp(s, sp->s_name) == 0) 36717829Sralph return(sp); 36817829Sralph if (sysname && !prefix(sysname, s)) 36917829Sralph return(NOSYS); 37017829Sralph sp = (struct sys *)malloc(sizeof(struct sys)); 37117829Sralph if (sp == NOSYS) 37217829Sralph return(NOSYS); 37317829Sralph strcpy(sp->s_name, s); 37417829Sralph sp->s_njobs = 0; 37517829Sralph sp->s_jobp = (struct job *)0; 37617829Sralph sp->s_sysp = syshead; 37717829Sralph sp->s_bytes = 0; 37817829Sralph syshead = sp; 37917829Sralph return(sp); 38017829Sralph } 381