jv@mh.nl.UUCP (Johan Vromans) (11/14/87)
Some time ago, someone posted somewhere a shell script to generate UUCP reports from UUCP files. I don't know who, when and where, but I made the script running on our systems. The script took too long to complete, so I rewrote the script in C. This program has not been adapted to SVR3 (not having such a system). It is not perfect either. I added some code to generate weekly reports (using SYSLOG.WEEK). Take it for what it is worth -- it generates fine reports on our systems. Whoever wrote the shell script deserves the honour - I only converted it. Remarks and fixes are welcome. -- Real-Name: Johan Vromans | jv@mh.nl via European backbone Multihouse N.V., Gouda, The Netherlands | uucp: ..{uunet!}mcvax!mh.nl!jv "Its better to light a candle than to curse the darkness" ---------------- CUT HERE ---------------- /* uucpstat.c - to print the UUCP transaction statistics (aap 7/9/87) * for System V Release 2 or 3 formatted UUCP transaction files * Version 1.0 * * This program will process the uucp transactions for each node and report * total transaction statistics. Processing is performed on the file $UUCP_LOG * which defaults to: * /usr/spool/uucp/SYSLOG (Rlse 2) or /usr/spool/uucp/.Admin/xferstats (Rlse 3). * Processing defaults to statistics for the current day. Options allow * processing of all transactions found (usually the current week's * transactions are maintained) or a specific day's transactions. * Output is directed to standard output. * * INSTALLATION NOTES - * * uucp.stat is non-intrusive and should be installed with 755 permissions. * Set the variable: $RLSE_LVL to the System V major release level that * you are running prior to installation. * * syntax: uucp.stat [<option>] * * where <option> is one or more of the following: * * -a : process all transactions found * -u : do not display user statistics * -n : do not display node statistics * -t : do not display total statistics * mm/dd : process transactions for month/day. * (do not use leading zeroes) * -h : display syntax only * -w : use logfile.WEEK, implies -a * -v : display program parameters * * If no <option> is specified, process today's transactions only. */ #define PROG_VERSION "1.0" /* Program Version number */ #define RLSE_LVL 2 /* major system V release level */ #include <stdio.h> #define EOS '\0' #if RLSE_LVL == 2 char UUCP_log[] = "/usr/spool/uucp/SYSLOG\0\0\0\0\0\0\0"; #else char UUCP_log[] = "/usr/spool/uucp/.Admin/xferstats"; #endif int D_month; int D_day; int D_year; char local_node[20]; char cur_node[20]; char cur_login[32]; char *wrkname; int uulog; char *my_name; /* Print mode flags */ int PF_user = 1; int PF_node = 1; int PF_grand = 1; int PF_param = 0; int PF_weekly = 0; int f_date = 1; /* default is current day's */ int nrecs; int user_xact; long user_bytes; int user_time; int node_xact; long node_bytes; int node_time; int tot_xact; long tot_bytes; int tot_time; main (argc, argv) int argc; char *argv[]; { init (argc, argv); pre_process (); sort (); process (); return (0); } #include <sys/utsname.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> init (argc, argv) int argc; char *argv[]; { extern char *optarg; extern int optind; struct utsname u; struct stat st; long time(); int c; long now = time (&now); char *tempnam (); struct tm *lt; wrkname = tempnam (NULL, "UU"); my_name = argv[0]; uname (&u); strncpy (local_node, u.nodename, UTSLEN); local_node[UTSLEN] = '\0'; lt = localtime (&now); D_day = lt->tm_mday; D_month = lt->tm_mon + 1; D_year = lt->tm_year; while ((c = getopt (argc, argv, "aunthwv")) != EOF) { switch (c) { case '?': case 'h': fprintf (stderr, " syntax: %s [<option>]\n", my_name); fprintf (stderr, " where <option> is one or more of the following:\n"); fprintf (stderr, " -h : display syntax \n"); fprintf (stderr, " -a : process statistics for all days found \n"); fprintf (stderr, " -u : do not display user statistics\n"); fprintf (stderr, " -n : do not display node statistics\n"); fprintf (stderr, " -t : do not display total statistics\n"); fprintf (stderr, " -w : display weekly stats\n"); fprintf (stderr, " mo/day : process statistics for specific month/day\n"); fprintf (stderr, " -v : display program characteristics\n"); fprintf (stderr, " default is to process today's transactions only\n"); break; case 'u': PF_user = 0; break; case 'n': PF_node = 0; break; case 't': PF_grand = 0; break; case 'v': PF_param = 1; break; case 'a': f_date = 0; break; #if RLSE_LVL == 2 case 'w': PF_weekly = 1; f_date = 0; strcat (UUCP_log, ".WEEK"); break; #endif } } if (argc > optind) { c = atoi (argv[optind]); D_day = c % 100; D_month = c / 100; if (D_day == 0 || D_day > 31 || D_month == 0 || D_month > 12) { fprintf (stderr, "%s: invalid date spec: %s\n", my_name, argv[optind]); } else f_date = 1; } print_params (); if (((uulog = open (UUCP_log, 0)) < 0) || (fstat (uulog, &st) < 0) || (st.st_size == 0)) { fprintf (stderr, "File: %s unaccessible or empty\n", UUCP_log); exit (1); } } /* print routines */ /* Display Individual login User Stats */ printit (node, login, xact, bytes, time) char *node, *login; int xact, time; long bytes; { printf ("%-8s %-8s %6d %9ld %8d", node, login, xact, bytes, time); if (time != 0) printf ("%10d\n", bytes / time); else printf ("\n\n"); } user_stats () { if (PF_user) { printit (cur_node, cur_login, user_xact, user_bytes, user_time); } } /* Display cur_node Statistics */ node_stats () { if (PF_node) { printit (cur_node, "TOTAL:", node_xact, node_bytes, node_time); printf ("\n"); } } /* Display Grand Totals */ grand_totals () { if (PF_grand) { printf ("_________________________________________________________________\n\n"); printit (local_node, "", tot_xact, tot_bytes, tot_time); printf ("\n"); } } print_params () { if (PF_param) { printf ("[%s] Version: %s O/S Rlse Level: %d\n", my_name, PROG_VERSION, RLSE_LVL); printf ("[%s] Transaction File: %s\n", my_name, UUCP_log); printf ("[%s] Print Flags:%s%s%s\n\n\n", my_name, PF_user ? " User" : "", PF_node ? " Node" : "", PF_grand ? " Total" : ""); } } /* Print header */ print_header () { long time(); long now = time (&now); char *ctime (); char *cp = ctime (&now); static char *m_tab = "JanFebMarAprMayJunJulAugSepOctNovDec"; cp[24] = '\0'; if (PF_param) printf ("\n\n"); printf ("\tUUCP Network Transaction Statistics\n"); printf ("\tNode: %s %s\n", local_node, cp); if (f_date) printf ("\t(Transactions of: %.3s %d 19%d)\n\n", &m_tab[3*(D_month-1)], D_day, D_year); else printf ("\t(All Transactions)\n\n"); printf ("Node User Xact Bytes Time Rate (Bytes/Sec)\n"); printf ("_________________________________________________________________\n\n"); } /* phase 2 - pre-processing of UUCP_log file * by making one pass at the UUCP_log file and extracting just the * fields for cur_node & username, byte count and transaction time, * then sorting them by node and login, we can process the sub-totals * and totals synchronously and process more quickly then by mutiple passes. */ pre_process () { char buf [BUFSIZ]; char *cp; FILE *uu = fdopen (uulog, "r"); FILE *wrkfile = fopen (wrkname, "w"); int mtmp, dtmp; int etime; long bytes; if (PF_param) printf ("Selecting ...\n"); nrecs = 0; while ((cp = fgets (buf, BUFSIZ, uu)) != NULL) { while (*cp == ' ') cp++; if (*cp == '[') continue; if (sscanf (cp, "%[^!]!%s %*s (%d/%d%*s %*s %*s %*s %ld / %d", cur_node, cur_login, &mtmp, &dtmp, &bytes, &etime) != 6) { fprintf (stderr, "** fmt ** %s", buf); continue; } /* if a date option was specified then extract only the records */ /* for that date */ if (f_date) { if (mtmp != D_month || dtmp != D_day) continue; } #if RLSE_LVL == 3 # Rlse 3 xaction log file has time as fractional number #endif fprintf (wrkfile, "%s %s %ld %d\n", cur_node, cur_login, bytes, etime); nrecs++; } fclose (wrkfile); fclose (uu); } /* now sort the stream in order of node login bytes time */ sort () { char buf [BUFSIZ]; if (PF_param) printf ("Sorting %d records ...\n", nrecs); sprintf (buf, "sort -o %s %s", wrkname, wrkname); system (buf); } /* phase 3 - process each transaction record and calculate/display stats */ process () { FILE *wrkfile = fopen (wrkname, "r"); char buf [BUFSIZ]; char node [64]; char login [64]; long bytes; int etime; *node = *cur_node = EOS; *login = *cur_login = EOS; tot_xact = tot_bytes = tot_time = 0; user_xact = user_bytes = user_time = 0; node_xact = node_bytes = node_time = 0; print_header (); while (fgets (buf, BUFSIZ, wrkfile) != NULL) { sscanf (buf, "%s %s %ld %d", node, login, &bytes, &etime); if (!strcmp (node, cur_node) || *node == EOS) { /* first entry or same node as previous entry */ if (!strcmp (login, cur_login) || *login == EOS) { /* first entry or same cur_login as previous entry */ user_xact++; user_bytes += bytes; user_time += etime; } else { /* cur_login is different than previous login. */ /* print current user's summaries. */ if (*cur_login) user_stats (); /* init counters for new cur_login */ user_xact = 1; user_bytes = bytes; user_time = etime; strcpy (cur_login, login); } /* update node statistics */ node_xact++; node_bytes += bytes; node_time += etime; strcpy (cur_node, node); } else { /* node name is different than previous entry */ /* print previous user and cur_node totals */ if (*cur_node) { user_stats (); node_stats (); } /* init counters for new cur_node */ strcpy (cur_node, node); strcpy (cur_login, login); user_xact = 1; user_bytes = bytes; user_time = etime; node_xact = 1; node_bytes = bytes; node_time = etime; } /* update grand totals */ tot_xact++; tot_bytes += bytes; tot_time += etime; } if (*cur_node) { user_stats (); node_stats (); grand_totals (); } else printf ("No transactions found\n"); fclose (wrkfile); unlink (wrkname); }