home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES4.ZIP / UUTRAF / uutraf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-20  |  31.7 KB  |  1,259 lines

  1. /*
  2.  *    uutraf.c - generate UUCP traffic reports and summaries
  3.  */
  4.  
  5. #define SID    "@(#)uutraf:uutraf.c    1.2.2.8    92/10/23 10:23:03 (woods)"
  6. #include <sccsid.h>
  7.  
  8. #if defined(USE_STDDEF) || defined(_POSIX_SOURCE) || \
  9.     REALSTDC || (__STDC__ - 0) == 1
  10. # include <stddef.h>    /* should do before sysdefs.h */
  11. #endif
  12. #include <sysdefs.h>    /* a local header for common portability */
  13. #include <sys/types.h>
  14. #include <time.h>
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include <math.h>
  18. #ifdef BSD        /* really only pre-4.4BSD? */
  19. # include <strings.h>
  20. #else
  21. # include <string.h>
  22. # if !REALSTDC || defined(USE_MALLOC)
  23. #  include <malloc.h>
  24. # endif
  25. # ifndef SYSVR2
  26. #  include <limits.h>
  27. # endif
  28. #ifndef UUPC
  29. # include <unistd.h>
  30. #endif
  31. #endif
  32. #if REALSTDC || defined(USE_STDLIB)
  33. # include <stdlib.h>
  34. #endif
  35. #include <str.h>    /* local header:  STR*() macros */
  36. #include <libc.h>    /* local header:  for older libc's */
  37. #include <dlst.h>    /* local header:  dynamic list library */
  38. #include "defs.h"    /* uutraf's customization */
  39. #include "uutraf.h"    /* uutraf's common header */
  40. #include <extern.h>    /* local header:  setup for external declarations */
  41. #include "version.h"    /* uutraf's version stuff */
  42.  
  43. #ifdef UUPC
  44. #include "lib.h"
  45. #include "getopt.h"
  46. currentfile();
  47. #endif
  48.  
  49. #ifndef lint
  50. static const char *sccsold = "@(#) original uutraf.c : rel 1.2 : mod 2/2/90";
  51. #endif
  52.  
  53. /*
  54.  * History:
  55.  *    woods@robohack.UUCP - Mon Oct 12 15:11:03 EDT 1992
  56.  *    - added version and help message
  57.  *
  58.  *    rstory@shaboom.UUCP - Sat Sep 19 09:25:36 EDT 1992
  59.  *    - added reporting of date range time stamping
  60.  *
  61.  *    woods@robohack.UUCP - Thu Aug 27 00:52:14 EDT 1992
  62.  *    - finally an ULTRIX SYSLOG to work with!
  63.  *
  64.  *    woods@robohack.UUCP - Tue Aug 25 22:07:24 EDT 1992
  65.  *    - changed some field widths to allow > CPS values
  66.  *
  67.  *    woods@robohack.UUCP - Sun Feb 16 14:30:38 EST 1992
  68.  *    - added new report style for systems by port...
  69.  *
  70.  *    woods@eci386.UUCP - Mon Jul 16 10:46:06 EDT 1990
  71.  *    - fixed compare math
  72.  *
  73.  *    woods@robohack.UUCP - Sun Jul 15 18:11:48 EDT 1990
  74.  *    - major re-write
  75.  *    - added list library modules
  76.  *    - added print options (and name sort option)
  77.  *
  78.  * @(#) PROJ:        uutraf
  79.  * @(#) FILE:        uutraf.c
  80.  * @(#) Release:    1.2
  81.  * @(#) Rel. Date:    2/2/90
  82.  * @(#) Author:        Greg Hackney <hack@texbell.swbt.com>
  83.  */
  84.  
  85. forward LINK    *getsys();
  86. forward PORT    *getdev();
  87. forward void    procfile(),
  88.         tsfill(),
  89.         zerosys(),
  90.         zerodev(),
  91.         sortrun(),
  92.         printrun(),
  93.         printsys(),
  94.         printdev(),
  95.         printsum(),
  96.         printtmrng(),
  97.         comma_fy(),
  98.         sortlst(),
  99.         usage_err();
  100. forward cmp_t    cmpdev(),
  101.         cmpsys();
  102.  
  103. char        *argv0 = NULL;
  104.  
  105. char        *statfile = STATFILE;
  106.  
  107. /*
  108.  * globals for compare routines
  109.  */
  110. unsigned short    sort_sys_f = 0,
  111.         sort_dev_f = 0;
  112.  
  113. #ifdef DEBUG
  114. int    debug = 0;
  115. #endif
  116.  
  117. /* ARGSUSED */
  118. int
  119. main(argc, argv, envp)
  120.     int    argc;
  121.     char    *argv[];
  122.     char    *envp[];
  123. {
  124.     unsigned short    sortopt,    /* default sort method, see defs.h */
  125.             sortnames,
  126.             printopt;
  127.     static SUMM    trec = {0};    /* summary record */
  128.     llst_t        *syslst,    /* linked list of per-system totals */
  129.             *devlst;    /* linked list of per-device totals */
  130.     int        c;
  131.     FILE        *logfile = NULL;
  132.  
  133. #ifdef UUPC
  134.     if (!configure( B_UUCICO ))
  135.       panic();
  136.     statfile = malloc(512);
  137.     mkfilename(statfile, E_spooldir, SYSLOG);
  138. #endif
  139.  
  140.     sortnames = 0;
  141.     sortopt = 0;
  142.     printopt = 0;
  143.     devlst = syslst = (llst_t *) NULL;
  144.  
  145.     argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0];
  146.  
  147.     while ((c = getopt(argc, argv, "HMNPSVab:c:f:hnt:sx:?")) != EOF) {
  148.         switch (c) {
  149.         case 'H':
  150.             printopt |= HEADERS;
  151.             break;
  152.         case 'N':
  153.             printopt |= SYS_RPT;
  154.             break;
  155.         case 'S':
  156.             printopt |= SUMM_RPT;
  157.             break;
  158. #ifdef HAVE_HDBUUCP
  159.         case 'P':
  160.             printopt |= PORT_RPT;
  161.             break;
  162.         case 'M':
  163.             printopt |= (SYSBYPORT_OPT | SYS_RPT);
  164.             break;
  165. #endif
  166.         case 'a':    /* sort in ascending vs. descending order */
  167.             sortopt |= REVERSE;
  168.             break;
  169.         case 'b':    /* sort by bytes xmitted and/or received */
  170.             if (*(optarg + 1) != EOS)
  171.                 usage_err(argv0, "-b requires a one-letter argument");
  172.             switch (*optarg) {
  173.             case 'b':
  174.                 sortopt |= (RECEIVED | XMIT);
  175.                 break;
  176.             case 'r':
  177.                 sortopt |= RECEIVED;
  178.                 break;
  179.             case 'x':
  180.                 sortopt |= XMIT;
  181.                 break;
  182.             default:
  183.                 usage_err(argv0, "-b's argument must be one of [brx]");
  184.                 break;
  185.             }
  186.             break;
  187.         case 'c':    /* sort by xfer rate xmitted and/or received */
  188.             if (*(optarg + 1) != EOS)
  189.                 usage_err(argv0, "-c requires a one-letter argument");
  190.             switch (*optarg) {
  191.             case 'b':
  192.                 sortopt |= (R_CPS | X_CPS);
  193.                 break;
  194.             case 'r':
  195.                 sortopt |= R_CPS;
  196.                 break;
  197.             case 'x':
  198.                 sortopt |= X_CPS;
  199.                 break;
  200.             default:
  201.                 usage_err(argv0, "-c's argument must be one of [brx]");
  202.                 break;
  203.             }
  204.             break;
  205.         case 'n':
  206.             sortnames = 1;
  207.             break;
  208.         case 'f':    /* number of files */
  209.             if (*(optarg + 1) != EOS)
  210.                 usage_err(argv0, "-f requires a one-letter argument");
  211.             switch (*optarg) {
  212.             case 'b':
  213.                 sortopt |= (R_NUMB | X_NUMB);
  214.                 break;
  215.             case 'r':
  216.                 sortopt |= R_NUMB;
  217.                 break;
  218.             case 'x':
  219.                 sortopt |= X_NUMB;
  220.                 break;
  221.             default:
  222.                 usage_err(argv0, "-f's argument must be one of [brx]");
  223.                 break;
  224.             }
  225.             break;
  226.         case 't':    /* sort by accumulated time */
  227.             if (*(optarg + 1) != EOS)
  228.                 usage_err(argv0, "-t requires a one-letter argument");
  229.             switch (*optarg) {
  230.             case 'b':
  231.                 sortopt |= (R_TIME | X_TIME);
  232.                 break;
  233.             case 'r':
  234.                 sortopt |= R_TIME;
  235.                 break;
  236.             case 'x':
  237.                 sortopt |= X_TIME;
  238.                 break;
  239.             default:
  240.                 usage_err(argv0, "-t's argument must be one of [brx]");
  241.                 break;
  242.             }
  243.             break;
  244.         case 's':    /* Use stdin instead of normal xferstat file */
  245.             logfile = stdin;
  246.             break;
  247.         case 'x':
  248. #ifdef DEBUG
  249.             debug = atoi(optarg);
  250.             break;
  251. #else
  252.             (void) fprintf(stderr, "%s: debugging not compiled in.\n", argv0);
  253.             break;
  254. #endif
  255.         case 'V':
  256.             (void) fprintf(stderr, "%s: Version %d.%d, Patchlevel %d.\n", argv0, version, subver, patchlevel);
  257.             break;
  258.         default:
  259.             (void) fprintf(stderr, "\n%s: Version %d.%d, Patchlevel %d.\n", argv0, version, subver, patchlevel);
  260.             usage_err(argv0, usage);
  261.             break;
  262.         }
  263.     }
  264.     /*
  265.      * Use default sorting method if none or names was chosen
  266.      */
  267.     if (((sortopt == REVERSE) || !sortopt) && !sortnames)
  268.         sortopt |= DEFAULT_SORT;
  269.     if ((printopt == HEADERS) || !printopt)
  270.         printopt |= DEFAULT_RPT;
  271.     if (optind == argc || logfile)            /* fake up the default file */
  272.         argv[--optind] = statfile;
  273.     for ( ; optind < argc; optind++) {
  274.         if (STREQ(argv[optind], "-")) {
  275. #ifdef DEBUG
  276.             if (debug)
  277.                 (void) fprintf(stderr, "%s: processing STDIN.\n", argv0);
  278. #endif
  279.             logfile = stdin;
  280.         } else {
  281.             if (! (logfile = fopen(argv[optind], "r"))) {
  282.                 (void) fprintf(stderr, "%s: Can't open %s for reading -- ", argv0, argv[optind]);
  283.                 perror(optarg);
  284.             }
  285. #ifdef DEBUG
  286.             if (debug)
  287.                 (void) fprintf(stderr, "%s: processing %s.\n", argv0, argv[optind]);
  288. #endif
  289.         }
  290.         procfile(logfile, &syslst, &devlst, &trec);
  291.         (void) fclose(logfile);        /* will possibly close stdin */
  292.     }
  293.     trec.syscnt = llst_total(syslst);
  294. #ifdef HAVE_HDBUUCP
  295.     trec.devcnt = llst_total(devlst);
  296. #endif
  297.     sortrun(syslst, devlst, sortopt, sortopt);    /* sort it */
  298.     printrun(syslst, devlst, &trec, printopt);    /* print it out */
  299.     exit(0);
  300.     /* NOTREACHED */
  301. }
  302.  
  303. void
  304. procfile(logfile, syslstp, devlstp, trec)
  305.     FILE    *logfile;
  306.     llst_t    **syslstp;
  307.     llst_t    **devlstp;
  308.     SUMM    *trec;
  309. {
  310.     LINK    *sysp;
  311.     PORT    *devp;
  312.     PORT    *portp;
  313.     char    *sys,        /* points at the previous remote node name */
  314.         *user,        /* points at the "user-id" */
  315.         flow[10],    /* holds the direction of uucp flow */
  316.         buf[BUFSIZ],    /* general purpose */
  317.         *string;    /* general purpose */
  318.     long    bytes;        /* number of bytes in the uucp xfer */
  319.     float    seconds;    /* number of seconds the xfer took */
  320.     int    mon, day, hh, mm;
  321. #ifdef HAVE_HDBUUCP
  322.     char    *dev;        /* points at the device name used */
  323.     char    mode, pchar = ' ';
  324.     int    ss, pid = 0, seq = 0;
  325. #else
  326.     long    epoch;
  327. #endif
  328. #ifdef DEBUG
  329.     int    i = 0;
  330. #endif
  331.  
  332.     /*
  333.      * process each line in the logfile
  334.      */
  335. #ifdef HAVE_HDBUUCP
  336.     /*    From an AT&T 3b2/400 SysVr3.2 /usr/spool/uucp/.Admin/xferstats:
  337.      * fastlane!woods M (2/16-19:43:37) (C,5711,2) [tty33] -> 152 / 1.420 secs, 107 bytes/sec
  338.      * fastlane!rhl M (2/16-19:43:50) (C,5711,3) [tty33] <- 471 / 6.090 secs, 77 bytes/sec
  339.      *
  340.      *    From an AIX 3.2 /var/uucp/.Admin/xfererstats:
  341.      * ecirs6k!uucp M (2/17-19:44:54) (C,8560,0) [notty] <- 365531 / 7.633 secs, 47888 bytes/sec 
  342.      * ecirs6k!uucp M (2/17-22:10:19) (C,321,0) [notty] <- 32178 / 0.366 secs, 87918 bytes/sec 
  343.      */
  344. #else
  345.     /*    From an ULTRIX 4.2 /var/spool/uucp/SYSLOG:
  346.      * daemon becker (8/26-0:14) (714802480) sent 348 b 0 secs, Pk: 7, Rxmt: 0
  347.      * daemon becker (8/26-0:14) (714802487) sent 89 b 0 secs, Pk: 3, Rxmt: 0
  348.      * news censor (8/25-6:00) (714736824) received 43842 b 47 secs
  349.      * news censor (8/25-6:00) (714736827) received 108 b 1 secs
  350.      */
  351. #endif
  352.     while (fgets(buf, BUFSIZ, logfile)) {
  353. #ifdef DEBUG
  354.         if (debug > 8)
  355.             (void) fprintf(stderr, "%d: %s", i, buf);
  356. #endif
  357.         user = buf;
  358.         /*
  359.          * look for the node name
  360.          */
  361. #ifdef HAVE_HDBUUCP
  362.         if (!(sys = strtok(buf, "!")))
  363. #else
  364.         if (!(sys = strtok(buf, " ")) ||
  365.             !(sys = strtok((char *) NULL, " ")))
  366. #endif
  367.             continue;
  368. #ifdef DEBUG
  369.         if (debug >  7)
  370.             (void) fprintf(stderr, "System: %s, ", sys);
  371. #endif
  372.         /*
  373.          * look for the junk information
  374.          */
  375. #ifdef HAVE_HDBUUCP
  376.         if (!(string = strtok((char *) NULL, "[")))
  377.             continue;
  378. #ifdef UUPC
  379.         if (sscanf(string, "%*s %c %*s (%d/%d-%d:%d:%d) (%c,%d,%d)",
  380. #else
  381.         if (sscanf(string, "%*s %c (%d/%d-%d:%d:%d) (%c,%d,%d)",
  382. #endif
  383.                &mode, &mon, &day, &hh, &mm, &ss, &pchar, &pid, &seq) == EOF)
  384.             continue;
  385. # ifdef DEBUG
  386.         if (debug > 6)
  387.             (void) fprintf(stderr, "mode: %c, time&pid: (%d/%d-%d:%d:%d) (%c,%d,%d)\n",
  388.                        mode, mon, day, hh, mm, ss, pchar, pid, seq);
  389. # endif
  390. #else
  391.         if (!(string = strtok((char *) NULL, " ")))
  392.             continue;
  393. # ifdef DEBUG
  394.         if (debug > 8)
  395.             (void) fprintf(stderr, "date&time ");
  396. # endif
  397.         if (sscanf(string, "(%d/%d-%d:%d)", &mon, &day, &hh, &mm) == EOF)
  398.             continue;
  399. # ifdef DEBUG
  400.         if (debug > 6)
  401.             (void) fprintf(stderr, "(%d/%d-%d:%d)", mon, day, hh, mm);
  402. # endif
  403.         if (!(string = strtok((char *) NULL, " ")))
  404.             continue;
  405. # ifdef DEBUG
  406.         if (debug > 8)
  407.             (void) fprintf(stderr, " epoch");
  408. # endif
  409.         if (sscanf(string, "(%ld)", &epoch) == EOF)
  410.             continue;
  411. # ifdef DEBUG
  412.         if (debug > 6)
  413.             (void) fprintf(stderr, " (%ld)\n", mon, day, hh, mm, epoch);
  414. # endif
  415. #endif
  416.                 tsfill(trec, mon, day, hh, mm);    /* should be inlined for efficiency */
  417. #ifdef HAVE_HDBUUCP
  418.         /*
  419.          * look for the device name
  420.          */
  421.         if (!(dev = strtok((char *) NULL, "]")))
  422.             continue;
  423. #endif
  424.         /*
  425.          * parse the remainder of the data string
  426.          */
  427.         if (!(string = strtok((char *) NULL, "\n")))
  428.             continue;
  429. #ifdef HAVE_HDBUUCP
  430.         if (sscanf(string, "%s %ld / %f", flow, &bytes, &seconds) == EOF)
  431. #else
  432. # if defined(ultrix) || defined(__ultrix__)    /* ???? */
  433.         if (sscanf(string, "%s %ld b %f secs", flow, &bytes, &seconds) == EOF)
  434. # else
  435.         if (sscanf(string, "%s data %ld bytes %f secs", flow, &bytes, &seconds) == EOF)
  436. # endif
  437. #endif
  438.             continue;
  439.         if (!(sysp = getsys(syslstp, sys)))
  440.             exit(1);
  441. #ifdef HAVE_HDBUUCP
  442.         if (!(devp = getdev(devlstp, dev)))
  443.             exit(1);
  444.         if (sysp->l_lastpid != pid) {
  445.             sysp->l_lastpid = pid;
  446.             if (mode == 'M')
  447.                 sysp->l_out_conn++;
  448.             else
  449.                 sysp->l_in_conn++;
  450.         }
  451.         if (devp->p_lastpid != pid) {
  452.             devp->p_lastpid = pid;
  453.             if (mode == 'M') 
  454.                 devp->p_out_conn++;
  455.             else
  456.                 devp->p_in_conn++;
  457.         }
  458. #endif
  459.         /* outgoing uucp */
  460.         if (STREQ(flow, OUT)
  461. #ifdef pyr
  462.              || STREQ(flow, T_OUT) || STREQ(flow, F_OUT)
  463. #endif
  464.            ) {
  465. #ifdef DEBUG
  466.             if (debug > 5)
  467. # ifdef HAVE_HDBUUCP
  468.                 (void) fprintf(stderr, "%s OUTGOING %s\n", sys, dev);
  469. # else
  470.                 (void) fprintf(stderr, "%s OUTGOING\n", sys);
  471. # endif
  472. #endif
  473.             sysp->l_xmit += bytes;
  474.             sysp->l_xmit_time += seconds;
  475.             sysp->l_xmit_cnt++;
  476. #ifdef HAVE_HDBUUCP
  477.             devp->p_xmit += bytes;
  478.             devp->p_xmit_time += seconds;
  479.             devp->p_xmit_cnt++;
  480.             if (!(portp = getdev(&(sysp->l_portlst), dev)))
  481.                 exit(1);
  482.             portp->p_xmit += bytes;
  483.             portp->p_xmit_time += seconds;
  484.             portp->p_xmit_cnt++;
  485.             if (portp->p_lastpid != pid) {
  486.                 portp->p_lastpid = pid;
  487.                 if (mode == 'M') {
  488.                     portp->p_out_conn++;
  489.                     trec->num_out_conn++;    /* only once! */
  490.                 } else {
  491.                     portp->p_in_conn++;
  492.                     trec->num_in_conn++;
  493.                 }
  494.             }
  495. #endif
  496.             trec->bytes_xmit += bytes;    /* summary totals */
  497.             trec->sec_xmit += seconds;
  498.             trec->num_xmit++;
  499.         } else if (STREQ(flow, IN)        /* incoming uucp */
  500.  
  501. #ifdef pyr
  502.                || STREQ(flow, T_IN) || STREQ(flow, F_IN)
  503. #endif
  504.               ) {
  505. #ifdef DEBUG
  506.             if (debug > 5)
  507. # ifdef HAVE_HDBUUC
  508.                 (void) fprintf(stderr, "%s INCOMING %s\n", sys, dev);
  509. # else
  510.                 (void) fprintf(stderr, "%s INCOMING\n", sys);
  511. # endif
  512. #endif
  513.             sysp->l_recv += bytes;
  514.             sysp->l_recv_time += seconds;
  515.             sysp->l_recv_cnt++;
  516. #ifdef HAVE_HDBUUCP
  517.             devp->p_recv += bytes;
  518.             devp->p_recv_time += seconds;
  519.             devp->p_recv_cnt++;
  520.             if (!(portp = getdev(&(sysp->l_portlst), dev)))
  521.                 exit(1);
  522.             portp->p_recv += bytes;
  523.             portp->p_recv_time += seconds;
  524.             portp->p_recv_cnt++;
  525.             if (portp->p_lastpid != pid) {
  526.                 portp->p_lastpid = pid;
  527.                 if (mode == 'M') {
  528.                     portp->p_out_conn++;
  529.                     trec->num_out_conn++;
  530.                 } else {
  531.                     portp->p_in_conn++;
  532.                     trec->num_in_conn++;
  533.                 }
  534.             }
  535. #endif
  536.             trec->bytes_recv += bytes;    /* summary totals */
  537.             trec->sec_recv += seconds;
  538.             trec->num_recv++;
  539.         }
  540. #ifdef DEBUG
  541.         i++;
  542. #endif
  543.     }
  544.     return;
  545. }
  546.  
  547. #ifdef HAVE_HDBUUCP
  548. PORT *
  549. getdev(devlstp, d)    /* returns an link struct to the system name specified. */
  550.     llst_t    **devlstp;
  551.     char    *d;
  552. {
  553.     llst_t    *work;
  554.     PORT    *nd;
  555.     PORT    sd;
  556.  
  557.     extern unsigned short    sort_dev_f;
  558.  
  559.     sort_dev_f = 0;        /* set default comparison of name only */
  560.     work = *devlstp;
  561.     if (! work) {        /* must be the first time thru */
  562. #ifdef DEBUG
  563.         if (debug > 2)
  564.             (void) fprintf(stderr, "initialising devlst (%s)\n", d);
  565. #endif
  566.         if (!(work = llst_new())) {
  567.             perror("getdev(): llst_new() failed");
  568.             return(NULL);
  569.         }
  570.         if (!(nd = (PORT *) malloc(sizeof(PORT)))) {
  571.             perror("getdev(): malloc(nd) failed");
  572.             llst_destroy(work);
  573.             return(NULL);
  574.         }
  575.         if (!llst_add(work, (char *) nd)) {
  576.             perror("getdev(): llst_add(nd) failed");
  577.             llst_destroy(work);
  578.             free(nd);
  579.             return(NULL);
  580.         }
  581.         *devlstp = work;
  582.         zerodev(nd);
  583.         (void) strncpy(nd->p_dname, d, sizeof(nd->p_dname) - 1);
  584.         return(nd);
  585.     }
  586.     zerodev(&sd);
  587.     (void) strncpy(sd.p_dname, d, sizeof(sd.p_dname) - 1);
  588.     if (!llst_find(work, (char *) &sd, cmpdev)) {
  589.         /*
  590.          * create a new link
  591.          */
  592. #ifdef DEBUG
  593.         if (debug > 1)
  594.             (void) fprintf(stderr, "adding new device - %s\n", d);
  595. #endif
  596.         if (!(nd = (PORT *) malloc(sizeof(PORT)))) {
  597.             perror("getdev(): malloc(nd2) failed");
  598.             return(NULL);
  599.         }
  600.         if (!llst_add(work, (char *) nd)) {
  601.             perror("getdev(): llst_add(nd2) failed");
  602.             free(nd);
  603.             return(NULL);
  604.         }
  605.         zerodev(nd);
  606.         (void) strncpy(nd->p_dname, d, sizeof(nd->p_dname) - 1);
  607.     }
  608.     return((PORT *) llst_current(work));
  609. }
  610. #endif
  611.  
  612. LINK *
  613. getsys(syslstp, s)    /* returns an link struct to the system name specified. */
  614.     llst_t    **syslstp;
  615.     char    *s;
  616. {
  617.     llst_t    *work;
  618.     LINK    *nd;
  619.     char    buf[BUFSIZ];
  620.     LINK    *sd = (LINK *) buf;
  621.  
  622.     extern unsigned short    sort_sys_f;
  623.  
  624.     sort_sys_f = 0;        /* set default comparison of name only */
  625.     work = *syslstp;
  626.     if (! work) {        /* must be the first time thru */
  627. #ifdef DEBUG
  628.         if (debug > 2)
  629.             (void) fprintf(stderr, "initialising syslst (%s)\n", s);
  630. #endif
  631.         if (!(work = llst_new())) {
  632.             perror("getsys(): llst_new() failed");
  633.             return(NULL);
  634.         }
  635.         if (!(nd = (LINK *) malloc(sizeof(LINK) + strlen(s)))) {
  636.             perror("getsys(): malloc() failed");
  637.             llst_destroy(work);
  638.             return(NULL);
  639.         }
  640.         if (!llst_add(work, (char *) nd)) {
  641.             perror("getsys(): llst_add(nd) failed");
  642.             llst_destroy(work);
  643.             free(nd);
  644.             return(NULL);
  645.         }
  646.         *syslstp = work;
  647.         zerosys(nd);
  648.         (void) strcpy(nd->l_sysname, s);
  649.         return(nd);
  650.     }
  651.     zerosys(sd);
  652.     (void) strcpy(sd->l_sysname, s);
  653.     if (!llst_find(work, (char *) sd, cmpsys)) {
  654.         /*
  655.          * create a new link
  656.          */
  657. #ifdef DEBUG
  658.         if (debug > 1)
  659.             (void) fprintf(stderr, "adding new system - %s\n", s);
  660. #endif
  661.         if (!(nd = (LINK *) malloc(sizeof(LINK) + strlen(s)))) {
  662. #ifdef DEBUG
  663.             (void) fprintf(stderr, "malloc(%d + %d)\n", sizeof(LINK), strlen(s));
  664. #endif
  665.             perror("getsys(): malloc(nd2) failed");
  666.             return((LINK *) NULL);
  667.         }
  668.         if (!llst_add(work, (char *) nd)) {
  669.             perror("getsys(): llst_add(nd2) failed");
  670.             free(nd);
  671.             return(NULL);
  672.         }
  673.         zerosys(nd);
  674.         (void) strcpy(nd->l_sysname, s);
  675.     }
  676.     return((LINK *) llst_current(work));
  677. }
  678.  
  679. void
  680. zerosys(l)
  681.     LINK    *l;
  682. {
  683.     /*
  684.      * added for portability vs. memset/bzero
  685.      */
  686.     l->l_recv    = 0.0;
  687.     l->l_recv_time    = 0.0;
  688.     l->l_recv_cnt    = 0L;
  689.     l->l_xmit    = 0.0;
  690.     l->l_xmit_time    = 0.0;
  691.     l->l_xmit_cnt    = 0L;
  692.     l->l_in_conn    = 0;
  693.     l->l_out_conn    = 0;
  694.     l->l_lastpid    = 0;
  695.     l->l_portlst    = NULL;
  696.     l->l_sysname[0]    = '\0';
  697. }
  698.  
  699. void
  700. zerodev(p)
  701.     PORT    *p;
  702. {
  703.     /*
  704.      * added for portability vs. memset/bzero
  705.      */
  706.     p->p_recv    = 0.0;
  707.     p->p_recv_time    = 0.0;
  708.     p->p_recv_cnt    = 0L;
  709.     p->p_xmit    = 0.0;
  710.     p->p_xmit_time    = 0.0;
  711.     p->p_xmit_cnt    = 0L;
  712.     p->p_in_conn    = 0;
  713.     p->p_out_conn    = 0;
  714.     p->p_lastpid    = 0;
  715.     p->p_syslst    = NULL;
  716.     p->p_dname[0]    = '\0';
  717. }
  718.  
  719. void 
  720. tsfill(trec, mon, day, hh, mm) 
  721.     SUMM    *trec;
  722.     int    mon;
  723.         int    day;
  724.         int    hh;
  725.         int    mm;
  726. {
  727.     static int    AlreadySetFirst = FALSE;
  728.  
  729.     if (!AlreadySetFirst) {
  730. #ifdef DEBUG
  731.         if (debug > 2)
  732.             (void) fprintf(stderr, "initialising trec->first_rec (%d/%d-%02d:%02d)\n", mon, day, hh, mm);
  733. #endif
  734.         trec->first_rec.tm_mon = mon;
  735.         trec->first_rec.tm_mday = day;
  736.         trec->first_rec.tm_hour = hh;
  737.         trec->first_rec.tm_min = mm;
  738.         AlreadySetFirst = TRUE;
  739.     } else {
  740. #ifdef DEBUG
  741.         if (debug > 2)
  742.             (void) fprintf(stderr, "initialising trec->last_rec (%d/%d-%02d:%02d)\n", mon, day, hh, mm);
  743. #endif
  744.         trec->last_rec.tm_mon = mon;
  745.         trec->last_rec.tm_mday = day;
  746.         trec->last_rec.tm_hour = hh;
  747.         trec->last_rec.tm_min = mm;
  748.     }
  749.     return;
  750. }
  751.  
  752. void
  753. sortrun(syslst, devlst, howsys, howdev)
  754.     llst_t        *syslst;
  755.     llst_t        *devlst;
  756.     unsigned short    howsys;
  757.     unsigned short    howdev;
  758. {
  759.     extern cmp_t        cmpdev();
  760.     extern cmp_t        cmpsys();
  761.     extern unsigned short    sort_sys_f;
  762.     extern unsigned short    sort_dev_f;
  763.  
  764. #ifdef DEBUG
  765.     if (debug)
  766.         (void) fprintf(stderr, "%s: sorting system and device lists.\n", argv0);
  767. #endif
  768.     sort_sys_f = howsys;        /* set global used by cmpsys() */
  769.     llst_sort(syslst, cmpsys);
  770.     llst_top(devlst);
  771.     do {
  772.         PORT    *devp;
  773.  
  774.         if (! (devp = (PORT *) llst_current(devlst)))
  775.             continue;
  776.         llst_sort(devp->p_syslst, cmpsys);
  777.     } while (llst_next(devlst));
  778.     sort_dev_f = howdev;        /* set global used by cmpdev() */
  779.     llst_sort(devlst, cmpdev);
  780.     llst_top(syslst);
  781.     do {
  782.         LINK    *sysp;
  783.  
  784.         if (! (sysp = (LINK *) llst_current(syslst)))
  785.             continue;
  786.         llst_sort(sysp->l_portlst, cmpdev);
  787.     } while (llst_next(syslst));
  788.     return;
  789. }
  790.  
  791. void
  792. printrun(syslst, devlst, trec, printopt)
  793.     llst_t        *syslst;
  794.     llst_t        *devlst;
  795.     SUMM        *trec;
  796.     unsigned short    printopt;
  797. {
  798. #ifdef DEBUG
  799.     if (debug)
  800.         (void) fprintf(stderr, "%s: printing report.\n", argv0);
  801. #endif
  802.     if (printopt & SYS_RPT)
  803.         printsys(syslst, trec, printopt);
  804. #ifdef HAVE_HDBUUCP
  805.     if (printopt & PORT_RPT)
  806.         printdev(devlst, trec, printopt);
  807. #endif
  808.     if (printopt & SUMM_RPT)
  809.         printsum(trec, printopt);
  810.     return;
  811. }
  812.  
  813. /* ARGSUSED */
  814. void
  815. printsys(syslst, trec, printopt)
  816.     llst_t        *syslst;
  817.     SUMM        *trec;
  818.     unsigned short    printopt;
  819. {
  820.     LINK    *sysp;
  821.  
  822.     if (printopt & HEADERS) {
  823.         printtmrng(trec, printopt);
  824.         (void) printf("%-8s ", "Remote");
  825.         (void) printf("%9s ", "K-Bytes");
  826.         (void) printf("%9s ", "K-Bytes");
  827.         (void) printf("%9s ", "K-Bytes");
  828.         (void) printf("%5s ", "Hours");
  829.         (void) printf("%5s ", "Hours");
  830.         (void) printf("%6s ", "AvCPS");
  831.         (void) printf("%6s ", "AvCPS");
  832.         (void) printf("%4s ", "#");
  833.         (void) printf("%4s ", "#");
  834. #ifdef HAVE_HDBUUCP
  835.         (void) printf("%3s\n", "#");
  836. #else
  837.         (void) putchar('\n');
  838. #endif
  839.  
  840.         (void) printf("%-8s ", "SiteName");
  841.         (void) printf("%9s ", "Recv");
  842.         (void) printf("%9s ", "Xmit");
  843.         (void) printf("%9s ", "Total");
  844.         (void) printf("%5s ", "Recv");
  845.         (void) printf("%5s ", "Xmit");
  846.         (void) printf("%6s ", "Recv");
  847.         (void) printf("%6s ", "Xmit");
  848.         (void) printf("%4s ", "Recv");
  849.         (void) printf("%4s ", "Xmit");
  850. #ifdef HAVE_HDBUUCP
  851.         (void) printf("%3s\n", "Con");
  852. #else
  853.         (void) putchar('\n');
  854. #endif
  855.  
  856.         (void) printf("%s ", "--------");
  857.         (void) printf("%s ", "---------");
  858.         (void) printf("%s ", "---------");
  859.         (void) printf("%s ", "---------");
  860.         (void) printf("%s ", "-----");
  861.         (void) printf("%s ", "-----");
  862.         (void) printf("%s ", "------");
  863.         (void) printf("%s ", "------");
  864.         (void) printf("%s ", "----");
  865.         (void) printf("%s ", "----");
  866. #ifdef HAVE_HDBUUCP
  867.         (void) printf("%s\n", "---");
  868. #else
  869.         (void) putchar('\n');
  870. #endif
  871.     }
  872.  
  873.     llst_top(syslst);
  874.     do {
  875.         if (! (sysp = (LINK *) llst_current(syslst)))
  876.             continue;
  877.         (void) printf("%-9.9s", sysp->l_sysname);
  878.         (void) printf("%9.3f ", (double) sysp->l_recv / 1024.0);
  879.         (void) printf("%9.3f ", (double) sysp->l_xmit / 1024.0);
  880.         (void) printf("%9.3f ", (double) (sysp->l_xmit + sysp->l_recv) / 1024.0);
  881.         (void) printf("%5.2f ", (double) sysp->l_recv_time / 3600.0);
  882.         (void) printf("%5.2f ", (double) sysp->l_xmit_time / 3600.0);
  883.         if (sysp->l_recv_time != 0.0)    /* divide by zero ? */
  884.             (void) printf("%6.0f ", (double) sysp->l_recv / sysp->l_recv_time);
  885.         else
  886.             (void) printf("%6.0f ", (double) 0);
  887.         if (sysp->l_xmit_time != 0.0)    /* divide by zero ? */
  888.             (void) printf("%6.0f ", (double) sysp->l_xmit / sysp->l_xmit_time);
  889.         else
  890.             (void) printf("%6.0f ", (double) 0);
  891.         (void) printf("%4ld ", sysp->l_recv_cnt);
  892.         (void) printf("%4ld ", sysp->l_xmit_cnt);
  893. #ifdef HAVE_HDBUUCP
  894.         (void) printf("%3d\n", sysp->l_in_conn + sysp->l_out_conn);
  895.         if (printopt & SYSBYPORT_OPT) {
  896.             llst_top(sysp->l_portlst);
  897.             do {
  898.                 PORT    *devp;
  899.  
  900.                 if (! (devp = (PORT *) llst_current(sysp->l_portlst)))
  901.                     continue;
  902.                 (void) printf("%8.8s ", devp->p_dname);
  903.                 (void) printf("%9.3f ", (double) devp->p_recv / 1024.0);
  904.                 (void) printf("%9.3f ", (double) devp->p_xmit / 1024.0);
  905.                 (void) printf("%9.3f ", (double) (devp->p_xmit + devp->p_recv) / 1024);
  906.                 (void) printf("%5.2f ", (double) devp->p_recv_time / 3600.0);
  907.                 (void) printf("%5.2f ", (double) devp->p_xmit_time / 3600.0);
  908.                 if (devp->p_recv_time != 0.0)    /* divide by zero ? */
  909.                     (void) printf("%6.0f ", (double) devp->p_recv / devp->p_recv_time);
  910.                 else
  911.                     (void) printf("%6.0f ", (double) 0);
  912.                 if (devp->p_xmit_time != 0.0)    /* divide by zero ? */
  913.                     (void) printf("%6.0f ", (double) devp->p_xmit / devp->p_xmit_time);
  914.                 else
  915.                     (void) printf("%6.0f ", (double) 0);
  916.                 (void) printf("%4ld ", devp->p_recv_cnt);
  917.                 (void) printf("%4ld ", devp->p_xmit_cnt);
  918.                 (void) printf("%3d\n", devp->p_in_conn + devp->p_out_conn);
  919.             } while (llst_next(sysp->l_portlst));
  920.             putchar('\n');
  921.         }
  922. #else
  923.         putchar('\n');
  924. #endif
  925.     } while (llst_next(syslst));
  926.     return;
  927. }
  928.  
  929. #ifdef HAVE_HDBUUCP
  930. /* ARGSUSED */
  931. void
  932. printdev(devlst, trec, printopt)
  933.     llst_t        *devlst;
  934.     SUMM        *trec;
  935.     unsigned short    printopt;
  936. {
  937.     PORT    *devp;
  938.  
  939.     if (printopt & HEADERS) {
  940.         printtmrng(trec, printopt);
  941.         (void) printf("%-8s ", "Port");
  942.         (void) printf("%9s ", "K-Bytes");
  943.         (void) printf("%9s ", "K-Bytes");
  944.         (void) printf("%9s ", "K-Bytes");
  945.         (void) printf("%5s ", "Hours");
  946.         (void) printf("%5s ", "Hours");
  947.         (void) printf("%6s ", "AvCPS");
  948.         (void) printf("%6s ", "AvCPS");
  949.         (void) printf("%4s ", "#");
  950.         (void) printf("%4s ", "#");
  951.         (void) printf("%3s\n", "#");
  952.  
  953.         (void) printf("%-8s ", "Name");
  954.         (void) printf("%9s ", "Recv");
  955.         (void) printf("%9s ", "Xmit");
  956.         (void) printf("%9s ", "Total");
  957.         (void) printf("%5s ", "Recv");
  958.         (void) printf("%5s ", "Xmit");
  959.         (void) printf("%6s ", "Recv");
  960.         (void) printf("%6s ", "Xmit");
  961.         (void) printf("%4s ", "Recv");
  962.         (void) printf("%4s ", "Xmit");
  963.         (void) printf("%3s\n", "Con");
  964.  
  965.         (void) printf("%s ", "--------");
  966.         (void) printf("%s ", "---------");
  967.         (void) printf("%s ", "---------");
  968.         (void) printf("%s ", "---------");
  969.         (void) printf("%s ", "-----");
  970.         (void) printf("%s ", "-----");
  971.         (void) printf("%s ", "------");
  972.         (void) printf("%s ", "------");
  973.         (void) printf("%s ", "----");
  974.         (void) printf("%s ", "----");
  975.         (void) printf("%s\n", "---");
  976.     }
  977.  
  978.     llst_top(devlst);
  979.     do {
  980.         if (! (devp = (PORT *) llst_current(devlst)))
  981.             continue;
  982.         (void) printf("%-9.9s", devp->p_dname);
  983.         (void) printf("%9.3f ", (double) devp->p_recv / 1024.0);
  984.         (void) printf("%9.3f ", (double) devp->p_xmit / 1024.0);
  985.         (void) printf("%9.3f ", (double) (devp->p_xmit + devp->p_recv) / 1024.0);
  986.         (void) printf("%5.2f ", (double) devp->p_recv_time / 3600.0);
  987.         (void) printf("%5.2f ", (double) devp->p_xmit_time / 3600.0);
  988.         if (devp->p_recv_time != 0.0)    /* divide by zero ? */
  989.             (void) printf("%6.0f ", (double) devp->p_recv / devp->p_recv_time);
  990.         else
  991.             (void) printf("%6.0f ", (double) 0);
  992.         if (devp->p_xmit_time != 0.0)    /* divide by zero ? */
  993.             (void) printf("%6.0f ", (double) devp->p_xmit / devp->p_xmit_time);
  994.         else
  995.             (void) printf("%6.0f ", (double) 0);
  996.         (void) printf("%4ld ", devp->p_recv_cnt);
  997.         (void) printf("%4ld ", devp->p_xmit_cnt);
  998.         (void) printf("%3d\n", devp->p_in_conn + devp->p_out_conn);
  999.     } while (llst_next(devlst));
  1000.     return;
  1001. }
  1002. #endif
  1003.  
  1004. /* ARGSUSED */
  1005. void
  1006. printsum(trec, printopt)
  1007.     SUMM        *trec;
  1008.     unsigned short    printopt;
  1009. {
  1010.     long    total_secs;
  1011.     char    buf[BUFSIZ];
  1012.  
  1013.     if (printopt & HEADERS)
  1014.         printtmrng(trec);
  1015.     (void) printf("Active UUCP sites:\t");
  1016.     (void) sprintf(buf, "%d", trec->syscnt);
  1017.     comma_fy(buf);
  1018.     (void) printf("%10s", buf);
  1019.     (void) printf("\tTotal time recv:\t%4d:%02d:%02d\n",
  1020.               (int) (trec->sec_recv / 3600.0),
  1021.               (int) (((int) trec->sec_recv % 3600) / 60),
  1022.               (int) ((int) trec->sec_recv % 60));
  1023. #ifdef HAVE_HDBUUCP
  1024.     (void) printf("Active UUCP ports:\t");
  1025.     (void) sprintf(buf, "%d", trec->devcnt);
  1026.     comma_fy(buf);
  1027.     (void) printf("%10s", buf);
  1028. #else
  1029.     (void) printf("\t\t\t\t");
  1030. #endif
  1031.     (void) printf("\tTotal time xmit:\t%4d:%02d:%02d\n",
  1032.               (int) (trec->sec_xmit / 3600.0),
  1033.               (int) (((int) trec->sec_xmit % 3600) / 60),
  1034.               (int) ((int) trec->sec_xmit % 60));
  1035. #ifdef HAVE_HDBUUCP
  1036.     (void) printf("Connections with work:\t");
  1037.     (void) sprintf(buf, "%ld", trec->num_in_conn + trec->num_out_conn);
  1038.     comma_fy(buf);
  1039.     (void) printf("%10s", buf);
  1040. #else
  1041.     (void) printf("\t\t\t\t");
  1042. #endif
  1043.     total_secs = trec->sec_recv + trec->sec_xmit;
  1044.     (void) printf("\tTotal UUCP time:\t%4d:%02d:%02d\n",
  1045.               (int) (total_secs / 3600.0),
  1046.               (int) (((long) total_secs % 3600) / 60),
  1047.               (int) ((long) total_secs % 60));
  1048.     (void) printf("\nTotal files rec'd:\t");
  1049.     (void) sprintf(buf, "%ld", trec->num_recv);
  1050.     comma_fy(buf);
  1051.     (void) printf("%10s", buf);
  1052.     (void) printf("\tTotal bytes rec'd:\t");
  1053.     (void) sprintf(buf, "%ld", trec->bytes_recv);
  1054.     comma_fy(buf);
  1055.     (void) printf("%10s\n", buf);
  1056.     (void) printf("Total files xmit:\t");
  1057.     (void) sprintf(buf, "%ld", trec->num_xmit);
  1058.     comma_fy(buf);
  1059.     (void) printf("%10s", buf);
  1060.     (void) printf("\tTotal bytes xmit:\t");
  1061.     (void) sprintf(buf, "%ld", trec->bytes_xmit);
  1062.     comma_fy(buf);
  1063.     (void) printf("%10s\n", buf);
  1064.     (void) printf("Total files:\t\t");
  1065.     (void) sprintf(buf, "%ld", trec->num_xmit + trec->num_recv);
  1066.     comma_fy(buf);
  1067.     (void) printf("%10s", buf);
  1068.     (void) printf("\tTotal bytes:\t\t");
  1069.     (void) sprintf(buf, "%ld", trec->bytes_xmit + trec->bytes_recv);
  1070.     comma_fy(buf);
  1071.     (void) printf("%10s\n", buf);
  1072.     return;
  1073. }
  1074.  
  1075. /*
  1076.  * print report header & report time range
  1077.  */
  1078. void 
  1079. printtmrng(trec, printopt)
  1080.     SUMM    *trec;
  1081.     int    printopt;
  1082. {
  1083.     static char    *months[] = {
  1084.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1085.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  1086.     };
  1087.     static int    IsAlreadyPrinted = FALSE;
  1088.  
  1089.     if (IsAlreadyPrinted) {
  1090.         putchar('\n');
  1091.         return;
  1092.     }
  1093.     (void) printf("%*sUUCP Traffic Report\n", 31, " ");
  1094.     if (trec->first_rec.tm_mon && trec->last_rec.tm_mon) {
  1095.         (void) printf("%*sFrom: %s %2d %02d:%02d   To: %s %2d %02d:%02d\n\n",
  1096.                   22, " ",
  1097.                   months[trec->first_rec.tm_mon-1],
  1098.                   trec->first_rec.tm_mday,
  1099.                   trec->first_rec.tm_hour,
  1100.                   trec->first_rec.tm_min,
  1101.                   months[trec->last_rec.tm_mon-1],
  1102.                   trec->last_rec.tm_mday,
  1103.                   trec->last_rec.tm_hour,
  1104.                   trec->last_rec.tm_min);
  1105.     }
  1106.     IsAlreadyPrinted = TRUE;
  1107.     return;
  1108. }
  1109.  
  1110. /*
  1111.  * put commas in long numeric strings contained in buf[]
  1112.  */
  1113. void
  1114. comma_fy(buf)
  1115.     char    buf[];
  1116. {
  1117.     int    i, ii, cnt;
  1118.     char    backw[BUFSIZ];
  1119.  
  1120.     /*
  1121.      * put string backwards inserting commas
  1122.      */
  1123.     for (ii = 0, cnt = 0, i = strlen(buf) - 1; i >= 0 ; i--) {
  1124.         backw[ii++] = buf[i];
  1125.         if (buf[i] == '.')
  1126.             cnt = 0;
  1127.         else if (++cnt == 3) {
  1128.             if (i && buf[i - 1] != '\0' && isdigit(buf[i - 1]))
  1129.                 backw[ii++] = ',';
  1130.             cnt = 0;
  1131.         }
  1132.     }
  1133.     backw[ii] = '\0';
  1134.     /*
  1135.      * put string forward
  1136.      */
  1137.     for (ii = 0, cnt = 0, i = strlen(backw) - 1; i >= 0 ; i--)
  1138.         buf[ii++] = backw[i];
  1139.     buf[ii]='\0';
  1140. }
  1141.  
  1142. cmp_t
  1143. cmpdev(a, b)
  1144.     PORT    *a,
  1145.         *b;        /* we rely on alignment of char * */
  1146. {
  1147.     float            aw = 0, bw = 0;
  1148.     extern unsigned short    sort_dev_f;
  1149.  
  1150.     if (sort_dev_f & RECEIVED) {
  1151.         aw += a->p_recv;
  1152.         bw += b->p_recv;
  1153.     }
  1154.     if (sort_dev_f & XMIT) {
  1155.         aw += a->p_xmit;
  1156.         bw += b->p_xmit;
  1157.     }
  1158.     if (sort_dev_f & R_TIME) {
  1159.         aw += a->p_recv_time;
  1160.         bw += b->p_recv_time;
  1161.     }
  1162.     if (sort_dev_f & X_TIME) {
  1163.         aw += a->p_xmit_time;
  1164.         bw += b->p_xmit_time;
  1165.     }
  1166.     if (sort_dev_f & R_CPS) {
  1167.         if (a->p_recv_time != 0)
  1168.             aw += (float) a->p_recv / (float) a->p_recv_time;
  1169.         if (b->p_recv_time != 0)
  1170.             bw += (float) b->p_recv / (float) b->p_recv_time;
  1171.     }
  1172.     if (sort_dev_f & X_CPS) {
  1173.         if (a->p_xmit_time != 0)
  1174.             aw += (float) a->p_xmit / (float) a->p_xmit_time;
  1175.         if (b->p_xmit_time != 0)
  1176.             bw += (float) b->p_xmit / (float) b->p_xmit_time;
  1177.     }
  1178.     if (sort_dev_f & R_NUMB) {
  1179.         aw += a->p_recv_cnt;
  1180.         bw += b->p_recv_cnt;
  1181.     }
  1182.     if (sort_dev_f & X_NUMB) {
  1183.         aw += a->p_xmit_cnt;
  1184.         bw += b->p_xmit_cnt;
  1185.     }
  1186.     if (!sort_dev_f || (sort_sys_f == REVERSE) || ((aw == 0) && (bw == 0)))
  1187.         aw = strcmp(b->p_dname, a->p_dname);
  1188.     if (sort_sys_f & REVERSE)
  1189.         return((cmp_t) (aw - bw));
  1190.     else
  1191.         return((cmp_t) (bw - aw));
  1192. }
  1193.  
  1194. cmp_t
  1195. cmpsys(a, b)
  1196.     LINK    *a,
  1197.         *b;
  1198. {
  1199.     float            aw = 0, bw = 0;
  1200.     extern unsigned short    sort_sys_f;
  1201.  
  1202.     if (sort_sys_f & RECEIVED) {
  1203.         aw += a->l_recv;
  1204.         bw += b->l_recv;
  1205.     }
  1206.     if (sort_sys_f & XMIT) {
  1207.         aw += a->l_xmit;
  1208.         bw += b->l_xmit;
  1209.     }
  1210.     if (sort_sys_f & R_TIME) {
  1211.         aw += a->l_recv_time;
  1212.         bw += b->l_recv_time;
  1213.     }
  1214.     if (sort_sys_f & X_TIME) {
  1215.         aw += a->l_xmit_time;
  1216.         bw += b->l_xmit_time;
  1217.     }
  1218.     if (sort_sys_f & R_CPS) {
  1219.         if (a->l_recv_time != 0)
  1220.             aw += (float) a->l_recv / (float) a->l_recv_time;
  1221.         if (b->l_recv_time != 0)
  1222.             bw += (float) b->l_recv / (float) b->l_recv_time;
  1223.     }
  1224.     if (sort_sys_f & X_CPS) {
  1225.         if (a->l_xmit_time != 0)
  1226.             aw += (float) a->l_xmit / (float) a->l_xmit_time;
  1227.         if (b->l_xmit_time != 0)
  1228.             bw += (float) b->l_xmit / (float) b->l_xmit_time;
  1229.     }
  1230.     if (sort_sys_f & R_NUMB) {
  1231.         aw += a->l_recv_cnt;
  1232.         bw += b->l_recv_cnt;
  1233.     }
  1234.     if (sort_sys_f & X_NUMB) {
  1235.         aw += a->l_xmit_cnt;
  1236.         bw += b->l_xmit_cnt;
  1237.     }
  1238.     if (!sort_sys_f || (sort_sys_f == REVERSE) || ((aw == 0) && (bw == 0)))
  1239.         aw = strcmp(b->l_sysname, a->l_sysname);
  1240.     if (sort_sys_f & REVERSE)
  1241.         return((cmp_t) (aw - bw));
  1242.     else
  1243.         return((cmp_t) (bw - aw));
  1244. }
  1245.  
  1246.  
  1247. void
  1248. usage_err(arg0, msg)
  1249.     char    *arg0;
  1250.     char    *msg;
  1251. {
  1252.     (void) fprintf(stderr, "\nUsage: %s [options] [xferstat_file | -]\n", arg0);
  1253.     if (msg && *msg)
  1254.         (void) fprintf(stderr, "%s\n", msg);
  1255.     exit(2);
  1256.     /* NOTREACHED */
  1257. }
  1258.  
  1259.