news1@texbell.swbt.com (Greg Hackney) (02/03/90)
uutraf analyzes uucico log files, and produces a summarized report. It helps in keeping track of UUCP volume and transfer rates. It now includes support for BSD UUCP systems as well as HoneyDanBer/BNU UUCP. Plus, the report format has been improved. uutraf is know to work on a Pyramid, NCR Tower, Sequent Balance, Sun 3/50, Compaq running SCO Xenix, and AT&T 3B2. -- Greg Hackney Southwestern Bell Telephone Co. Dallas, Texas hack@texbell.swbt.com #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: CREDITS Makefile README defs.h strtok.c uutraf.1 uutraf.c # uutraf.h uutraf.nro # Wrapped by root@texbell on Fri Feb 2 20:19:46 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'CREDITS' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'CREDITS'\" else echo shar: Extracting \"'CREDITS'\" \(504 characters\) sed "s/^X//" >'CREDITS' <<'END_OF_FILE' X XAcknowledgements: X X--------------------------- XDoug Davis, doug@letni.uucp XDavid Butler, gdb@ninja.uucp X - Added the sorting routines, plus other major work X--------------------------- XBud Hovell, bhh@whizz.uucp X - Reworked the printout for readability and precision X--------------------------- XDavid Kaelbing, drk@igor.uu.net X - Made it work with Sun's version of UUCP X--------------------------- XJoe Garvey, garvey%cmic@mips.com X - Fixed core dumps on empty files X--------------------------- X END_OF_FILE if test 504 -ne `wc -c <'CREDITS'`; then echo shar: \"'CREDITS'\" unpacked with wrong size! fi # end of 'CREDITS' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1013 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# @(#) FILE: Makefile X# @(#) Release: 1.2 X# @(#) Rel. Date: 2/2/90 X# @(#) Author: Greg Hackney (hack@texbell.swbt.com) X# X# Makefile for uutraf X# X# Usage: X# make uutraf X# make man X# make install X# make clean X# make clobber X# make shar X X# ----<Pick one>---- X# --AT&T BNU, HoneyDanBer, & Pyramid ATT Universe-- XCFLAGS = -O X# --BSD UUCP, Sun UUCP, & Pyramid UCB Universe-- X#CFLAGS = -O -DBSD X XBIN=/usr/lbin X XCATMAN = /usr/catman/l_man/man1 X XFORMATTER = nroff -man X XOBJECTS = uutraf.o strtok.o XSOURCES = uutraf.c strtok.c XINCLUDES = uutraf.h defs.h X X Xdefault: all X Xall: uutraf X Xman: uutraf.man X Xuutraf: $(OBJECTS) X cc $(CFLAGS) $(LFLAGS) $(OBJECTS) -o uutraf $(LIBS) X X$(OBJECTS): $(INCLUDES) X cc $(CFLAGS) -c $< X Xuutraf.man: uutraf.1 X $(FORMATTER) uutraf.1 > uutraf.man X Xinstall: all X cp uutraf $(BIN)/uutraf X chmod 755 $(BIN)/uutraf X Xclean: X rm -f *.o X Xclobber: clean X rm -f uutraf uutraf.man X Xshar: X shar Makefile uutraf.1 $(INCLUDES) $(SOURCES) > uutraf.shar END_OF_FILE if test 1013 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(695 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X XOVERVIEW X-------- Xuutraf is a program that analyzes the output of uucico log files, Xand produces a summary of activity. It works with both BSD style UUCP Xand AT&T's BNU or HoneyDanBer UUCP. It requires no special privileges Xto execute. It makes no shell calls. X XTO COMPILE X---------- XFirst edit the "Makefile": CFLAGS, BIN, FORMATTER X XType "make", and it should produce an executable called 'uutraf'. XIf it runs okay, type "make install". X XMANUALS X------- XIf you don't have nroff or troff, 'uutraf.nro' is a readable manual page. XOtherwise, type "make man" and it should produce a manual page, 'uutraf.man'. X X-- XGreg Hackney XSouthwestern Bell Telephone Co. Xhack@texbell.swbt.com XDallas, Texas X END_OF_FILE if test 695 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'defs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'defs.h'\" else echo shar: Extracting \"'defs.h'\" \(1410 characters\) sed "s/^X//" >'defs.h' <<'END_OF_FILE' X/* X X @(#) FILE: defs.h X @(#) Release: 1.2 X @(#) Rel. Date: 2/2/90 X @(#) Author: Greg Hackney (hack@texbell.swbt.com) X X*/ X X/* This file contains user defined parameters */ X X X#ifdef BSD X#define STATFILE "/usr/spool/uucp/SYSLOG" X#else X#define STATFILE "/usr/spool/uucp/.Admin/xferstats" X#endif X X/* default way to sort */ X#define DEFAULT (RECEIVED | XMIT) /* Total number of bytes */ X X/* you can instead pick from one of these for the default sorting method. X Sort by number of bytes X #define DEFAULT (RECEIVED) X #define DEFAULT (XMIT) X #define DEFAULT (RECEIVED | XMIT) X #define DEFAULT (RECEIVED | REVERSE) X #define DEFAULT (XMIT | REVERSE) X #define DEFAULT (RECEIVED | XMIT | REVERSE) X X Sort by transfer rate X #define DEFAULT (R_CPS) X #define DEFAULT (X_CPS) X #define DEFAULT (R_CPS | X_CPS) X #define DEFAULT (R_CPS | REVERSE) X #define DEFAULT (X_CPS | REVERSE) X #define DEFAULT (R_CPS | X_CPS | REVERSE) X X Sort by number of file transactions X #define DEFAULT (R_NUMB) X #define DEFAULT (X_NUMB) X #define DEFAULT (R_NUMB | X_NUMB) X #define DEFAULT (R_NUMB | REVERSE) X #define DEFAULT (X_NUMB | REVERSE) X #define DEFAULT (R_NUMB | X_NUMB | REVERSE) X X Sort by modem clock time X #define DEFAULT (R_TIME) X #define DEFAULT (X_TIME) X #define DEFAULT (X_TIME | R_TIME) X #define DEFAULT (R_TIME | REVERSE) X #define DEFAULT (X_TIME | REVERSE) X #define DEFAULT (X_TIME | R_TIME | REVERSE) X */ X END_OF_FILE if test 1410 -ne `wc -c <'defs.h'`; then echo shar: \"'defs.h'\" unpacked with wrong size! fi # end of 'defs.h' fi if test -f 'strtok.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'strtok.c'\" else echo shar: Extracting \"'strtok.c'\" \(912 characters\) sed "s/^X//" >'strtok.c' <<'END_OF_FILE' X/* File : strtok.c X Original Author : Richard A. O'Keefe. X Dated: 11 April 1984 X Public domain X X @(#) FILE: strtok.c X @(#) Release: 1.1 X @(#) Rel. Date: 2/2/90 X @(#) By: Greg Hackney (hack@texbell.swbt.com) X X*/ X X#ifdef SCCSID Xstatic char sccsid[] = "@(#) file strtok.c : rel 1.1 : mod 2/2/90"; X#endif X X Xstatic char *oldSrc = ""; Xint _set_ctr = 127; Xchar _set_vec[128]; X X#ifdef BSD Xchar *strtok(src, set) X register char *src; X char *set; X { X char *save; X X _str2set(set); X if (src == (char *)0) src = oldSrc; X while (_set_vec[*src] == _set_ctr) src++; X if (!*src) return (char *)0; X save = src; X while (_set_vec[*++src] != _set_ctr) ; X *src++ = 0; X oldSrc = src; X return save; X } X X_str2set(set) X register char *set; X { X if (set == (char *)0) return; X if (++_set_ctr == 128) { X _set_ctr = 1; X } X while (*set) _set_vec[*set++] = _set_ctr; X } X#endif X END_OF_FILE if test 912 -ne `wc -c <'strtok.c'`; then echo shar: \"'strtok.c'\" unpacked with wrong size! fi # end of 'strtok.c' fi if test -f 'uutraf.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uutraf.1'\" else echo shar: Extracting \"'uutraf.1'\" \(1511 characters\) sed "s/^X//" >'uutraf.1' <<'END_OF_FILE' X.TH UUTRAF USENET X.SH NAME Xuutraf X- UUCP file transfer statistics X.SH SYNOPSIS X.B uutraf X[options] [xferstat_file | -] X.br X.SH DESCRIPTION X.I uutraf Xanalyzes uucp log files, and provides a report on transfer statistics, Xusing a default sorting format, or an optional user specified sorting format. X.SH OPTIONS X.B \-s Xtake the input from stdin rather than a file. X.br X.sp XSorting Options: X.br X.B \-b[r|x|b] Xby number of bytes <r>ecd, <x>mit, or <b>oth. X.br X.B \-c[r|x|b] Xby transfer rate in <r>ecv, <x>mit, or <b>oth. X.br X.B \-n[r|x|b] Xby number of files <r>ecd, <x>mit, or <b>oth. X.br X.B \-t[r|x|b] Xby connect time in <r>ecv, <x>mit, or <b>oth. X.br X.B \-a Xsort in asending order, rather than desending. X.br X.SH EXAMPLES X.B uutraf \-bb Xwill display the total bytes transfered, in desending order. XThis is also the default sorting method. X.PP X.B uutraf \-cx Xwill display the connections with the fastest transfer rates, Xin decending order. X.PP X.B uutraf \-txa Xwill display the connections by total amount of modem connect time, Xin ascending sort order. X.PP X.SH BUGS XMultiple sorting options may not work as you would hope. With fast networks, Xthe time resolution of 1/10th an hour needs to be changed. X.SH NOTES XComments and bug reports are welcomed. X.SH AUTHOR XGreg Hackney, hack@texbell.swbt.com X.br X.SH CONTRIBUTORS XDoug Davis - doug@letni.uucp X.br XDavid Butler - gdb@ninja.uucp X.br XBud Hovell - bhh@whizz.uucp X.br XDavid Kaelbing - drk@igor.uu.net X.br XJoe Garvey - garvey%cmic@mips.com X END_OF_FILE if test 1511 -ne `wc -c <'uutraf.1'`; then echo shar: \"'uutraf.1'\" unpacked with wrong size! fi # end of 'uutraf.1' fi if test -f 'uutraf.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uutraf.c'\" else echo shar: Extracting \"'uutraf.c'\" \(11573 characters\) sed "s/^X//" >'uutraf.c' <<'END_OF_FILE' X/* X X @(#) FILE: uutraf.c X @(#) Release: 1.2 X @(#) Rel. Date: 2/2/90 X @(#) Author: Greg Hackney (hack@texbell.swbt.com) X X*/ X X#ifdef SCCSID Xstatic char sccsid[] = "@(#) file uutraf.c : rel 1.2 : mod 2/2/90"; X#endif X X#include "uutraf.h" X#include "defs.h" X Xstatic char XLog_name[1024]=STATFILE; /* name of uucp logging file, see defs.h */ X Xstatic Xfloat bytes_recv, /* total bytes received */ X bytes_xmit, /* total bytes transmitted */ X sec_recv, /* total seconds spent in receive */ X sec_xmit; /* total seconds spent in transmit */ X Xstatic Xlong X num_recv, /* total number of files received */ X num_xmit; /* total number of files transmitted */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int how = 0; /* default sort method, see defs.h */ X register LINK *slot; /* pointer to element */ X float bytes, /* number of bytes in the uucp xfer */ X seconds; /* number of seconds the xfer took */ X int c; X X X /*Check for options*/ X while(( c = getopt(argc,argv, "ab:c:n:t:s")) != EOF){ X switch(c) { X case 'a': /* sort in ascending vs. descending order */ X how |= REVERSE; X break; X case 'b': /* sort by bytes xmitted and/or received */ X switch(*optarg) { X case 'b': X how |= (RECEIVED | XMIT); X break; X case 'r': X how |= RECEIVED; X break; X case 'x': X how |= XMIT; X break; X default: X usage_err(argv[0]); X break; X } X break; X case 'c': /* sort by xfer rate xmitted and/or received */ X switch(*optarg) { X case 'b': X how |= (R_CPS | X_CPS); X break; X case 'r': X how |= R_CPS; X break; X case 'x': X how |= X_CPS; X break; X default: X usage_err(argv[0]); X break; X } X break; X case 'n': /* number of transactions */ X switch(*optarg) { X case 'b': X how |= (R_NUMB | X_NUMB); X break; X case 'r': X how |= R_NUMB; X break; X case 'x': X how |= X_NUMB; X break; X default: X usage_err(argv[0]); X break; X } X break; X case 't': /* sort by clock time */ X switch(*optarg) { X case 'b': X how |= (R_TIME | X_TIME); X break; X case 'r': X how |= R_TIME; X break; X case 'x': X how |= X_TIME; X break; X default: X usage_err(argv[0]); X break; X } X break; X case 's': /* Use stdin instead of normal xferstat file */ X logfile = stdin; X break; X default: X usage_err(argv[0]); X break; X } X } X X /* Use default sorting method if none was chosen */ X if ((how == REVERSE) || !how) X how |= DEFAULT; X X if(argc != optind) { /*input from an optional file name*/ X if((argc - optind) > 1) /*more than 1 file*/ X usage_err(argv[0]); X if(logfile != (FILE *)NULL) /* If stdin was already specified */ X usage_err(argv[0]); X strcpy(Log_name, argv[--argc]); X if((strcmp(Log_name,"-"))==0) X logfile=stdin; X } X else { X if(logfile == (FILE *)NULL) X strcpy(Log_name,STATFILE); X } X X /* See if specified file can be read */ X if (logfile == (FILE *) NULL){ /* not stdin */ X if((logfile=fopen(Log_name, "r"))==NULL){ X fprintf(stderr,"%s: Can't open the xferstat file %s for reading\n",argv[0],Log_name); X exit(1); X } X } X /* initialize the linked list */ X record = (LINK *) NULL; X X while (fgets(buf, 512, logfile) != NULL) { X X /* look for the node name */ X#ifdef BSD X if (((sys = strtok(buf, " ")) == NULL) || X ((sys = strtok((char *)NULL, " ")) == NULL)){ X#else X if ((sys = strtok(buf, "!")) == NULL) { X#endif X continue; X } X X /* skip over unnecessary data */ X#ifdef BSD X if (((string = strtok((char *) NULL, " ")) == NULL) || X ((string = strtok((char *) NULL, " ")) == NULL)) { X#else X if ((string = strtok((char *) NULL, "]")) == NULL) { X#endif X continue; X } X X /* parse the remainder of the data string */ X if ((string = strtok((char *) NULL, "\n")) == NULL) { X continue; X } X X /* convert the information */ X#ifdef BSD X if (sscanf(string, "%s data %f bytes %f secs", X#else X if (sscanf(string, "%s %f / %f", X#endif X flow, &bytes, &seconds) == EOF) { X continue; X } X X /* see if it's outgoing uucp */ X#ifdef pyr X if ((strcmp(flow, OUT) == 0) || X (strcmp(flow, T_OUT) == 0) || X (strcmp(flow, F_OUT) == 0)) { X#else X if (strcmp(flow, OUT) == 0) { X#endif X /* assign an array slot for this node name */ X if ((slot = getslot(sys)) == (LINK *) NULL) { X exit(1); X } X slot->xmit += bytes; X slot->xmit_time += seconds; X slot->xmit_cnt++; X bytes_xmit += bytes; /* summary totals */ X sec_xmit += seconds; X num_xmit++; X } else if /* incoming uucp */ X#ifdef pyr X ((strcmp(flow, IN) == 0) || X (strcmp(flow, T_IN) == 0) || X (strcmp(flow, F_IN) == 0)) { X#else X (strcmp(flow, IN) == 0) { X#endif X /* assign an array slot for this node name */ X if ((slot = getslot(sys)) == (LINK *) NULL) { X exit(1); X } X slot->recv += bytes; X slot->recv_time += seconds; X slot->recv_cnt++; X bytes_recv += bytes; /* summary totals */ X sec_recv += seconds; X num_recv++; X } X } X if (record != (LINK *) NULL) /* if we got some data */ X sortrun(how); /* sort it */ X printrun(); /* print it out */ X fclose(logfile); X exit(0); X} X Xstatic LINK * Xgetslot(s) /* returns an link struct to the system name specified. */ Xchar *s; X{ X LINK *work, *last; X X work = record; X if (work == (LINK *) NULL) { /* must be the first time thru */ X work = (LINK *) malloc(sizeof(LINK) + strlen(s)); X if (work == (LINK *) NULL) { X perror("getslot() malloc() failed, returning NULL -- "); X return(work); X } X zeroit(work); X strcpy(work->sysname, s); X record = work; X return(work); X } X X while (work != (LINK *) NULL){ X if (!strcmp(work->sysname, s)) { X return(work); X } X last = work; X work = work->next; X } X X /* create a new link */ X if ((work = (LINK *) malloc(sizeof(LINK) + strlen(s))) == X (LINK *) NULL) { X perror("getslot() malloc() failed, returning NULL -- "); X return(work); X } X X zeroit(work); X last->next = work; X work->prev = last; X strcpy(work->sysname, s); X return(work); X} X Xstatic Xzeroit(l) XLINK *l; X{ X /* added for portability vs. memset/bzero */ X l->prev = (LINK *) NULL; X l->next = (LINK *) NULL; X l->recv = 0.0; X l->recv_time = 0.0; X l->recv_cnt = 0L; X l->xmit = 0.0; X l->xmit_time = 0.0; X l->xmit_cnt = 0L; X l->sysname[0] = '\0'; X} X Xprintrun() X{ X LINK *work; X int count = 0; X X printf("%-8s ", "\nRemote "); X printf("%26s ", "-----------K-Bytes-----------"); X printf("%12s ", "----Hours----"); X printf("%10s ", "--Avg CPS--"); X printf("%8s ", "--Files--\n"); X X printf("%-7s ", "Host "); X printf("%9s ", "Recv"); X printf("%9s ", "Sent"); X printf("%9s ", "Total"); X printf("%6s ", "Recv"); X printf("%6s ", "Sent"); X printf("%5s ", "Recv"); X printf("%5s ", "Sent"); X printf("%4s ", "Recv"); X printf("%4s\n", "Sent"); X X printf("%s ", "------ "); X printf("%s ", "---------"); X printf("%s ", "---------"); X printf("%s ", "---------"); X printf("%s ", "------"); X printf("%s ", "------"); X printf("%s ", "-----"); X printf("%s ", "-----"); X printf("%s ", "----"); X printf("%s\n", "----"); X X for (work = record; work != (LINK *) NULL;) { X count++; X strncpy(buf, work->sysname, 9); X buf[9]='\0'; X printf("%-9s", buf); X sprintf(buf, "%.1f", work->recv / 1000); X printf("%9s ", buf); X sprintf(buf, "%.1f", work->xmit / 1000); X printf("%9s ", buf); X sprintf(buf, "%.1f", (work->xmit + work->recv) / 1000); X printf("%9s ", buf); X sprintf(buf, "%.1f", work->recv_time / 3600); X printf("%6s ", buf); X sprintf(buf, "%.1f", work->xmit_time / 3600); X printf("%6s ", buf); X if (work->recv_time != 0.0) { /* divide by zero ? */ X sprintf(buf, "%5.0f", work->recv / work->recv_time); X } else { X sprintf(buf, "0"); X } X printf("%5s ", buf); X if(work->xmit_time != 0.0) { /* divide by zero ? */ X sprintf(buf, "%5.0f", work->xmit / work->xmit_time); X } else { X sprintf(buf, "0"); X } X printf("%5s ", buf); X printf("%4d ", work->recv_cnt); X printf("%4d\n", work->xmit_cnt); X work = work->next; X } X /* summary statement at the end */ X printf("\n -------------SUMMARY-------------\n"); X printf(" Total active uucp sites:"); X sprintf(buf,"%d",count); comma_fy(); X printf("%7s\n",buf); X X /* total files */ X printf(" Total files recv: "); X sprintf(buf,"%ld",num_recv); comma_fy(); X printf("%12s\n",buf); X printf(" Total files sent: "); X sprintf(buf,"%ld",num_xmit); comma_fy(); X printf("%12s\n",buf); X printf(" Total files: "); X sprintf(buf,"%ld",num_xmit + num_recv); comma_fy(); X printf("%12s\n",buf); X X /* total time */ X printf(" Total hours recv: "); X sprintf(buf,"%.1f",sec_recv / 3600); X printf("%12s\n",buf); X printf(" Total hours sent: "); X sprintf(buf,"%.1f",sec_xmit / 3600); X printf("%12s\n",buf); X printf(" Total hours: "); X sprintf(buf,"%.1f",(sec_recv + sec_xmit) / 3600); X printf("%12s\n",buf); X X /* total bytes */ X printf(" Total K-bytes recv: "); X sprintf(buf,"%.0f",bytes_recv / 1000); comma_fy(); X printf("%10s\n",buf); X printf(" Total K-bytes sent: "); X sprintf(buf,"%.0f",bytes_xmit / 1000); comma_fy(); X printf("%10s\n",buf); X printf(" Total K-bytes: "); X sprintf(buf,"%.0f",(bytes_xmit + bytes_recv) / 1000); comma_fy(); X printf("%10s\n\n",buf); X X} X Xcomma_fy() /* put commas in long numeric strings contained in buf[] */ X{ X int i, ii, cnt; X char backw[25]; X X /* put string backwards inserting commas */ X for(ii=0, cnt=0,i=strlen(buf) - 1; i >= 0 ; i--){ X backw[ii++] = buf[i]; X if(++cnt == 3){ X if(buf[i-1] != '\0') X backw[ii++] = ','; X cnt = 0; X } X } X backw[ii] = '\0'; X X /* put string forward */ X for(ii=0, cnt=0,i=strlen(backw) - 1; i >= 0 ; i--) X buf[ii++] = backw[i]; X buf[ii]='\0'; X X} X Xsortrun(how) Xunsigned short how; X{ X LINK *work; X int swapped; X X do { X for (swapped = 0, work = record; work->next != (LINK *) NULL;) { X if (do_test(work, work->next, how) < 0) { X if (work->prev != (LINK *) NULL) { X work->prev->next = work->next; X } else { X record = work->next; X } X work->next->prev = work->prev; X work->prev = work->next; X if (work->next->next != (LINK *) NULL) { X work->next->next->prev = work; X } X work->next = work->next->next; X /* this is the weird one */ X /* (work->prev was work->next) */ X work->prev->next = work; X swapped = 1; X } else { X work = work->next; X } X } X } while (swapped); X} X Xdo_test(a, b, how) XLINK *a, *b; Xunsigned short how; X{ X LINK *c; X long aw = 0L, bw = 0L; X X /* reverse the sort, least to most */ X if (how & REVERSE) { X /* swap the pointers around, faster than a complex if */ X c = a; X a = b; X b = c; X } X if (how & RECEIVED) { X aw += a->recv; X bw += b->recv; X } X if (how & XMIT) { X aw += a->xmit; X bw += b->xmit; X } X if (how & R_TIME) { X aw += (long) a->recv_time; X bw += (long) b->recv_time; X } X if (how & X_TIME) { X aw += (long) a->xmit_time; X bw += (long) b->xmit_time; X } X if (how & R_CPS) { X if (a->recv_time != 0.0) { X aw += (long) (a->recv / a->recv_time); X } X if (b->recv_time != 0.0) { X bw += (long) (b->recv / b->recv_time); X } X } X if (how & X_CPS) { X if (a->xmit_time != 0.0) { X aw += (long) (a->xmit / a->xmit_time); X } X if (b->xmit_time != 0.0) { X bw += (long) (b->xmit / b->xmit_time); X } X } X if (how & R_NUMB) { X aw += a->recv_cnt; X bw += b->recv_cnt; X } X if (how & X_NUMB) { X aw += a->xmit_cnt; X bw += b->xmit_cnt; X } X return(aw - bw); X} Xusage_err(arg0) Xchar *arg0; X{ X fprintf(stderr,"Usage: %s [options] [xferstat_file | -]\n", arg0); X fprintf(stderr,"%s\n",usage); X exit(1); X} END_OF_FILE if test 11573 -ne `wc -c <'uutraf.c'`; then echo shar: \"'uutraf.c'\" unpacked with wrong size! fi # end of 'uutraf.c' fi if test -f 'uutraf.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uutraf.h'\" else echo shar: Extracting \"'uutraf.h'\" \(2690 characters\) sed "s/^X//" >'uutraf.h' <<'END_OF_FILE' X/* X X @(#) FILE: uutraf.h X @(#) Release: 1.2 X @(#) Rel. Date: 2/2/90 X @(#) Author: Greg Hackney (hack@texbell.swbt.com) X X*/ X X#include <stdio.h> X#ifdef BSD X#include <strings.h> X#else X#include <string.h> X#endif Xchar *strtok(); X X X/* these defines are part of the sort routine to figure out how X * to sort the linked list X */ X#define REVERSE 0x0001 /* reverse the order, least to most */ X#define RECEIVED 0x0002 /* sort by received */ X#define XMIT 0x0004 /* sort by xmit */ X#define R_TIME 0x0010 /* sort by received time */ X#define X_TIME 0x0020 /* sort by xmit time */ X#define R_CPS 0x0100 /* sort by characters RECEIVED per second */ X#define X_CPS 0x0200 /* sort by characters TRANSMITTED per second */ X#define R_NUMB 0x1000 /* sort by number of RECEIVED transactions */ X#define X_NUMB 0x2000 /* sort by number of TRANSMITTED transactions */ X X#ifdef BSD X#define OUT "sent" X#define IN "received" X#else /* Most other BNU systems */ X#define OUT "->" /*uucp flow direction indicator*/ X#define IN "<-" /*uucp flow direction indicator*/ X#endif X X#ifdef pyr /* UUCP via TCP/IP on an ATT Pyramid */ X#define T_OUT "t->" /* t protocol outgoing */ X#define T_IN "t<-" /* t protocol incoming */ X#define F_OUT "f->" /* f protocol outgoing */ X#define F_IN "f<-" /* f protocol incoming */ X#endif X Xtypedef struct link { X struct link *prev; /* pointer to the previous entry */ X struct link *next; /* pointer to the next entry */ X float recv; /* num of bytes rec'd from remote system */ X float recv_time; /* total seconds spent in receive */ X long recv_cnt; /* total number of files received */ X float xmit; /* num of bytes sent to remote system */ X float xmit_time; /* total seconds spent in transmit */ X long xmit_cnt; /* total number of files sent */ X char sysname[1]; /* name of remote system */ X} LINK; X X Xstatic XFILE *logfile = (FILE *) NULL; /* file pointer to the xferstats file */ X Xstatic XLINK *record = (LINK *) NULL, *getslot(); X Xstatic Xchar *sys, /* holds the name of the previous remote node name */ X flow[10], /* holds the direction of uucp flow */ X buf[512], /* general purpose */ X *string; /* general purpose */ X Xstatic Xfloat bytes, /* number of bytes in the uucp xfer */ X seconds; /* number of seconds the xfer took */ X Xchar *malloc(), *optarg; Xint optind; X Xchar usage[]="\n\ X-s use standard input instead of default xferstats file\n\ X-b[rxb] sort by total bytes rec'd, xmit'ed, or both\n\ X-c[rxb] sort by chars per second rec'd, xmit'ed, or both\n\ X-n[rxb] sort by # of files rec'd, xmit'ed, or both\n\ X-t[rxb] sort by total clock time in rec, xmit, or both\n\ X-a sort in ascending vs. descending order\n"; END_OF_FILE if test 2690 -ne `wc -c <'uutraf.h'`; then echo shar: \"'uutraf.h'\" unpacked with wrong size! fi # end of 'uutraf.h' fi if test -f 'uutraf.nro' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uutraf.nro'\" else echo shar: Extracting \"'uutraf.nro'\" \(1840 characters\) sed "s/^X//" >'uutraf.nro' <<'END_OF_FILE' X X X X UUTRAF(USENET) UNIX System V UUTRAF(USENET) X X X X NAME X uutraf - UUCP file transfer statistics X X SYNOPSIS X uutraf [options] [xferstat_file | -] X X DESCRIPTION X uutraf analyzes uucp log files, and provides a report on X transfer statistics, using a default sorting format, or an X optional user specified sorting format. X X OPTIONS X -s take the input from stdin rather than a file. X X Sorting Options: X -b[r|x|b] by number of bytes <r>ecd, <x>mit, or <b>oth. X -c[r|x|b] by transfer rate in <r>ecv, <x>mit, or <b>oth. X -n[r|x|b] by number of files <r>ecd, <x>mit, or <b>oth. X -t[r|x|b] by connect time in <r>ecv, <x>mit, or <b>oth. X -a sort in asending order, rather than desending. X X EXAMPLES X uutraf -bb will display the total bytes transfered, in X desending order. This is also the default sorting method. X X uutraf -cx will display the connections with the fastest X transfer rates, in decending order. X X uutraf -txa will display the connections by total amount of X modem connect time, in ascending sort order. X X BUGS X Multiple sorting options may not work as you would hope. X With fast networks, the time resolution of 1/10th an hour X needs to be changed. X X NOTES X Comments and bug reports are welcomed. X X AUTHOR X Greg Hackney, hack@texbell.swbt.com X X CONTRIBUTORS X Doug Davis - doug@letni.uucp X David Butler - gdb@ninja.uucp X Bud Hovell - bhh@whizz.uucp X David Kaelbing - drk@igor.uu.net X Joe Garvey - garvey%cmic@mips.com X X X X X X X X Page 1 (printed 2/2/90) X X X END_OF_FILE if test 1840 -ne `wc -c <'uutraf.nro'`; then echo shar: \"'uutraf.nro'\" unpacked with wrong size! fi # end of 'uutraf.nro' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0