home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8707 / 63 < prev    next >
Encoding:
Internet Message Format  |  1990-07-13  |  11.3 KB

  1. From: allbery@ncoast.UUCP (Brandon S. Allbery)
  2. Newsgroups: comp.sources.misc
  3. Subject: uul -- list uucp systems with jobs pending
  4. Message-ID: <3638@ncoast.UUCP>
  5. Date: 26 Jul 87 23:37:33 GMT
  6. Sender: allbery@ncoast.UUCP
  7. Organization: Cleveland Public Access UN*X, Cleveland, Oh
  8. Lines: 302
  9. Approved: allbery@ncoast.UUCP
  10. X-Archive: comp.sources.misc/8707/63
  11.  
  12. The following is a quick utility to list systems with UUCP jobs pending.  It
  13. is (sort of) a successor to the uuque I hacked up in C from the original shell
  14. script; it stands a chance of being more portable.  It presently doesn't take
  15. any options.  There also isn't a makefile or man page.
  16.  
  17. Sample output:
  18.  
  19. System           Files  Send  Recv  Exec   Size Status
  20. ----------------------------------------------------------------------
  21. cwruecm              4     4     0     0     7K Aborted (dial failed)
  22. cbosgd               2     2     0     0     1K Last poll successful
  23. hal                 30    30     0     0   160K Aborted (conversation)
  24. hnsurg3             22    22     0     0   465K Last poll successful
  25. peng                 8     8     0     0    35K Last poll successful
  26. devon               10    10     0     0   230K Last poll successful
  27. ----------------------------------------------------------------------
  28. TOTAL               76                     898K for 6 system(s)
  29.  
  30. Compiling/installation:
  31.  
  32. The only system dependencies should be in the UUCP files/directories themsel-
  33. ves.  The program doesn't use strchr()/index()/foobar()/whatever-its-called-
  34. this-week().  It uses the Berkeley directory routines, but PD versions of
  35. these are distributed with B news for those not running Berkeley UN*X.
  36.  
  37. Most of the UUCP configuration is in #defines at the beginning of the pro-
  38. gram.  They are:
  39.  
  40. UUCPDIR -- shouldn't need changing.  This is the name of the UUCP spool
  41. directory.  /usr/spool/uucp is the default.
  42.  
  43. L_SYS -- the name of the systems file.  HoneyDanBer uses /usr/lib/uucp/Systems;
  44. others use /usr/lib/uucp/L.sys.
  45.  
  46. JOBNLEN -- When a UUCP job is queued, it is stored in a file named:
  47.  
  48.     C.<sysname><jobname>
  49.  
  50. The #define JOBNLEN specifies the length of the <jobname> component; for most
  51. of the uucp's I've used, this is 5.
  52.  
  53. MAXSYSLEN -- The number of significant characters in a system name.  Also the
  54. maximum length of the <sysname> component of a job file name.  For V7, Xenix 3,
  55. and BSD4.2, this is 7; for HoneyDanBer and non-HDB System V, this is 6; I
  56. haven't the faintest what 4.3BSD uses.
  57.  
  58. UUSUBDIRS -- If this is #defined, then the UUCP spool directory is assumed to
  59. use subdirectories C., D., D.<localsysname>, etc.  For BSD UUCP's only;
  60. undefine for V7, System III, System V, HDB(?).
  61.  
  62. UUSTST(s) -- The name of the STST file for system s.  For most UUCP's, the
  63. default will do.  I understand that some non-flat systems (4.3BSD?) have an
  64. STST. subdirectory; if this is so, change the define to:
  65.  
  66.     #define UUSTST(s) _catstr(UUCPDIR, "/STST./STST.", s, (char *) 0)
  67.  
  68. UULOCK(s) -- Like UUSTST(s), but returns the name of the system lock file.
  69. Again, this is set correctly unless you have an LCK. subdirectory.
  70.  
  71. UUCPCMD -- This is an fscanf() string which extracts the command and data
  72. file name from a UUCP job file (C.system...).  It should return two strings:
  73. the first is the command, the second is the data file name and is assumed to
  74. not be a pathname, just a basename.  The default is valid for 4.2BSD UUCP.
  75. I haven't checked what System V uses and I don't have HoneyDanBer.
  76.  
  77. LOCALDIR -- If UUSUBDIRS is defined, then LOCALDIR must be set to the basename
  78. of the local UUCP data file directory, "D.<sysname>".  Alternatively, it
  79. could be changed to get the local system name from somewhere else dynamically,
  80. but my experience with grabbing local system names indicates that hardcoding
  81. the name is probably the most portable way available.  (Sigh.)
  82.  
  83. The only other spot that might cause problems is the format of an STST. file.
  84. I have the 4.2BSD format hardcoded; unfortunately, the code is nontrivial
  85. compared to that for parsing UUCP job files.  I'd appreciate information
  86. on what format other UUCPs use.
  87.  
  88. The L_SYS file is assumed to have the system name as the first non-whitespace
  89. on a line; blank lines and lines whose first nonspace character is '#' are
  90. skipped.  Consecutive duplicate system names (for alternate speeds or phone
  91. numbers, etc.) are folded to a single output line, but _non_consecutive dupli-
  92. cate lines are not caught.
  93.  
  94. This program uses varargs in one routine, _catstr(), a function which concat-
  95. enates a series of string arguments (terminated by (char *) 0) into a static
  96. string, then returns a pointer to the string.  This is used to construct path
  97. names for UUCP files in various ways, depending on whether UUSUBDIRS is defined
  98. or not.  The usage is fairly vanilla and conforms to the standard insofar as
  99. I know it:  the function declaration is _catstr(va_alist) and the va_start
  100. and va_end macros are matched in the code; and all arguments retrieved are the
  101. same size, sizeof (char *), and terminated with (char *) 0.  I've also made an
  102. attempt to avoid problems with portability to machines where sizeof (int) !=
  103. sizeof (char *) or sizeof (long) or both; all NULLs are explicitly cast to
  104. the correct type, and the only ints are used to collect file sizes in Kunits
  105. (a "unit" being whatever the basic unit of (struct stat).st_size is, generally
  106. an 8-bit byte but who knows what the DEC-20 uses).  If someone has more than
  107. 32767K queued for a system or total, they probably have worse problems than
  108. uul not working right!
  109.  
  110. To compile:  set up the UUCP parameters described above to the correct values,
  111. then type "cc -O -o uul uul.c".  Append -lndir if you're not running Berkeley
  112. UN*X.  (If you didn't install ndir in your system library directory, do so;
  113. it's a wonderful portability aid!)
  114.  
  115. The executable must be chown'ed to the owner of uucico (usually uucp or
  116. uucputl; at least one system I know of requires setuid _root_) and made
  117. setuid.  This is safe, as all files are opened for read and only job files
  118. and STST. files are read; data files are only stat'ed.
  119.  
  120. On ncoast, I find uul invaluable for tracking uucp spool size.  (I discovered
  121. some major problems recently involving some local systems queueing 1500K each
  122. and not picking their files up!)  Hopefully, others will find it useful; and
  123. hopefully others will be able to use it no matter what flavor UUCP they run.
  124. (Please mail configuration information for your version of UUCP to me; include
  125. the system type, OS type, and UUCP type.  I'll fold this into a makefile which
  126. will attempt to autoconfigure uul and send it out with any revisions I make.)
  127.  
  128. Cut at the dotted line and save to a file.  (WARNING:  IT'S NOT A SHAR!)
  129.  
  130. ===============================================================================
  131. #include <stdio.h>
  132. #include <ctype.h>
  133. #include <varargs.h>
  134. #include <sys/types.h>
  135. #include <sys/stat.h>
  136. #include <ndir.h>
  137.  
  138. #define UUCPDIR        "/usr/spool/uucp"
  139. #define L_SYS        "/usr/lib/uucp/L.sys"
  140. /* for HDB, change the above to /usr/lib/uucp/Systems */
  141. #define JOBNLEN        5
  142. /* this is the number of characters tacked onto a file name, the job # */
  143. #define MAXSYSLEN    7
  144. /* the maximum number of characters allowed in a UUCP name, 6 for sys5 */
  145. #define UUSUBDIRS
  146. /* do not define this for flat-directory UUCP's! */
  147. #define UUSTST(s)    _catstr(UUCPDIR, "/STST.", s, (char *) 0)
  148. /* for 4.3BSD UUCP this may be STST./STST.sysname */
  149. #define UULOCK(s)    _catstr(UUCPDIR, "/LCK..", s, (char *) 0)
  150. /* for 4.3BSD UUCP this may be LCK./LCK..sysname */
  151. #define UUCPCMD        "%s %s %*s %*s %*s %*s %*s"
  152. /* fscanf() format for UUCP command files (C.xxx) - arg 1 = S or R, */
  153. /* arg 2 is filename on local system.  The above is for 4.2BSD uucp. */
  154.  
  155. #ifdef UUSUBDIRS
  156. #define UUPATH(c,f)    _catstr(UUCPDIR, "/", c, "/", f, (char *) 0)
  157. #define UUDIR(d)    _catstr(UUCPDIR, "/", d, (char *) 0)
  158. #define LOCALDIR    "D.ncoast"
  159. #else
  160. #define UUPATH(c,f)    _catstr(UUCPDIR, "/", f, (char *) 0)
  161. #define UUDIR(d)    UUCPDIR
  162. #define LOCALDIR    ""
  163. #endif
  164.  
  165. static char *_catstr(va_alist)
  166. va_dcl {
  167.     static char buf[5120];
  168.     char *cp, *bp;
  169.     va_list args;
  170.     
  171.     va_start(args);
  172.     bp = buf;
  173.     while ((cp = va_arg(args, char *)) != (char *) 0)
  174.         while (*cp != '\0')
  175.             *bp++ = *cp++;
  176.     *bp = '\0';
  177.     va_end(args);
  178.     return buf;
  179. }
  180.  
  181. lsys(sys, nf, nk)
  182. int *nf, *nk;
  183. char *sys; {
  184.     DIR *dp;
  185.     struct direct *uuf;
  186.     int len, n, files, blocks, nsend, nrec, nexec;
  187.     char dname[256], cmd[16];
  188.     FILE *fp;
  189.     struct stat st;
  190.     
  191.     blocks = 0;
  192.     files = 0;
  193.     nsend = 0;
  194.     nrec = 0;
  195.     nexec = 0;
  196.     if ((dp = opendir(UUDIR("C."))) == (DIR *) 0) {
  197.         perror(UUDIR("C."));
  198.         exit(1);
  199.     }
  200.     while ((uuf = readdir(dp)) != (struct direct *) 0) {
  201.         if (strncmp(uuf->d_name, "C.", 2) != 0)
  202.             continue;
  203.         len = strlen(uuf->d_name) - JOBNLEN;
  204.         for (n = 2; n < len; n++)
  205.             dname[n - 2] = uuf->d_name[n];
  206.         dname[n - 2] = '\0';
  207.         if (strcmp(dname, sys) != 0)
  208.             continue;
  209.         if ((fp = fopen(UUPATH("C.", uuf->d_name), "r")) == (FILE *) 0) {
  210.             perror(UUPATH("C.", uuf->d_name));
  211.             continue;
  212.         }
  213.         while (fscanf(fp, UUCPCMD, cmd, dname) == 2) {
  214.             files++;
  215.             switch (*cmd) {
  216.             case 'S':
  217.                 nsend++;
  218.                 break;
  219.             case 'R':
  220.                 nrec++;
  221.                 continue;
  222.             }
  223.             if (stat(UUPATH(LOCALDIR, dname), &st) < 0)
  224.                 continue;
  225.             blocks += (st.st_size + 1023) / 1024;
  226.         }
  227.         fclose(fp);
  228.     }
  229.     closedir(dp);
  230.     if ((dp = opendir(UUDIR("X."))) == (DIR *) 0) {
  231.         perror(UUDIR("X."));
  232.         exit(1);
  233.     }
  234.     while ((uuf = readdir(dp)) != (struct direct *) 0) {
  235.         if (strncmp(uuf->d_name, "X.", 2) != 0)
  236.             continue;
  237.         len = strlen(uuf->d_name) - JOBNLEN;
  238.         for (n = 2; n < len; n++)
  239.             dname[n - 2] = uuf->d_name[n];
  240.         dname[n - 2] = '\0';
  241.         if (strcmp(dname, sys) != 0)
  242.             continue;
  243.         files++;
  244.         nexec++;
  245.     }
  246.     closedir(dp);
  247.     *nf = files;
  248.     *nk = blocks;
  249.     if (files == 0)
  250.         return;
  251.     printf("%-16s %5d %5d %5d %5d %5dK ", sys, files, nsend, nrec, nexec, blocks);
  252.     if ((fp = fopen(UUSTST(sys), "r")) == (FILE *) 0)
  253.         printf("Last poll successful\n");
  254.     else {
  255.         if (stat(UULOCK(sys), &st) < 0)
  256.             printf("Aborted");
  257.         else
  258.             printf("Connected");
  259.         if (fgets(dname, sizeof dname, fp) == (char *) 0)
  260.             printf(" (reason unknown)\n");
  261.         else {
  262.             for (len = strlen(dname) - 1; dname[len] != ' '; len--)
  263.                 ;
  264.             dname[len] = '\0';
  265.             printf(" (");
  266.             for (n = 0, len = 0; dname[len] != ' ' || ++n < 4; len++)
  267.                 ;
  268.             while (dname[++len] != '\0')
  269.                 putchar(tolower(dname[len]));
  270.             printf(")\n");
  271.         }
  272.         fclose(fp);
  273.     }
  274. }
  275.  
  276. main() {
  277.     FILE *fp;
  278.     char sys[1024], sysname[132], lastsys[132];
  279.     int nf, nk, files, blocks, nsys;
  280.     
  281.     if ((fp = fopen(L_SYS, "r")) == (FILE *) 0) {
  282.         perror(L_SYS);
  283.         exit(1);
  284.     }
  285.     printf("System           Files  Send  Recv  Exec   Size Status\n");
  286.     printf("----------------------------------------------------------------------\n");
  287.     nsys = 0;
  288.     lastsys[0] = '\0';
  289.     while (fgets(sys, sizeof sys, fp) != (char *) 0) {
  290.         if (sscanf(sys, "%s", sysname) == 0)
  291.             continue;
  292.         sysname[MAXSYSLEN] = '\0';
  293.         if (sysname[0] == '#')
  294.             continue;
  295.         if (strcmp(sysname, lastsys) == 0)
  296.             continue;
  297.         lsys(sysname, &nf, &nk);
  298.         files += nf;
  299.         blocks += nk;
  300.         if (nf != 0)
  301.             nsys++;
  302.         strcpy(lastsys, sysname);
  303.     }
  304.     if (nsys != 0)
  305.         printf("----------------------------------------------------------------------\n");
  306.     printf("TOTAL            %5d                   %5dK for %d system(s)\n", files, blocks, nsys);
  307.     exit(0);
  308. }
  309. -- 
  310.  Brandon S. Allbery, moderator of comp.sources.misc and comp.binaries.ibm.pc
  311.   {{harvard,mit-eddie}!necntc,well!hoptoad,sun!cwruecmp!hal}!ncoast!allbery
  312. ARPA: necntc!ncoast!allbery@harvard.harvard.edu  Fido: 157/502  MCI: BALLBERY
  313.    <<ncoast Public Access UNIX: +1 216 781 6201 24hrs. 300/1200/2400 baud>>
  314.