home *** CD-ROM | disk | FTP | other *** search
- From: allbery@ncoast.UUCP (Brandon S. Allbery)
- Newsgroups: comp.sources.misc
- Subject: uul -- list uucp systems with jobs pending
- Message-ID: <3638@ncoast.UUCP>
- Date: 26 Jul 87 23:37:33 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Cleveland Public Access UN*X, Cleveland, Oh
- Lines: 302
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8707/63
-
- 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.<sysname><jobname>
-
- The #define JOBNLEN specifies the length of the <jobname> 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 <sysname> 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.<localsysname>, 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.<sysname>". 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 <stdio.h>
- #include <ctype.h>
- #include <varargs.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ndir.h>
-
- #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
- <<ncoast Public Access UNIX: +1 216 781 6201 24hrs. 300/1200/2400 baud>>
-