1*17829Sralph #ifndef lint 2*17829Sralph static char sccsid[] = "@(#)uuq.c 4.1 (Berkeley) 01/22/85"; 3*17829Sralph #endif 4*17829Sralph 5*17829Sralph /* 6*17829Sralph * uuq - looks at uucp queues 7*17829Sralph * 8*17829Sralph * Lou Salkind 9*17829Sralph * New York University 10*17829Sralph * 11*17829Sralph */ 12*17829Sralph 13*17829Sralph #include "uucp.h" 14*17829Sralph #include <stdio.h> 15*17829Sralph #include <sys/types.h> 16*17829Sralph 17*17829Sralph #ifdef NDIR 18*17829Sralph #include "libndir/ndir.h" 19*17829Sralph #else !NDIR 20*17829Sralph #include <sys/dir.h> 21*17829Sralph #endif !NDIR 22*17829Sralph #include <sys/stat.h> 23*17829Sralph 24*17829Sralph #define NOSYS (struct sys *)0 25*17829Sralph 26*17829Sralph #define W_TYPE wrkvec[0] 27*17829Sralph #define W_FILE1 wrkvec[1] 28*17829Sralph #define W_FILE2 wrkvec[2] 29*17829Sralph #define W_USER wrkvec[3] 30*17829Sralph #define W_OPTNS wrkvec[4] 31*17829Sralph #define W_DFILE wrkvec[5] 32*17829Sralph #define W_MODE wrkvec[6] 33*17829Sralph #define WSUFSIZE 5 /* work file name suffix size */ 34*17829Sralph 35*17829Sralph struct sys { 36*17829Sralph char s_name[8]; 37*17829Sralph int s_njobs; 38*17829Sralph off_t s_bytes; 39*17829Sralph struct job *s_jobp; 40*17829Sralph struct sys *s_sysp; 41*17829Sralph }; 42*17829Sralph 43*17829Sralph struct job { 44*17829Sralph int j_files; 45*17829Sralph int j_flags; 46*17829Sralph char j_jobno[WSUFSIZE]; 47*17829Sralph char j_user[22]; 48*17829Sralph char j_fname[128]; 49*17829Sralph char j_grade; 50*17829Sralph off_t j_bytes; 51*17829Sralph time_t j_date; 52*17829Sralph struct job *j_jobp; 53*17829Sralph }; 54*17829Sralph 55*17829Sralph struct sys *syshead; 56*17829Sralph struct sys *getsys(); 57*17829Sralph int jcompare(); 58*17829Sralph char *sysname; 59*17829Sralph char *user; 60*17829Sralph char *rmjob; 61*17829Sralph int hflag; 62*17829Sralph int lflag; 63*17829Sralph 64*17829Sralph char *malloc(), *calloc(); 65*17829Sralph float atof(); 66*17829Sralph float baudrate = 800.; 67*17829Sralph char Username[BUFSIZ]; 68*17829Sralph char Filename[BUFSIZ]; 69*17829Sralph int Maxulen = 0; 70*17829Sralph 71*17829Sralph main(argc, argv) 72*17829Sralph char **argv; 73*17829Sralph { 74*17829Sralph register i; 75*17829Sralph register struct sys *sp; 76*17829Sralph register struct job *jp; 77*17829Sralph struct job **sortjob; 78*17829Sralph int nsys; 79*17829Sralph 80*17829Sralph strcpy(Progname, "uuq"); 81*17829Sralph uucpname(Myname); 82*17829Sralph 83*17829Sralph while (--argc > 0) { 84*17829Sralph argv++; 85*17829Sralph if (argv[0][0] == '-') switch (argv[0][1]) { 86*17829Sralph case 'r': 87*17829Sralph Spool = &argv[0][2]; 88*17829Sralph break; 89*17829Sralph case 's': 90*17829Sralph sysname = &argv[0][2]; 91*17829Sralph if (strlen(sysname) > 7) 92*17829Sralph sysname[7] = '\0'; 93*17829Sralph break; 94*17829Sralph case 'u': 95*17829Sralph user = &argv[0][2]; 96*17829Sralph break; 97*17829Sralph case 'd': 98*17829Sralph rmjob = &argv[0][2]; 99*17829Sralph break; 100*17829Sralph case 'b': 101*17829Sralph baudrate = atof(&argv[0][2]); 102*17829Sralph break; 103*17829Sralph case 'h': 104*17829Sralph hflag++; 105*17829Sralph break; 106*17829Sralph case 'l': 107*17829Sralph lflag++; 108*17829Sralph break; 109*17829Sralph default: 110*17829Sralph fprintf(stderr, 111*17829Sralph "usage: uuq [-l] [-h] [-ssystem] [-uuser] [-djobno] [-rspool] [-bbaudrate]\n"); 112*17829Sralph exit(0); 113*17829Sralph } 114*17829Sralph } 115*17829Sralph 116*17829Sralph subchdir(Spool); 117*17829Sralph baudrate *= 6.; /* convert to chars/minute */ 118*17829Sralph gather(); 119*17829Sralph nsys = 0; 120*17829Sralph for (sp = syshead; sp; sp = sp->s_sysp) { 121*17829Sralph if (sp->s_njobs == 0) 122*17829Sralph continue; 123*17829Sralph if (!hflag && nsys++ > 0) 124*17829Sralph putchar('\n'); 125*17829Sralph printf("%s: %d %s", sp->s_name, 126*17829Sralph sp->s_njobs, sp->s_njobs > 1 ? "jobs" : "job"); 127*17829Sralph if (lflag) { 128*17829Sralph float minutes; 129*17829Sralph int hours; 130*17829Sralph /* The 80 * njobs is because of the uucp handshaking */ 131*17829Sralph minutes = (float)(sp->s_bytes + 80 * sp->s_njobs)/baudrate; 132*17829Sralph hours = minutes/60; 133*17829Sralph printf(", %d bytes, ", sp->s_bytes); 134*17829Sralph if (minutes > 60){ 135*17829Sralph printf("%d hour%s, ",hours, 136*17829Sralph hours > 1 ? "s": ""); 137*17829Sralph minutes -= 60 * hours; 138*17829Sralph } 139*17829Sralph printf("%3.1f minutes (@ %d baud)",minutes,(int)baudrate/6); 140*17829Sralph } 141*17829Sralph putchar('\n'); 142*17829Sralph if (hflag) 143*17829Sralph continue; 144*17829Sralph /* sort them babies! */ 145*17829Sralph sortjob = (struct job **)calloc(sp->s_njobs, sizeof (struct job 146*17829Sralph *)); 147*17829Sralph for (i=0, jp=sp->s_jobp; i < sp->s_njobs; i++, jp=jp->j_jobp) 148*17829Sralph sortjob[i] = jp; 149*17829Sralph qsort(sortjob, sp->s_njobs, sizeof (struct job *), jcompare); 150*17829Sralph for (i = 0; i < sp->s_njobs; i++) { 151*17829Sralph jp = sortjob[i]; 152*17829Sralph if (lflag) { 153*17829Sralph printf("%s %2d %-*s%7d%5.1f %-12.12s %c %.*s\n", 154*17829Sralph jp->j_jobno, jp->j_files, Maxulen, jp->j_user, jp->j_bytes, jp->j_bytes/baudrate, 155*17829Sralph ctime(&jp->j_date) + 4, jp->j_flags, sizeof (jp->j_fname), jp->j_fname 156*17829Sralph ); 157*17829Sralph } else { 158*17829Sralph printf("%s", jp->j_jobno); 159*17829Sralph putchar((i+1)%10 ? '\t' : '\n'); 160*17829Sralph } 161*17829Sralph /* There's no need to keep the force poll if jobs > 1*/ 162*17829Sralph if (sp->s_njobs > 1 && strcmp("POLL", jp->j_jobno)==0) { 163*17829Sralph char pbuf[BUFSIZ]; 164*17829Sralph sprintf(pbuf,"%s/%c.%szPOLL", subdir(Spool, CMDPRE), CMDPRE,sp->s_name); 165*17829Sralph unlink(pbuf); 166*17829Sralph } 167*17829Sralph } 168*17829Sralph if (!lflag && (sp->s_njobs%10)) 169*17829Sralph putchar('\n'); 170*17829Sralph } 171*17829Sralph exit(0); 172*17829Sralph } 173*17829Sralph 174*17829Sralph jcompare(j1, j2) 175*17829Sralph struct job **j1, **j2; 176*17829Sralph { 177*17829Sralph int delta; 178*17829Sralph 179*17829Sralph delta = (*j1)->j_grade - (*j2)->j_grade; 180*17829Sralph if (delta) 181*17829Sralph return delta; 182*17829Sralph return(strcmp((*j1)->j_jobno,(*j2)->j_jobno)); 183*17829Sralph } 184*17829Sralph 185*17829Sralph /* 186*17829Sralph * Get all the command file names 187*17829Sralph */ 188*17829Sralph gather() 189*17829Sralph { 190*17829Sralph struct direct *d; 191*17829Sralph DIR *df; 192*17829Sralph 193*17829Sralph /* 194*17829Sralph * Find all the spool files in the spooling directory 195*17829Sralph */ 196*17829Sralph if ((df = opendir(subdir(Spool, CMDPRE))) == NULL) { 197*17829Sralph fprintf(stderr, "can't examine spooling area"); 198*17829Sralph exit(1); 199*17829Sralph } 200*17829Sralph for (;;) { 201*17829Sralph if ((d = readdir(df)) == NULL) 202*17829Sralph break; 203*17829Sralph if (d->d_namlen <= 2 || d->d_name[0] != CMDPRE || 204*17829Sralph d->d_name[1] != '.') 205*17829Sralph continue; 206*17829Sralph if (analjob(d->d_name) < 0) { 207*17829Sralph fprintf(stderr, "out of memory\n"); 208*17829Sralph break; 209*17829Sralph } 210*17829Sralph } 211*17829Sralph closedir(df); 212*17829Sralph } 213*17829Sralph 214*17829Sralph /* 215*17829Sralph * analjob does the grunge work of verifying jobs 216*17829Sralph */ 217*17829Sralph analjob(filename) 218*17829Sralph char *filename; 219*17829Sralph { 220*17829Sralph struct job *jp; 221*17829Sralph struct sys *sp; 222*17829Sralph char sbuf[MAXNAMLEN+1], str[256], nbuf[256]; 223*17829Sralph char *jptr, *wrkvec[20]; 224*17829Sralph char grade; 225*17829Sralph FILE *fp, *df; 226*17829Sralph struct stat statb; 227*17829Sralph int files, gotname, i; 228*17829Sralph off_t bytes; 229*17829Sralph 230*17829Sralph strncpy(sbuf, filename, MAXNAMLEN); 231*17829Sralph sbuf[MAXNAMLEN] = '\0'; 232*17829Sralph jptr = sbuf + strlen(sbuf) - WSUFSIZE; 233*17829Sralph grade = *jptr; 234*17829Sralph *jptr++ = 0; 235*17829Sralph /* 236*17829Sralph * sbuf+2 now points to sysname name (null terminated) 237*17829Sralph * jptr now points to job number (null terminated) 238*17829Sralph */ 239*17829Sralph if (rmjob) { 240*17829Sralph if (strcmp(rmjob, jptr)) 241*17829Sralph return(0); 242*17829Sralph } else { 243*17829Sralph if ((sp = getsys(sbuf+2)) == NOSYS) 244*17829Sralph return(0); 245*17829Sralph if (!lflag) { 246*17829Sralph /* SHOULD USE A SMALLER STRUCTURE HERE */ 247*17829Sralph jp = (struct job *)malloc(sizeof(struct job)); 248*17829Sralph if (jp == (struct job *)0) 249*17829Sralph return(-1); 250*17829Sralph strcpy(jp->j_jobno, jptr); 251*17829Sralph jp->j_jobp = sp->s_jobp; 252*17829Sralph jp->j_grade = grade; 253*17829Sralph sp->s_jobp = jp; 254*17829Sralph sp->s_njobs++; 255*17829Sralph return(1); 256*17829Sralph } 257*17829Sralph } 258*17829Sralph if ((fp = fopen(subfile(filename), "r")) == NULL) { 259*17829Sralph perror(subfile(filename)); 260*17829Sralph return(0); 261*17829Sralph } 262*17829Sralph files = 0; 263*17829Sralph bytes = 0; 264*17829Sralph gotname = 0; 265*17829Sralph while (fgets(str, sizeof str, fp)) { 266*17829Sralph if (getargs(str, wrkvec, 20) <= 0) 267*17829Sralph continue; 268*17829Sralph if (rmjob) { 269*17829Sralph if (W_TYPE[0] == 'S' && !index(W_OPTNS, 'c')) { 270*17829Sralph unlink(subfile(W_DFILE)); 271*17829Sralph fprintf(stderr, "Removing data file %s\n", W_DFILE); 272*17829Sralph } 273*17829Sralph continue; 274*17829Sralph } 275*17829Sralph if (user && (W_TYPE[0] == 'X' || !prefix(user, W_USER))) { 276*17829Sralph fclose(fp); 277*17829Sralph return(0); 278*17829Sralph } 279*17829Sralph files++; 280*17829Sralph if (W_TYPE[0] == 'S') { 281*17829Sralph if (strcmp(W_DFILE, "D.0") && 282*17829Sralph stat(subfile(W_DFILE), &statb) >= 0) 283*17829Sralph bytes += statb.st_size; 284*17829Sralph else if (stat(subfile(W_FILE1), &statb) >= 0) 285*17829Sralph bytes += statb.st_size; 286*17829Sralph } 287*17829Sralph /* amusing heuristic */ 288*17829Sralph #define isXfile(s) (s[0]=='D' && s[strlen(s)-WSUFSIZE]=='X') 289*17829Sralph if (gotname == 0 && isXfile(W_FILE1)) { 290*17829Sralph if ((df = fopen(subfile(W_FILE1), "r")) == NULL) 291*17829Sralph continue; 292*17829Sralph while (fgets(nbuf, sizeof nbuf, df)) { 293*17829Sralph nbuf[strlen(nbuf) - 1] = '\0'; 294*17829Sralph if (nbuf[0] == 'C' && nbuf[1] == ' ') { 295*17829Sralph strcpy(Filename, nbuf+2); 296*17829Sralph gotname++; 297*17829Sralph } else if (nbuf[0] == 'R' && nbuf[1] == ' ') { 298*17829Sralph register char *p, *q, *r; 299*17829Sralph r = q = p = nbuf+2; 300*17829Sralph do { 301*17829Sralph if (*p == '!' || *p == '@'){ 302*17829Sralph r = q; 303*17829Sralph q = p+1; 304*17829Sralph } 305*17829Sralph } while (*p++); 306*17829Sralph 307*17829Sralph strcpy(Username, r); 308*17829Sralph W_USER = Username; 309*17829Sralph } 310*17829Sralph } 311*17829Sralph fclose(df); 312*17829Sralph } 313*17829Sralph } 314*17829Sralph fclose(fp); 315*17829Sralph if (rmjob) { 316*17829Sralph unlink(subfile(filename)); 317*17829Sralph fprintf(stderr, "Removing command file %s\n", filename); 318*17829Sralph exit(0); 319*17829Sralph } 320*17829Sralph if (files == 0) { 321*17829Sralph static char *wtype = "X"; 322*17829Sralph static char *wfile = "forced poll"; 323*17829Sralph if (strcmp("POLL", &filename[strlen(filename)-4])) { 324*17829Sralph fprintf(stderr, "%.14s: empty command file\n", filename); 325*17829Sralph return(0); 326*17829Sralph } 327*17829Sralph W_TYPE = wtype; 328*17829Sralph W_FILE1 = wfile; 329*17829Sralph } 330*17829Sralph jp = (struct job *)malloc(sizeof(struct job)); 331*17829Sralph if (jp == (struct job *)0) 332*17829Sralph return(-1); 333*17829Sralph strcpy(jp->j_jobno, jptr); 334*17829Sralph jp->j_files = files; 335*17829Sralph jp->j_bytes = bytes; 336*17829Sralph jp->j_grade = grade; 337*17829Sralph jp->j_flags = W_TYPE[0]; 338*17829Sralph strncpy(jp->j_user, W_TYPE[0]=='X' ? "---" : W_USER, 20 ); 339*17829Sralph jp->j_user[20] = '\0'; 340*17829Sralph i = strlen(jp->j_user); 341*17829Sralph if (i > Maxulen) 342*17829Sralph Maxulen = i; 343*17829Sralph /* SHOULD ADD ALL INFORMATION IN THE WHILE LOOP */ 344*17829Sralph if (gotname) 345*17829Sralph strncpy(jp->j_fname, Filename, sizeof jp->j_fname); 346*17829Sralph else 347*17829Sralph strncpy(jp->j_fname, W_FILE1, sizeof jp->j_fname); 348*17829Sralph stat(subfile(filename), &statb); 349*17829Sralph jp->j_date = statb.st_mtime; 350*17829Sralph jp->j_jobp = sp->s_jobp; 351*17829Sralph sp->s_jobp = jp; 352*17829Sralph sp->s_njobs++; 353*17829Sralph sp->s_bytes += jp->j_bytes; 354*17829Sralph return(1); 355*17829Sralph } 356*17829Sralph 357*17829Sralph struct sys * 358*17829Sralph getsys(s) 359*17829Sralph register char *s; 360*17829Sralph { 361*17829Sralph register struct sys *sp; 362*17829Sralph 363*17829Sralph for (sp = syshead; sp; sp = sp->s_sysp) 364*17829Sralph if (strcmp(s, sp->s_name) == 0) 365*17829Sralph return(sp); 366*17829Sralph if (sysname && !prefix(sysname, s)) 367*17829Sralph return(NOSYS); 368*17829Sralph sp = (struct sys *)malloc(sizeof(struct sys)); 369*17829Sralph if (sp == NOSYS) 370*17829Sralph return(NOSYS); 371*17829Sralph strcpy(sp->s_name, s); 372*17829Sralph sp->s_njobs = 0; 373*17829Sralph sp->s_jobp = (struct job *)0; 374*17829Sralph sp->s_sysp = syshead; 375*17829Sralph sp->s_bytes = 0; 376*17829Sralph syshead = sp; 377*17829Sralph return(sp); 378*17829Sralph } 379