From ncr-sd!hp-sdd!hplabs!sri-unix!husc6!necntc!ncoast!allbery Mon Jul 27 02:45:41 PDT 1987 The following is a quick utility to list systems with UUCP jobs pending. It is (sort of) a successor to the uuque I hacked up in C from the original shell script; it stands a chance of being more portable. It presently doesn't take any options. There also isn't a makefile or man page. Sample output: System Files Send Recv Exec Size Status ---------------------------------------------------------------------- cwruecm 4 4 0 0 7K Aborted (dial failed) cbosgd 2 2 0 0 1K Last poll successful hal 30 30 0 0 160K Aborted (conversation) hnsurg3 22 22 0 0 465K Last poll successful peng 8 8 0 0 35K Last poll successful devon 10 10 0 0 230K Last poll successful ---------------------------------------------------------------------- TOTAL 76 898K for 6 system(s) Compiling/installation: The only system dependencies should be in the UUCP files/directories themsel- ves. The program doesn't use strchr()/index()/foobar()/whatever-its-called- this-week(). It uses the Berkeley directory routines, but PD versions of these are distributed with B news for those not running Berkeley UN*X. Most of the UUCP configuration is in #defines at the beginning of the pro- gram. They are: UUCPDIR -- shouldn't need changing. This is the name of the UUCP spool directory. /usr/spool/uucp is the default. L_SYS -- the name of the systems file. HoneyDanBer uses /usr/lib/uucp/Systems; others use /usr/lib/uucp/L.sys. JOBNLEN -- When a UUCP job is queued, it is stored in a file named: C. The #define JOBNLEN specifies the length of the component; for most of the uucp's I've used, this is 5. MAXSYSLEN -- The number of significant characters in a system name. Also the maximum length of the component of a job file name. For V7, Xenix 3, and BSD4.2, this is 7; for HoneyDanBer and non-HDB System V, this is 6; I haven't the faintest what 4.3BSD uses. UUSUBDIRS -- If this is #defined, then the UUCP spool directory is assumed to use subdirectories C., D., D., etc. For BSD UUCP's only; undefine for V7, System III, System V, HDB(?). UUSTST(s) -- The name of the STST file for system s. For most UUCP's, the default will do. I understand that some non-flat systems (4.3BSD?) have an STST. subdirectory; if this is so, change the define to: #define UUSTST(s) _catstr(UUCPDIR, "/STST./STST.", s, (char *) 0) UULOCK(s) -- Like UUSTST(s), but returns the name of the system lock file. Again, this is set correctly unless you have an LCK. subdirectory. UUCPCMD -- This is an fscanf() string which extracts the command and data file name from a UUCP job file (C.system...). It should return two strings: the first is the command, the second is the data file name and is assumed to not be a pathname, just a basename. The default is valid for 4.2BSD UUCP. I haven't checked what System V uses and I don't have HoneyDanBer. LOCALDIR -- If UUSUBDIRS is defined, then LOCALDIR must be set to the basename of the local UUCP data file directory, "D.". Alternatively, it could be changed to get the local system name from somewhere else dynamically, but my experience with grabbing local system names indicates that hardcoding the name is probably the most portable way available. (Sigh.) The only other spot that might cause problems is the format of an STST. file. I have the 4.2BSD format hardcoded; unfortunately, the code is nontrivial compared to that for parsing UUCP job files. I'd appreciate information on what format other UUCPs use. The L_SYS file is assumed to have the system name as the first non-whitespace on a line; blank lines and lines whose first nonspace character is '#' are skipped. Consecutive duplicate system names (for alternate speeds or phone numbers, etc.) are folded to a single output line, but _non_consecutive dupli- cate lines are not caught. This program uses varargs in one routine, _catstr(), a function which concat- enates a series of string arguments (terminated by (char *) 0) into a static string, then returns a pointer to the string. This is used to construct path names for UUCP files in various ways, depending on whether UUSUBDIRS is defined or not. The usage is fairly vanilla and conforms to the standard insofar as I know it: the function declaration is _catstr(va_alist) and the va_start and va_end macros are matched in the code; and all arguments retrieved are the same size, sizeof (char *), and terminated with (char *) 0. I've also made an attempt to avoid problems with portability to machines where sizeof (int) != sizeof (char *) or sizeof (long) or both; all NULLs are explicitly cast to the correct type, and the only ints are used to collect file sizes in Kunits (a "unit" being whatever the basic unit of (struct stat).st_size is, generally an 8-bit byte but who knows what the DEC-20 uses). If someone has more than 32767K queued for a system or total, they probably have worse problems than uul not working right! To compile: set up the UUCP parameters described above to the correct values, then type "cc -O -o uul uul.c". Append -lndir if you're not running Berkeley UN*X. (If you didn't install ndir in your system library directory, do so; it's a wonderful portability aid!) The executable must be chown'ed to the owner of uucico (usually uucp or uucputl; at least one system I know of requires setuid _root_) and made setuid. This is safe, as all files are opened for read and only job files and STST. files are read; data files are only stat'ed. On ncoast, I find uul invaluable for tracking uucp spool size. (I discovered some major problems recently involving some local systems queueing 1500K each and not picking their files up!) Hopefully, others will find it useful; and hopefully others will be able to use it no matter what flavor UUCP they run. (Please mail configuration information for your version of UUCP to me; include the system type, OS type, and UUCP type. I'll fold this into a makefile which will attempt to autoconfigure uul and send it out with any revisions I make.) Cut at the dotted line and save to a file. (WARNING: IT'S NOT A SHAR!) =============================================================================== #include #include #include #include #include #include #define UUCPDIR "/usr/spool/uucp" #define L_SYS "/usr/lib/uucp/L.sys" /* for HDB, change the above to /usr/lib/uucp/Systems */ #define JOBNLEN 5 /* this is the number of characters tacked onto a file name, the job # */ #define MAXSYSLEN 7 /* the maximum number of characters allowed in a UUCP name, 6 for sys5 */ #define UUSUBDIRS /* do not define this for flat-directory UUCP's! */ #define UUSTST(s) _catstr(UUCPDIR, "/STST.", s, (char *) 0) /* for 4.3BSD UUCP this may be STST./STST.sysname */ #define UULOCK(s) _catstr(UUCPDIR, "/LCK..", s, (char *) 0) /* for 4.3BSD UUCP this may be LCK./LCK..sysname */ #define UUCPCMD "%s %s %*s %*s %*s %*s %*s" /* fscanf() format for UUCP command files (C.xxx) - arg 1 = S or R, */ /* arg 2 is filename on local system. The above is for 4.2BSD uucp. */ #ifdef UUSUBDIRS #define UUPATH(c,f) _catstr(UUCPDIR, "/", c, "/", f, (char *) 0) #define UUDIR(d) _catstr(UUCPDIR, "/", d, (char *) 0) #define LOCALDIR "D.ncoast" #else #define UUPATH(c,f) _catstr(UUCPDIR, "/", f, (char *) 0) #define UUDIR(d) UUCPDIR #define LOCALDIR "" #endif static char *_catstr(va_alist) va_dcl { static char buf[5120]; char *cp, *bp; va_list args; va_start(args); bp = buf; while ((cp = va_arg(args, char *)) != (char *) 0) while (*cp != '\0') *bp++ = *cp++; *bp = '\0'; va_end(args); return buf; } lsys(sys, nf, nk) int *nf, *nk; char *sys; { DIR *dp; struct direct *uuf; int len, n, files, blocks, nsend, nrec, nexec; char dname[256], cmd[16]; FILE *fp; struct stat st; blocks = 0; files = 0; nsend = 0; nrec = 0; nexec = 0; if ((dp = opendir(UUDIR("C."))) == (DIR *) 0) { perror(UUDIR("C.")); exit(1); } while ((uuf = readdir(dp)) != (struct direct *) 0) { if (strncmp(uuf->d_name, "C.", 2) != 0) continue; len = strlen(uuf->d_name) - JOBNLEN; for (n = 2; n < len; n++) dname[n - 2] = uuf->d_name[n]; dname[n - 2] = '\0'; if (strcmp(dname, sys) != 0) continue; if ((fp = fopen(UUPATH("C.", uuf->d_name), "r")) == (FILE *) 0) { perror(UUPATH("C.", uuf->d_name)); continue; } while (fscanf(fp, UUCPCMD, cmd, dname) == 2) { files++; switch (*cmd) { case 'S': nsend++; break; case 'R': nrec++; continue; } if (stat(UUPATH(LOCALDIR, dname), &st) < 0) continue; blocks += (st.st_size + 1023) / 1024; } fclose(fp); } closedir(dp); if ((dp = opendir(UUDIR("X."))) == (DIR *) 0) { perror(UUDIR("X.")); exit(1); } while ((uuf = readdir(dp)) != (struct direct *) 0) { if (strncmp(uuf->d_name, "X.", 2) != 0) continue; len = strlen(uuf->d_name) - JOBNLEN; for (n = 2; n < len; n++) dname[n - 2] = uuf->d_name[n]; dname[n - 2] = '\0'; if (strcmp(dname, sys) != 0) continue; files++; nexec++; } closedir(dp); *nf = files; *nk = blocks; if (files == 0) return; printf("%-16s %5d %5d %5d %5d %5dK ", sys, files, nsend, nrec, nexec, blocks); if ((fp = fopen(UUSTST(sys), "r")) == (FILE *) 0) printf("Last poll successful\n"); else { if (stat(UULOCK(sys), &st) < 0) printf("Aborted"); else printf("Connected"); if (fgets(dname, sizeof dname, fp) == (char *) 0) printf(" (reason unknown)\n"); else { for (len = strlen(dname) - 1; dname[len] != ' '; len--) ; dname[len] = '\0'; printf(" ("); for (n = 0, len = 0; dname[len] != ' ' || ++n < 4; len++) ; while (dname[++len] != '\0') putchar(tolower(dname[len])); printf(")\n"); } fclose(fp); } } main() { FILE *fp; char sys[1024], sysname[132], lastsys[132]; int nf, nk, files, blocks, nsys; if ((fp = fopen(L_SYS, "r")) == (FILE *) 0) { perror(L_SYS); exit(1); } printf("System Files Send Recv Exec Size Status\n"); printf("----------------------------------------------------------------------\n"); nsys = 0; lastsys[0] = '\0'; while (fgets(sys, sizeof sys, fp) != (char *) 0) { if (sscanf(sys, "%s", sysname) == 0) continue; sysname[MAXSYSLEN] = '\0'; if (sysname[0] == '#') continue; if (strcmp(sysname, lastsys) == 0) continue; lsys(sysname, &nf, &nk); files += nf; blocks += nk; if (nf != 0) nsys++; strcpy(lastsys, sysname); } if (nsys != 0) printf("----------------------------------------------------------------------\n"); printf("TOTAL %5d %5dK for %d system(s)\n", files, blocks, nsys); exit(0); } -- Brandon S. Allbery, moderator of comp.sources.misc and comp.binaries.ibm.pc {{harvard,mit-eddie}!necntc,well!hoptoad,sun!cwruecmp!hal}!ncoast!allbery ARPA: necntc!ncoast!allbery@harvard.harvard.edu Fido: 157/502 MCI: BALLBERY <>