Annotation of coherent/g/usr/lib/uucp/tay104/contrib/uurate.c, revision 1.1.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.