Annotation of coherent/g/usr/lib/uucp/tay104/contrib/uurate.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * @(#)uurate.c 1.2 - Thu Sep  3 18:32:46 1992
        !             3:  *
        !             4:  * This program digests log and stats files in the "Taylor" format
        !             5:  * and outputs various statistical data to standard out.
        !             6:  *
        !             7:  * Author:
        !             8:  *     Bob Denny ([email protected])
        !             9:  *     Fri Feb  7 13:38:36 1992
        !            10:  *
        !            11:  * Original author:
        !            12:  *     Mark Pizzolato   [email protected]
        !            13:  *
        !            14:  * Edits:
        !            15:  *     Bob Denny - Fri Feb  7 15:04:54 1992
        !            16:  *     Heavy rework for Taylor UUCP. This was the (very old) uurate from
        !            17:  *     DECUS UUCP, which had a single logfile for activity and stats.
        !            18:  *      Personally, I would have done things differently, with tables
        !            19:  *      and case statements, but in the interest of time, I preserved
        !            20:  *      Mark Pizzolato's techniques and style.
        !            21:  *
        !            22:  *      Bob Denny - Sun Aug 30 14:18:50 1992
        !            23:  *      Changes to report format suggested by Francois Pinard and others.
        !            24:  *      Add summary report, format from uutraf.pl (perl script), again
        !            25:  *      thanks to Francois. Integrate and checkout with 1.03 of Taylor UUCP.
        !            26:  */
        !            27: 
        !            28: char version[] = "@(#) Taylor UUCP Log File Summary Filter, Version 1.2";
        !            29: 
        !            30: #include <ctype.h>             /* Character Classification     */
        !            31: #include <string.h>
        !            32: #include <math.h>
        !            33: 
        !            34: #include "uucp.h"
        !            35: 
        !            36: 
        !            37: #define _DEBUG_ 0
        !            38:        
        !            39: /*
        !            40:  * Direction of Calling and Data Transmission
        !            41:  */
        !            42: #define IN     0               /* Inbound              */
        !            43: #define OUT    1               /* Outbound             */
        !            44: 
        !            45: /*
        !            46:  * Data structures used to collect information
        !            47:  */
        !            48: struct File_Stats
        !            49:     {
        !            50:     int files;                 /* Files Transferred    */
        !            51:     unsigned long bytes;       /* Data Size Transferred*/
        !            52:     double time;               /* Transmission Time    */
        !            53:     };
        !            54: 
        !            55: struct Phone_Call
        !            56:     {
        !            57:     int calls;                 /* Call Count           */
        !            58:     int succs;                 /* Successful calls     */
        !            59:     double connect_time;       /* Connect Time Spent   */
        !            60:     struct File_Stats flow[2]; /* Rcvd & Sent Data     */
        !            61:     };
        !            62: 
        !            63: struct Execution_Command
        !            64:     {
        !            65:     struct Execution_Command *next;
        !            66:     char Commandname[64];
        !            67:     int count;
        !            68:     };
        !            69: 
        !            70: struct Host_entry
        !            71:     {
        !            72:     struct Host_entry *next;
        !            73:     char Hostname[32];
        !            74:     struct Execution_Command *cmds;    /* Local Activities */
        !            75:     struct Phone_Call call[2];         /* In & Out Activities */
        !            76:     };
        !            77: 
        !            78: /*
        !            79:  * Stuff for getopt()
        !            80:  */
        !            81: extern int optind;             /* GETOPT : Option Index                */
        !            82: extern char *optarg;           /* GETOPT : Option Value                */
        !            83: extern void *calloc();
        !            84: 
        !            85: static void fmtime();
        !            86: static void fmbytes();
        !            87: 
        !            88: /*
        !            89:  * Default files to read. Taken from Taylor compile-time configuration.
        !            90:  * Must look like an argvec, hence the dummy argv[0].
        !            91:  */
        !            92: static char *(def_logs[3]) = { "", LOGFILE, STATFILE };
        !            93: 
        !            94: /*
        !            95:  * Misc. strings for reports
        !            96:  */
        !            97: static char *(file_hdr[2]) = { "\nReceived file statistics:\n",
        !            98:                                 "\nSent file statistics\n" };
        !            99:   
        !           100: /*
        !           101:  * BEGIN EXECUTION
        !           102:  */
        !           103: main(argc, argv)
        !           104: int argc;
        !           105: char *argv[];
        !           106: {
        !           107:   char c;
        !           108:   char *p, *s;
        !           109:   struct Host_entry *hosts = NULL;
        !           110:   struct Host_entry *cur = NULL;
        !           111:   struct Host_entry *e;
        !           112:   struct Execution_Command *cmd;
        !           113:   struct Execution_Command *ec;
        !           114:   char Hostname[64];
        !           115:   FILE *Log = NULL;
        !           116:   char logline[1024];
        !           117:   char *logmsg;
        !           118:   int sent;
        !           119:   int called;
        !           120:   int show_files = 0;          /* I prefer boolean, but... */
        !           121:   int show_calls = 0;
        !           122:   int show_commands = 0;
        !           123:   int show_efficiency = 0;
        !           124:   int show_summary = 0;
        !           125:   int have_files = 0;
        !           126:   int have_calls = 0;
        !           127:   int have_commands = 0;  
        !           128:   int use_stdin = 0;
        !           129:   Hostname[0] = '\0';
        !           130: 
        !           131:   /*
        !           132:    * I wish the compiler had the #error directive!
        !           133:    */
        !           134: #if !HAVE_TAYLOR_LOGGING
        !           135:   fprintf(stderr, "uurate cannot be used with your configuration of\n");
        !           136:   fprintf(stderr, "Taylor UUCP. To use uurate you must be using the\n");
        !           137:   fprintf(stderr, "TAYLOR_LOGGING configuration.\n");
        !           138:   exit(1);
        !           139: #endif
        !           140: 
        !           141:   /*
        !           142:    * Process the command line arguments
        !           143:    */
        !           144:   while((c = getopt(argc, argv, "h:cfexai")) != EOF)
        !           145:     {
        !           146:       switch(c)
        !           147:        {
        !           148:        case 'h':
        !           149:          strcpy(Hostname, optarg);
        !           150:          break;
        !           151:        case 'c':
        !           152:          show_calls = 1;
        !           153:          break;
        !           154:        case 'f':
        !           155:          show_files = 1;
        !           156:          break;
        !           157:        case 'x':
        !           158:          show_commands = 1;
        !           159:          break;
        !           160:         case 'e':
        !           161:          show_efficiency = 1;
        !           162:          break;
        !           163:        case 'a':
        !           164:          show_calls = show_files = show_commands = show_efficiency = 1;
        !           165:          break;
        !           166:        case 'i':
        !           167:          use_stdin = 1;
        !           168:          break;
        !           169:         default :
        !           170:          goto usage;
        !           171:        }
        !           172:     }
        !           173: 
        !           174:   /*
        !           175:    * If no report switches given, show summary report.
        !           176:    */
        !           177:   if (show_calls == 0 && show_files == 0
        !           178:       && show_efficiency == 0 && show_commands == 0)
        !           179:     show_summary = 1;
        !           180:   
        !           181:   /*
        !           182:    * Adjust argv and argc to account for the args processed above.
        !           183:    */
        !           184:   argc -= (optind - 1);
        !           185:   argv += (optind - 1);
        !           186: 
        !           187:   /*
        !           188:    * If further args present, Assume rest are logfiles for us to process,
        !           189:    * otherwise, take input from Log and Stat files provided in the
        !           190:    * compilation environment of Taylor UUCP. If -i was given, Log already
        !           191:    * points to stdin and no file args are accepted.
        !           192:    */
        !           193:   if(argc == 1)                        /* No file arguments */
        !           194:     {
        !           195:       if (use_stdin)           /* If -i, read from stdin */
        !           196:        {
        !           197:          argc = 2;
        !           198:          Log = stdin;
        !           199:        }
        !           200:       else                     /* Read from current logs */
        !           201:        {
        !           202:           argc = 3;            /* Bash argvec to default log/stat files */
        !           203:           argv = &def_logs[0];
        !           204:         }
        !           205:     }
        !           206:   else if (use_stdin)          /* File args with -i is an error */
        !           207:     {
        !           208:       fprintf(stderr, "uurate (error): file args given with '-i'\n");
        !           209:       goto usage;
        !           210:     }
        !           211: 
        !           212: #if _DEBUG_
        !           213:   printf("\n");
        !           214: #endif
        !           215: 
        !           216:   /*
        !           217:    * MAIN LOGFILE PROCESSING LOOP
        !           218:    */
        !           219:   while (argc > 1)
        !           220:     {
        !           221: 
        !           222:       if (!use_stdin && (Log = fopen(argv[1], "r")) == NULL)
        !           223:        {
        !           224:          perror(argv[1]);
        !           225:          return;
        !           226:        }
        !           227: 
        !           228: #if _DEBUG_
        !           229:       printf("Reading %s...\n", (use_stdin ? "stdin" : argv[1]));
        !           230: #endif
        !           231:       
        !           232:       /*
        !           233:        * Read each line of the logfile and collect information
        !           234:        */
        !           235:       while (fgets(logline, sizeof(logline), Log))
        !           236:        {
        !           237:          /*
        !           238:           * The host name of the other end of the connection is
        !           239:           * always the second field of the log line, whether we
        !           240:           * are reading a Log file or a Stats file. Set 'p' to
        !           241:           * point to the second field, null-terminated. Skip
        !           242:           * the line if something is funny.
        !           243:           */
        !           244:          if (NULL == (p = strchr(logline, ' ')))
        !           245:            continue;
        !           246:          ++p;
        !           247:          if (NULL != (s = strchr(p, ' ')))
        !           248:            *s = '\0';
        !           249:          for (s = p; *s; ++s)
        !           250:            if (isupper(*s))
        !           251:              *s = tolower(*s);
        !           252:          /*
        !           253:           * Skip this line if we got -h <host> and
        !           254:           * this line does not contain that host name.
        !           255:           */
        !           256:          if (Hostname[0] != '\0')
        !           257:            if (0 != strcmp(p, Hostname))
        !           258:              continue;
        !           259:          /*
        !           260:           * We are within a call block now. If this line is a file
        !           261:           * transfer record, determine the direction. If not then
        !           262:           * skip the line if it is not interesting.
        !           263:           */
        !           264:          if ((s = strchr(++s, ')')) == NULL)
        !           265:            continue;
        !           266:          logmsg = s + 2;               /* Message is 2 characters after ')' */
        !           267:          if (0 == strncmp(logmsg, "sent", 4))
        !           268:            sent = OUT;
        !           269:          else
        !           270:            if (0 == strncmp(logmsg, "received", 8))
        !           271:              sent = IN;
        !           272:            else
        !           273:              if ((0 != strncmp(logmsg, "Call complete", 13)) &&
        !           274:                  (0 != strncmp(logmsg, "Calling system", 14)) &&
        !           275:                  (0 != strncmp(logmsg, "Incoming call", 13)) &&
        !           276:                  (0 != strncmp(logmsg, "Executing", 9)))
        !           277:                continue;
        !           278:          /*
        !           279:           * Find the Host_entry for this host, or create a new
        !           280:           * one and link it on to the list.
        !           281:           */
        !           282:          if ((cur == NULL) || (0 != strcmp(p, cur->Hostname)))
        !           283:            {
        !           284:              for (cur = hosts; cur != NULL ; cur = cur->next)
        !           285:                if (0 == strcmp(cur->Hostname, p))
        !           286:                  break;
        !           287:              if (cur == NULL)
        !           288:                {
        !           289:                  cur = (struct Host_entry *)calloc(1, sizeof(*hosts));
        !           290:                  strcpy(cur->Hostname, p);
        !           291:                  if (hosts == NULL)
        !           292:                    hosts = cur;
        !           293:                  else
        !           294:                    {
        !           295:                      for (e = hosts; e->next != NULL; e = e->next);
        !           296:                      e->next = cur;
        !           297:                    }
        !           298:                }
        !           299:            }
        !           300:          /*
        !           301:           * OK, if this is a uuxqt record, find the Execution_Command
        !           302:           * structure for the command being executed, or create a new
        !           303:           * one. Then count an execution of this command.
        !           304:           */
        !           305:          if (0 == strncmp(logmsg, "Executing", 9))
        !           306:            {
        !           307:              if (NULL == (p = strchr(logmsg, '(')))
        !           308:                continue;
        !           309:              if ((s = strpbrk(++p, " )")) == NULL)
        !           310:                continue;
        !           311:              *s = '\0';
        !           312:              for (cmd = cur->cmds; cmd != NULL; cmd = cmd->next)
        !           313:                if (0 == strcmp(cmd->Commandname, p))
        !           314:                  break;
        !           315:              if (cmd == NULL)
        !           316:                {
        !           317:                  cmd = (struct Execution_Command *)calloc(1, sizeof(*cmd));
        !           318:                  strcpy(cmd->Commandname, p);
        !           319:                  if (cur->cmds == NULL)
        !           320:                    cur->cmds = cmd;
        !           321:                  else
        !           322:                    {
        !           323:                      for (ec = cur->cmds; ec->next != NULL; ec = ec->next);
        !           324:                      ec->next = cmd;
        !           325:                    }
        !           326:                }
        !           327:              ++cmd->count;
        !           328:              have_commands = 1;
        !           329:              continue;
        !           330:            }
        !           331:          /*
        !           332:           * Count start of outgoing call.
        !           333:           */
        !           334:          if (0 == strncmp(logmsg, "Calling system", 14))
        !           335:            {
        !           336:              called = OUT;
        !           337:              cur->call[called].calls += 1;
        !           338:              have_calls = 1;
        !           339:              continue;
        !           340:            }
        !           341:          /*
        !           342:           * Count start of incoming call.
        !           343:           */
        !           344:          if (0 == strncmp(logmsg, "Incoming call", 13))
        !           345:            {
        !           346:              called = IN;
        !           347:              cur->call[called].calls += 1;
        !           348:              have_calls = 1;
        !           349:              continue;
        !           350:            }
        !           351:          /*
        !           352:           * Handle end of call. Pick up the connect time.
        !           353:           */
        !           354:          if (0 == strncmp(logmsg, "Call complete", 13))
        !           355:            {
        !           356:              cur->call[called].succs += 1;
        !           357:              if (NULL == (s = strchr(logmsg, '(')))
        !           358:                continue;
        !           359:              cur->call[called].connect_time += atof(s+1);
        !           360:              continue;
        !           361:            }
        !           362:          /*
        !           363:           * If we reached here, this must have been a file transfer
        !           364:           * record. Count it in the field corresponding to the
        !           365:           * direction of the transfer. Count bytes transferred and
        !           366:           * the time to transfer as well.
        !           367:           */
        !           368:          have_files = 1;
        !           369:          cur->call[called].flow[sent].files += 1;
        !           370:          if (NULL == (s = strchr(logmsg, ' ')))
        !           371:            continue;
        !           372:          cur->call[called].flow[sent].bytes += atol(++s);
        !           373:          if (NULL == (s = strchr(s, ' ')))
        !           374:            continue;
        !           375:          if (NULL == (s = strpbrk(s, "0123456789")))
        !           376:            continue;
        !           377:          cur->call[called].flow[sent].time += atof(s);
        !           378:        }
        !           379:       argc -= 1;
        !           380:       argv += 1;
        !           381:       if(Log != stdin)
        !           382:        fclose(Log);
        !           383:     }
        !           384:   
        !           385:   /*
        !           386:    *     ***********
        !           387:    *     * REPORTS *
        !           388:    *     ***********
        !           389:    */
        !           390: 
        !           391:   /*
        !           392:    * Truncate the Hostnames to 8 characters at most.
        !           393:    */
        !           394:   for (cur = hosts; cur != NULL; cur = cur->next)
        !           395:     cur->Hostname[8] = '\0';
        !           396: 
        !           397: #if _DEBUG_
        !           398:   printf("\n");
        !           399: #endif
        !           400: 
        !           401:   /*
        !           402:    * Summary report
        !           403:    *
        !           404:    * I know, this code could be tightened (rbd)...
        !           405:    */
        !           406:   if(show_summary)
        !           407:     {
        !           408:       char t1[32], t2[32], t3[32], t4[32], t5[32];
        !           409:       long ib, ob, b, rf, sf;
        !           410:       long t_ib=0, t_ob=0, t_b=0, t_rf=0, t_sf=0;
        !           411:       double it, ot, ir, or;
        !           412:       double t_it=0.0, t_ot=0.0;
        !           413:       int nhosts = 0;
        !           414: 
        !           415:       printf("\n\
        !           416:  Remote  ------- Bytes -------- --- Time ---- -- Avg CPS -- -- Files --\n");
        !           417:       printf("\
        !           418:   Host      Rcvd    Sent   Total   Rcvd   Sent   Rcvd   Sent  Rcvd  Sent\n");
        !           419:       printf("\
        !           420: -------- ------- ------- ------- ------ ------ ------ ------ ----- -----\n");
        !           421:       for (cur = hosts; cur != NULL; cur = cur->next)
        !           422:        {
        !           423:          ib = (cur->call[IN].flow[IN].bytes + 
        !           424:                cur->call[OUT].flow[IN].bytes);
        !           425:          fmbytes(ib, t1);
        !           426:          t_ib += ib;
        !           427: 
        !           428:          ob = (cur->call[IN].flow[OUT].bytes + 
        !           429:                cur->call[OUT].flow[OUT].bytes);
        !           430:          fmbytes(ob, t2);
        !           431:          t_ob += ob;
        !           432: 
        !           433:          b = ib + ob;
        !           434:          fmbytes(b, t3);
        !           435:          t_b += b;
        !           436: 
        !           437:          it = cur->call[IN].flow[IN].time +
        !           438:            cur->call[OUT].flow[IN].time;
        !           439:          fmtime(it, t4);
        !           440:          t_it += it;
        !           441: 
        !           442:          ot = cur->call[IN].flow[OUT].time +
        !           443:            cur->call[OUT].flow[OUT].time;
        !           444:          fmtime(ot, t5);
        !           445:          t_ot += ot;
        !           446: 
        !           447:          rf = cur->call[IN].flow[IN].files +
        !           448:            cur->call[OUT].flow[IN].files;
        !           449:          t_rf += rf;
        !           450: 
        !           451:          sf = cur->call[IN].flow[OUT].files +
        !           452:            cur->call[OUT].flow[OUT].files;
        !           453:          t_sf += sf;
        !           454: 
        !           455:          ir = (it == 0.0) ? 0.0 : (ib / it);
        !           456:          or = (ot == 0.0) ? 0.0 : (ob / ot);
        !           457: 
        !           458:          printf("%-8s %7s %7s %7s %6s %6s %6.1f %6.1f %5d %5d\n",
        !           459:                 cur->Hostname,
        !           460:                 t1, t2, t3, t4, t5, 
        !           461:                 ir, or, rf, sf);
        !           462:        }
        !           463: 
        !           464:       if(nhosts > 1)
        !           465:        {
        !           466:          fmbytes(t_ib, t1);
        !           467:          fmbytes(t_ob, t2);
        !           468:          fmbytes(t_b, t3);
        !           469:          fmtime(t_it, t4);
        !           470:          fmtime(t_ot, t5);
        !           471:          ir = (t_it == 0.0) ? 0.0 : (t_ib / t_it);
        !           472:          or = (t_ot == 0.0) ? 0.0 : (t_ob / t_ot);
        !           473: 
        !           474:          printf("\
        !           475: -------- ------- ------- ------- ------ ------ ------ ------ ----- -----\n");
        !           476:          printf("\
        !           477: Totals   %7s %7s %7s %6s %6s %6.1f %6.1f %5d %5d\n",
        !           478:                 t1, t2, t3, t4, t5,
        !           479:                 ir, or, t_rf, t_sf);
        !           480:        }
        !           481:     }
        !           482: 
        !           483:          
        !           484:   /*
        !           485:    * Call statistics report
        !           486:    */
        !           487:   if(show_calls && have_calls)
        !           488:     {
        !           489:       char t1[32], t2[32];
        !           490: 
        !           491:       printf("\nCall statistics:\n");
        !           492:       printf("\
        !           493:      sysname   callto  failto    totime  callfm  failfm    fmtime\n");
        !           494:       printf("\
        !           495:      --------  ------  ------  --------  ------  ------  --------\n");
        !           496:       for (cur = hosts; cur != NULL; cur = cur->next)
        !           497:        {
        !           498:          fmtime(cur->call[OUT].connect_time, t1);
        !           499:          fmtime(cur->call[IN].connect_time, t2),
        !           500:          printf("     %-8s  %6d  %6d  %8s  %6d  %6d  %8s\n",
        !           501:                 cur->Hostname,
        !           502:                 cur->call[OUT].calls,
        !           503:                 cur->call[OUT].calls - cur->call[OUT].succs,
        !           504:                 t1,
        !           505:                 cur->call[IN].calls,
        !           506:                 cur->call[IN].calls - cur->call[IN].succs,
        !           507:                 t2);
        !           508:        }
        !           509:     }
        !           510: 
        !           511:   /*
        !           512:    * File statistics report
        !           513:    */
        !           514:   if(show_files && have_files)
        !           515:     {
        !           516:       char t1[32], t2[32];
        !           517: 
        !           518:       for (sent = IN; sent <= OUT; ++sent)
        !           519:        {
        !           520:          printf(file_hdr[sent]);
        !           521:          printf("     sysname    files     bytes  xfr time  byte/s\n");
        !           522:          printf("     --------  ------  --------  --------  ------\n");
        !           523:          for (cur = hosts; cur != NULL; cur = cur->next)
        !           524:            {
        !           525:              double rate;
        !           526:              double time;
        !           527:              
        !           528:              time = cur->call[IN].flow[sent].time +
        !           529:                cur->call[OUT].flow[sent].time;
        !           530:              if (time == 0.0)
        !           531:                continue;
        !           532:              rate = (cur->call[IN].flow[sent].bytes +
        !           533:                      cur->call[OUT].flow[sent].bytes) / time;
        !           534:              fmbytes((cur->call[IN].flow[sent].bytes + 
        !           535:                      cur->call[OUT].flow[sent].bytes), t1);
        !           536:              fmtime((cur->call[IN].flow[sent].time + 
        !           537:                     cur->call[OUT].flow[sent].time), t2);
        !           538:              printf("     %-8s  %6d  %8s  %8s  %6.1f\n",
        !           539:                     cur->Hostname,
        !           540:                     cur->call[IN].flow[sent].files + 
        !           541:                     cur->call[OUT].flow[sent].files,
        !           542:                     t1, t2, rate);
        !           543:            }
        !           544:        }
        !           545:     }
        !           546: 
        !           547:   /*
        !           548:    * Efficiency report
        !           549:    */
        !           550:   if (show_efficiency && have_files)
        !           551:     {
        !           552:       char t1[32], t2[32], t3[32];
        !           553:       double total, flow;
        !           554: 
        !           555:       printf("\nEfficiency:\n");
        !           556:       printf("     sysname   conntime  flowtime  ovhdtime  eff. %%\n");
        !           557:       printf("     --------  --------  --------  --------  ------\n");
        !           558:       for (cur = hosts; cur != NULL; cur = cur->next)
        !           559:        {
        !           560:          total = cur->call[IN].connect_time + cur->call[OUT].connect_time;
        !           561:          flow = cur->call[IN].flow[IN].time + cur->call[IN].flow[OUT].time +
        !           562:            cur->call[OUT].flow[IN].time + cur->call[OUT].flow[OUT].time;
        !           563:          fmtime(total, t1);
        !           564:          fmtime(flow, t2);
        !           565:          fmtime((total-flow), t3);
        !           566:          printf("     %-8s  %8s  %8s  %8s  %5.1f%%\n",
        !           567:                 cur->Hostname, t1, t2, t3, ((flow / total) * 100.0));
        !           568:        }
        !           569:     }
        !           570: 
        !           571:   /*
        !           572:    * Command execution report
        !           573:    */  
        !           574:   if (show_commands & have_commands)
        !           575:     {
        !           576:       printf("\nCommand executions:\n");
        !           577:       printf("     sysname    rmail   rnews   other\n");
        !           578:       printf("     --------  ------  ------  ------\n");
        !           579:       for (cur = hosts; cur != NULL; cur = cur->next)
        !           580:        {
        !           581:           int rmail, rnews, other;
        !           582:          
        !           583:          if (cur->cmds == NULL)
        !           584:            continue;
        !           585:           rmail = rnews = other = 0;
        !           586:          for (cmd = cur->cmds; cmd != NULL; cmd = cmd->next)
        !           587:            {
        !           588:              if (strcmp(cmd->Commandname, "rmail") == 0)
        !           589:                rmail += cmd->count;
        !           590:              else if (strcmp(cmd->Commandname, "rnews") == 0)
        !           591:                rnews += cmd->count;
        !           592:              else
        !           593:                other += cmd->count;
        !           594:            }
        !           595:          printf("     %-8s  %6d  %6d  %6d\n", cur->Hostname,
        !           596:                 rmail, rnews, other);
        !           597:        }
        !           598:     }
        !           599:   return;
        !           600:   
        !           601:  usage:
        !           602:   fprintf(stderr,
        !           603:       "Usage uurate [-cfexai] [-h hostname] [logfile ... logfile]\n");
        !           604:   fprintf(stderr,"where:\t-c\tReport call statistics\n");
        !           605:   fprintf(stderr, "\t-f\tReport file transfer statistics\n");
        !           606:   fprintf(stderr, "\t-e\tReport efficiency statistics\n");
        !           607:   fprintf(stderr, "\t-x\tReport command execution statistics\n");
        !           608:   fprintf(stderr, "\t-a\tAll of the above reports\n");  
        !           609:   fprintf(stderr, "\t-h host\tReport activities involving ONLY host\n");
        !           610:   fprintf(stderr, "\t-i\tRead log info from standard input\n");
        !           611:   fprintf(stderr,
        !           612:       "If no report options given, a compact summary report is given.\n");
        !           613:   fprintf(stderr,
        !           614:       "If neither -i nor logfiles given, defaults to reading from\n");
        !           615:   fprintf(stderr, "%s and %s\n\n", LOGFILE, STATFILE);
        !           616: }
        !           617: 
        !           618: /*
        !           619:  * fmtime() - Format time in hours & minutes;
        !           620:  */
        !           621: static void fmtime(dsec, buf)
        !           622:      double dsec;
        !           623:      char *buf;
        !           624: {
        !           625:   long hrs, min, lsec;
        !           626: 
        !           627:   lsec = dsec;
        !           628:   hrs = lsec / 3600L;
        !           629:   min = (lsec - (hrs * 3600L)) / 60L;
        !           630: 
        !           631:   sprintf(buf, "%02ld:%02ld", hrs, min);
        !           632: }
        !           633: 
        !           634: /*
        !           635:  * fmbytes - Format size in bytes
        !           636:  */
        !           637: static void fmbytes(n, buf)
        !           638:      unsigned long n;
        !           639:      char *buf;
        !           640: {
        !           641:   char t;
        !           642:   double s = n;
        !           643: 
        !           644:   if(s >= 10239897.6)          /* More than 9999.9K ? */
        !           645:     {
        !           646:       s = (double)n / 1048576.0;       /* Yes, display in Megabytes */
        !           647:       t = 'M';
        !           648:     }
        !           649:   else
        !           650:     {
        !           651:       s = (double)n / 1024.0;  /* Display in Kilobytes */
        !           652:       t = 'K';
        !           653:     }
        !           654: 
        !           655:   sprintf(buf, "%.1f%c", s, t);
        !           656: }
        !           657: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.