From harvard!uucp Mon Nov 18 19:32:44 1985 Received: from harvard.HARVARD.EDU by seismo.CSS.GOV with SMTP; Mon, 18 Nov 85 19:30:20 EST Received: by harvard.HARVARD.EDU; Mon, 18 Nov 85 19:31:07 EST From: harvard!uucp (Black Hole) Return-Path: Received: by panda.LOCAL on Mon, 18 Nov 85 18:41:07 est Date: Mon, 18 Nov 85 18:41:07 est Message-Id: <8511182341.AA22171@panda.LOCAL> To: talcott!seismo!rick Subject: uucpanz.S5 Status: R From: decvax!sun!amdahl!gam (Gordon A. Moffett) Date: Thu, 8 Nov 84 08:58:07 PST Subject: uucpanz for System V : This is a shar archive. Extract with sh, not csh. echo x - README sed -e 's/^X//' > README << '!Funky!Stuff!' XThe files herein are: X Xuucpanz.h - header file for uucpanz.c Xuucpanz.c - C program source XMakefile - instructions for compilation for make(1) Xuucpanz.1 - manual page XREADME - this file. X XNote that this is assured to work only on System V Release 2 sites. !Funky!Stuff! echo x - uucpanz.1 sed -e 's/^X//' > uucpanz.1 << '!Funky!Stuff!' X.TH UUCPANZ 1 X.SH NAME Xuucpanz \- summarize uucp statistics X.SH SYNOPSIS X.B uucpanz X[ X.B \-l Xlogfile ] [ X.B \-s Xsyslog ] X.SH DESCRIPTION X.I Uucpanz Xexamines the files X.I logfile Xand X.I syslog X(by default, /usr/spool/uucp/LOGFILE and /usr/spool/uucp/SYSLOG, Xrespectively) and produces a report summarizing the data therein. X.P XThe report consists of 4 parts: X.TP 15 XBy system: XThe number of bytes sent to and received from each uucp node, Xas well as the number of calls and their status, and the number Xof files transfered. An average number of bytes per second transmitted Xis printed for both directions, if applicable. X.TP 15 XBy user: XThe number of files and bytes sent by users (directly, via X.IR uucp (1), Xor indirectly by use of some other command). This list is roughly Xsorted in reverse order. X.TP 15 XBy commands: XCommands issued directly or indirectly via X.IR uux (1), Xwith a repetition count. X.TP 15 XBy day: XTotal number of bytes sent or received for each day. X.P XThe users, uucp nodes, commands, and days are those found in the Xtwo input files; if no activity occurs for some uucp site it is Xnot reported. X.SH FILES X.TP 24 X/usr/spool/uucp/LOGFILE Xdefault X.I logfile Xfrom which the summary of commands, phone calls, and file counts Xis created. X.TP 24 X/usr/spool/uucp/SYSLOG Xdefault X.I syslog Xfrom which the summary of bytes and connect times is created. X.SH SEE ALSO Xuusub(1), uustat(1) X.br X``UUCP Adminstration'' in the X.I XUnix Administrator Guide X.SH DIAGNOSTICS X.TP 20 X``Out of memory'' X.I Uucpanz Xdynamically allocates memory to build linked lists for the Xcommand and user summaries. The greater the number of unique Xcommands and usernames, the more memory is allocated. X.SH WARNINGS XThe program is very sensitive to the file formats for X.I logfile Xand X.I syslog Xand expects them to be just as they are produced by X.IR uucico (1m). X.SH BUGS XDoes not recover well from garbage data. X.P XThis program should be written in X.IR awk (1). !Funky!Stuff! echo x - uucpanz.h sed -e 's/^X//' > uucpanz.h << '!Funky!Stuff!' X#define SYSLOG "/usr/spool/uucp/SYSLOG" X#define LOGFILE "/usr/spool/uucp/LOGFILE" X#define MAXSYS 32 X Xstruct dayrec { X int used; /* used */ X long recv; /* bytes recv */ X long sent; /* bytes sent */ X long trecv; /* seconds spent rec */ X long tsent; /* seconds spent sending */ X}; X Xstruct sys1 { X char sname[9]; /* system name */ X long bbsent; /* bytes sent */ X long brec; /* bytes rec. */ X long btsent; /* time spen sending */ X long btrec; /* time spent rec */ X int suc; /* succesfull calls */ X int fail; /* calls fail */ X int ugot; /* number of files we got */ X int lock; /* times of locked */ X int usent; /* number of files we sent */ X int okstr; /* number of conversations started */ X int okstop; /* number of conversations stop */ X}; X Xstruct users { X char *name; /* login name */ X long bsent; /* bytes sent */ X long utim; /* time spent */ X long nsent; /* number sent */ X struct users *nuser; X}; X Xstruct call { X int times; X char *cname; X struct call *ncall; X}; !Funky!Stuff! echo x - uucpanz.c sed -e 's/^X//' > uucpanz.c << '!Funky!Stuff!' X/* X* uucpanz.c X* program to print out stats about uucp usage. X* X* Permission is given by me [ Brad Smith ] for the use, X* modification, and distribution of this program X* exception: It may not be sold for profit individually nor as part of any X* software package, regardless of modifications. X* X* X* Bradley Smith X* Bradley University X* {ihnp4,cepu,uiucdcs,noao}!bradley!brad X* X* modified for System V Release 2 X* by Gordon A. Moffett X* Amdahl Corporation X* {ihnp4,hplabs}!amdahl!gam X*/ X#include X#include X X#include "uucpanz.h" X Xstruct dayrec dayacc[13] [32]; Xstruct sys1 sysacc[MAXSYS]; Xstruct call *cmd, *tcall(); Xstruct users *usage; X Xstruct users *tree(); Xchar *getfield(); Xchar *strchr(); Xchar *malloc(), *strsave(); Xchar *strcpy(), *strcat(); Xvoid exit(); X Xlong byt, tim, atol(); Xint cmdcount; Xlong hour, min,second, hourtmp; XFILE *fpin; Xchar *logfile = LOGFILE; Xchar *syslog = SYSLOG; X Xchar *Cmdname; X Xmain(argc, argv) X int argc; X char *argv[]; X{ X char line[512], field[128], cx[128],*cp, *sp, *c; X char junk[512]; X char sysname[18], username[9]; X register int i,j; X int d, m; X int opt; X extern char *optarg; X extern int optind; X X Cmdname = argv[0]; X X while ( (opt = getopt(argc, argv, "l:s:")) != EOF) { X switch(opt) { X case 'l': X logfile = optarg; X break; X case 's': X syslog = optarg; X break; X case '?': X default: X tellem(); X } X } X/* intialize */ X usage = NULL; X cmdcount = 0; X cmd = NULL; X X/* lets do SYSLOG first */ X X if((fpin = fopen(syslog,"r")) == NULL) X error(syslog); X X while(fgets(line, sizeof line, fpin) != NULL) { X fgets(junk, sizeof junk, fpin); /* skip over 2nd line */ X strcpy(cx,getfield(2,line,' ')); X cp = cx; X cp++; /* puts at first number */ X c = cp; X cp++; X if(isdigit(*cp)) X cp++; X *cp = '\0'; X m = atoi(c); X cp++; X c = cp; X cp++; X if(isdigit(*cp)) X cp++; X *cp = '\0'; X d = atoi(c); X strcpy(sysname, getfield(0,line,' ')); X cp = strchr(sysname, '!'); X if (cp == NULL) { X fprintf(stderr, "%s\n", line); X error("no '!' in 0th field"); X } X *cp++ = '\0'; /* cp now points to user name */ X byt = atol(getfield(7,line,' ')); X tim = atol(getfield(9,line,' ')); X strcpy(username, cp); X strcpy(field,getfield(6,line,' ')); X X if(tindex(field,"->") != -1) { X for(i = 0;i < MAXSYS;i ++) { X if(strlen(sysacc[i].sname) <= 0) { X strcpy(sysacc[i].sname, sysname); X sysacc[i].bbsent = byt; X sysacc[i].btsent = tim; X break; X } X else if(strcmp(sysacc[i].sname, sysname) == 0) { X sysacc[i].bbsent += byt; X sysacc[i].btsent += tim; X break; X } X } X usage = tree(usage, username); X dayacc[m][d].sent += byt; X dayacc[m][d].tsent += tim; X dayacc[m][d].used = 1; X } X else { X dayacc[m][d].recv += byt; X dayacc[m][d].trecv += tim; X dayacc[m][d].used = 1; X for(i=0;i< MAXSYS; i++) { X if(strlen(sysacc[i].sname) <= 0) { X strcpy(sysacc[i].sname, sysname); X sysacc[i].brec = byt; X sysacc[i].btrec = tim; X break; X } X else if(strcmp(sysacc[i].sname, sysname) == 0) { X sysacc[i].brec += byt; X sysacc[i].btrec += tim; X break; X } X } X } X } X fclose(fpin); X X if((fpin = fopen(logfile,"r")) == NULL ) X error(logfile); X X while(fgets(line, sizeof line, fpin) != NULL) { X c = getfield(3,line,' '); X strcpy(sysname, getfield(0, line, ' ')); X sp = strchr(sysname, '!'); X if (sp == NULL) { X fprintf(stderr, "%s\n", line); X error("no '!' in 0th field"); X } X *sp++ = '\0'; X if(strcmp(c,"XQT") == 0) { X strcpy(field, sysname); X strcat(field, "!"); X strcat(field,getfield(3,line,'(')); X field[strlen(field)-3] = '\0'; X cmd = tcall(cmd,field); X } X else if(tindex(getfield(4,line,' '),"call") != -1) { X cp = getfield(3,line,' '); X if(strcmp(cp,"SUCCEEDED") == 0) X for(i=0;i< MAXSYS;i++) { X if(strcmp(sysacc[i].sname,sysname) == 0) X sysacc[i].suc++; X } X else if(strcmp(cp,"FAILED") == 0) { X for(i=0;i< MAXSYS;i++) X if(strcmp(sysacc[i].sname,sysname) == 0) X sysacc[i].fail++; X } X else if(strcmp(cp,"LOCKED") == 0) { X for(i=0;i< MAXSYS;i++) X if(strcmp(sysacc[i].sname,sysname) == 0) X sysacc[i].lock++; X } X } X cp = getfield(3,line,' '); X if(strcmp(cp,"REQUESTED") == 0) { X for(i=0;i< MAXSYS;i++) X if(strcmp(sysacc[i].sname,sysname) == 0) X sysacc[i].usent++; X } X else if(strcmp(cp,"COPY") == 0) { X for(i=0;i< MAXSYS;i++) { X if(strcmp(sysacc[i].sname,sysname) == 0) X sysacc[i].ugot++; X } X } X else if(strcmp(cp,"OK") == 0) { X if(tindex(getfield(4,line,' '),"startup") != -1 ) { X for(i=0;i 0) { X printf("%10s%s\n", "", sysacc[i].sname); X hourtmp = sysacc[i].btsent / 60; /* gives interger min */ X second = sysacc[i].btsent - ( hourtmp * 60); /* seconds */ X hour = hourtmp / 60; /* gives integer hour */ X min = hourtmp - ( hour * 60); X printf("%15ssent %10ld bytes %5stime ", "", sysacc[i].bbsent,""); X printf("%02ld:%02ld:%02ld", hour, min, second); X if (sysacc[i].btsent != 0) X printf(" %3d bytes/sec", sysacc[i].bbsent / sysacc[i].btsent); X putchar('\n'); X printf("%15sreceived %10ld bytes %5stime ","",sysacc[i].brec,""); X hourtmp = sysacc[i].btrec / 60; /* gives interger min */ X second = sysacc[i].btrec - ( hourtmp * 60); /* seconds */ X hour = hourtmp / 60; /* gives integer hour */ X min = hourtmp - ( hour * 60); X printf("%02ld:%02ld:%02ld", hour, min, second); X if (sysacc[i].btrec != 0) X printf(" %3d bytes/sec", sysacc[i].brec / sysacc[i].btrec); X putchar('\n'); X printf("%15s# of files %10d sent %5s %5d received\n", X "",sysacc[i].usent, "",sysacc[i].ugot); X printf("%15s# of calls %10d suc %10d fail %10d lock\n", X "", sysacc[i].suc, sysacc[i].fail, sysacc[i].lock); X printf("%15sConversations OK %5d (startup) %5d (completed)\n", X "", sysacc[i].okstr, sysacc[i].okstop); X /* next do total */ X hour = sysacc[i].bbsent - sysacc[i].brec; X if(hour < 0) { /* means we rec more */ X hour *= -1; X printf("%15sreceived %ld bytes more than sent\n", X "", hour); X } X else if(hour > 0) /* means we sent more */ X printf("%15ssent %ld bytes more that received\n", X "", hour); X else X printf("%15ssent the same amount as received\n",""); X hourtmp = (sysacc[i].btrec + sysacc[i].btsent) / 60; X second = (sysacc[i].btrec + sysacc[i].btsent) X - ( hourtmp * 60); /* seconds */ X hour = hourtmp / 60; /* gives integer hour */ X min = hourtmp - ( hour * 60); X printf("%15stotal connect time %02ld:%02ld:%02ld\n", X "", hour, min, second); X } X } X printf("\n%5sBy user:\n", ""); X treeprint(usage); X printf("\n%5sBy commands:\n", ""); X trsort(); X tcallpr(cmd); X printf("\n%5sBy day:\n",""); X for(i = 1; i <= 12; i++) X for(j = 1; j <= 31; j++) { X if(dayacc[i][j].used) { X hourtmp = dayacc[i][j].trecv / 60; X second = dayacc[i][j].trecv - ( hourtmp * 60); X hour = hourtmp / 60; /* gives integer hour */ X min = hourtmp - ( hour * 60); X printf("%5s%2d/%02d ", "", i,j); X printf("received %8ld bytes in ", dayacc[i][j].recv); X printf("%02ld:%02ld:%02ld/sent %8ld bytes in ", X hour,min,second, dayacc[i][j].sent); X hourtmp = dayacc[i][j].tsent / 60; X second = dayacc[i][j].tsent - ( hourtmp * 60); X hour = hourtmp / 60; /* gives integer hour */ X min = hourtmp - ( hour * 60); X printf("%02ld:%02ld:%02ld\n", hour,min,second); X } X } X exit(0); X} X Xerror(s) Xchar *s; X{ X void perror(); X X perror(s); X exit(1); X} X Xtindex(s,t) Xchar s[], t[]; X{ X register int j,k,i; X X if (s == NULL || t == NULL) { X error("tindex: pointer is null"); X } X for(i=0;s[i] != '\0'; i++) { X for(j=i,k=0;t[k] != '\0' && s[j]== t[k]; j++, k++) X ; X if(t[k] == '\0') X return(i); X } X return(-1); X} Xchar *strsave(s) /* save string s somewhere */ Xchar *s; X{ X char *p; X char *strcpy(); X X if((p = malloc( (unsigned) (strlen(s)+1) )) == NULL) { X error("strsave: out of mem"); X } X return strcpy(p,s); X} Xstruct users *tree(p,w) Xstruct users *p; Xchar *w; X{ X if(p == NULL) { /* new word */ X p = (struct users *) malloc (sizeof(struct users)); X if (p == NULL) { X error("tree: out of memory"); X } X p->name = strsave(w); X p->bsent = byt; X p->utim = tim; X p->nsent = 1; X p->nuser = NULL; X } X else if(strcmp(w,p->name) == 0) { X p->bsent += byt; X p->utim += tim; X p->nsent++; X } X else { X p->nuser = tree(p->nuser,w); X } X return(p); X} Xstruct call *tcall(p,w) Xstruct call *p; Xchar *w; X{ X if(p == NULL) { /* new cmd */ X p = (struct call *) malloc (sizeof(struct call)); X if(p == NULL) X error("tcall out of Mem"); X p->ncall = NULL; X p->cname = strsave(w); X p->times = 1; X cmdcount++; X } X else if(strcmp(w,p->cname) == 0) { X p->times++; X } X else { X p->ncall = tcall(p->ncall,w); X } X return(p); X} Xtreeprint(p) Xstruct users *p; X{ X if(p != NULL) { X printf("%10s%10s ", "", p->name); X printf("sent %4ld files & %10ld bytes ", p->nsent, p->bsent); X hourtmp = p->utim /60; X second = p->utim - ( hourtmp * 60 ); X hour = hourtmp / 60; X min = hourtmp - (hour * 60); X printf("%02ld:%02ld:%02ld\n", hour,min,second); X treeprint(p->nuser); X } X} Xtcallpr(p) Xstruct call *p; X{ X if(p != NULL ) { X printf("%10d %s\n", p->times, p->cname); X tcallpr(p->ncall); X } X} Xtrsort() X{ X struct call *q; X struct call *p; X register int i, sw, n,m; X char *c; X char *d; X Xloop: X p = cmd; X sw = 0; X for(i=0;i< cmdcount-1; i++) { X q = p->ncall; X if(p->times < q->times) { /* switch */ X c = p->cname; X n = p->times; X d = q->cname; X m = q->times; X p->cname = d; X p->times = m; X q->cname = c; X q->times = n; X sw = 1; X } X p = p->ncall; X } X if(sw) X goto loop; X} X#define NULLP "" Xchar * Xgetfield(field,buffer,separator) Xchar separator; Xchar buffer[]; Xint field; X{ X register int i; X char *bp, *p, buff[512]; X int sht; X X sht = 0; X strcpy(buff,buffer); X p = &buff[0]; X i = 0; X if((*p == separator) && (field != 0)) { X field--; X sht = 1; X } X while( i != field) { X for(++p; *p != separator; p++) { X if (*p == '\0') { X return(NULLP); X } X } X i++; X } X if(sht) X field += 1; X if(field != 0) p++; X bp =p; X for (; *p != separator; p++) X if(*p == '\0') X return(bp); X *p = '\0'; X return(bp); X} X Xtellem() X{ X fprintf(stderr, "usage: %s [-l logfile] [-s syslog]\n", X Cmdname); X exit(1); X} !Funky!Stuff! echo 'x - Makefile' sed -e 's/^X//' > Makefile << '!Funky!Stuff!' XSHELL = /bin/sh XI = /usr/include XDEST = /usr/hippo/gam/bin X Xuucpanz: uucpanz.c uucpanz.h $I/stdio.h $I/ctype.h X $(CC) $(CFLAGS) -o uucpanz uucpanz.c X Xinstall: uucpanz X cp uucpanz $(DEST) X Xclean: Xclobber: clean X -rm -f uucpanz X !Funky!Stuff! exit