Article 1340 of comp.infosystems.wais:
Xref: feenix.metronet.com comp.infosystems.gopher:7848 comp.infosystems.wais:1340 comp.infosystems.www:5541
Newsgroups: comp.infosystems.gopher,comp.infosystems.wais,comp.infosystems.www
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!uknet!pipex!howland.reston.ans.net!cs.utexas.edu!newsfeed.rice.edu!rice!riddle
From: [email protected] (Prentiss Riddle)
Subject: Re: Single program to summarize logs of several kinds of server?
Message-ID: <[email protected]>
Sender: [email protected] (News)
Organization: Ministry of Information, William's Marsh
References: <[email protected]>
Date: Thu, 6 Jan 1994 20:29:40 GMT
Lines: 930

A couple of hours ago I wrote:
> I could swear that I had seen and saved an announcement of a single log
> summary program which could handle gopher, ftp, WAIS and (I think) a
> couple of other flavors of log files.

Several people responded with clues, but Bob Bagwill
([email protected]) sent me a copy of the program.  It's called
"fwgstat 0.35" and the author is Jonathan Magid ([email protected]).
Since neither archie, veronica nor I can find it archived anywhere, I
am appending it below.  Let's hope the author puts it on boombox or
some other well-know site soon.

Thanks to everyone who responded.

-- Prentiss Riddle ("aprendiz de todo, maestro de nada") [email protected]
-- Systems Programmer, Office of Networking Services
-- Rice University, POB 1892, Houston, TX 77251 / Mudd 208 / 713-285-5327
-- Opinions expressed are not necessarily those of my employer.

-------------------------------------------------------------------------
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#       README
#       country-codes
#       fwgstat
#       mygetopts.pl
#
echo x - README
sed 's/^X//' >README << 'END-of-README'
XThis is fwgstat v 0.35.  It is heavily based on the much better
Xwritten xferstats, which is packaged with the Wuarchive FTP daemon.
X
XThis version is capable of parsing the usage files for most
Xof the public access protocols in use today: FTP, Gopher, WAIS, and the NCSA
Xand the Plexus implementations of HTTP, and writing a nice usage report.
X
XAs of this version, fwgstat can summarize the usage of any number of these
Xprotocols in a single report.
X
XTo install the program, edit the perl script to specify the locations
Xof the log files for each daemon and the location of the accompanying
Xcountry-codes file.  You must also add the library file 'mygetopts.pl' to
Xyour Perl library directory.
X
X
XThese are the options which fwgstat supports:
X
X       -f <filename>   Use <filename> for the log file
X       -r              include real users (for FTP)
X       -a              include anonymous users (for FTP)
X       -h              include report on hourly traffic
X       -d              include report on domain traffic
X       -t              report on total traffic by section
X       -D <domain>     report only on traffic from <domain>
X       -l <depth>      Depth of path detail for sections
X       -s <section>    Section to report on, For example: -s /pub will report
X                               only on paths under /pub
X                               (left in for backward compatibility)
X       -g <section>    Process a Gopher file, followed by an optional section
X       -w <section>    Process a WAIS file, followed by an optional section
X       -p <section>    Process a Plexus HTTPD file, followed by an optional
X                               section
X       -n <section>    Process a NCSA HTTPD file, followed by an optional
X                               section
X       -F <section>    Process a FTP file, followed by an optional section
X       -m              Process multiple file types into one report
X
X
XIf you have any suggestions, bug reports, fixes, or enhancements,
Xsend them to [email protected].
END-of-README
echo x - country-codes
sed 's/^X//' >country-codes << 'END-of-country-codes'
XAD   Andorra
XAE   United Arab Emirates
XAF   Afghanistan
XAG   Antigua and Barbuda
XAI   Anguilla
XAL   Albania
XAM   Armenia
XAN   Netherland Antilles
XAO   Angola
XAQ   Antarctica
XAR   Argentina
XAS   American Samoa
XAT   Austria
XAU   Australia
XAW   Aruba
XAZ   Azerbaidjan
XBA   Bosnia-Herzegovina
XBB   Barbados
XBD   Banglades
XBE   Belgium
XBF   Burkina Faso
XBG   Bulgaria
XBH   Bahrain
XBI   Burundi
XBJ   Benin
XBM   Bermuda
XBN   Brunei Darussalam
XBO   Bolivia
XBR   Brazil
XBS   Bahamas
XBT   Buthan
XBV   Bouvet Island
XBW   Botswana
XBY   Belarus
XBZ   Belize
XCA   Canada
XCC   Cocos (Keeling) Isl.
XCF   Central African Rep.
XCG   Congo
XCH   Switzerland
XCI   Ivory Coast
XCK   Cook Islands
XCL   Chile
XCM   Cameroon
XCN   China
XCO   Colombia
XCR   Costa Rica
XCS   Czechoslovakia
XCU   Cuba
XCV   Cape Verde
XCX   Christmas Island
XCY   Cyprus
XCZ   Czech Republic
XDE   Germany
XDJ   Djibouti
XDK   Denmark
XDM   Dominica
XDO   Dominican Republic
XDZ   Algeria
XEC   Ecuador
XEE   Estonia
XEG   Egypt
XEH   Western Sahara
XES   Spain
XET   Ethiopia
XFI   Finland
XFJ   Fiji
XFK   Falkland Isl.(Malvinas)
XFM   Micronesia
XFO   Faroe Islands
XFR   France
XFX   France (European Ter.)
XGA   Gabon
XGB   Great Britain (UK)
XGD   Grenada
XGE   Georgia
XGH   Ghana
XGI   Gibraltar
XGL   Greenland
XGP   Guadeloupe (Fr.)
XGQ   Equatorial Guinea
XGF   Guyana (Fr.)
XGM   Gambia
XGN   Guinea
XGR   Greece
XGT   Guatemala
XGU   Guam (US)
XGW   Guinea Bissau
XGY   Guyana
XHK   Hong Kong
XHM   Heard & McDonald Isl.
XHN   Honduras
XHR   Croatia
XHT   Haiti
XHU   Hungary
XID   Indonesia
XIE   Ireland
XIL   Israel
XIN   India
XIO   British Indian O. Terr.
XIQ   Iraq
XIR   Iran
XIS   Iceland
XIT   Italy
XJM   Jamaica
XJO   Jordan
XJP   Japan
XKE   Kenya
XKG   Kirgistan
XKH   Cambodia
XKI   Kiribati
XKM   Comoros
XKN   St.Kitts Nevis Anguilla
XKP   Korea (North)
XKR   Korea (South)
XKW   Kuwait
XKY   Cayman Islands
XKZ   Kazachstan
XLA   Laos
XLB   Lebanon
XLC   Saint Lucia
XLI   Liechtenstein
XLK   Sri Lanka
XLR   Liberia
XLS   Lesotho
XLT   Lithuania
XLU   Luxembourg
XLV   Latvia
XLY   Libya
XMA   Morocco
XMC   Monaco
XMD   Moldavia
XMG   Madagascar
XMH   Marshall Islands
XML   Mali
XMM   Myanmar
XMN   Mongolia
XMO   Macau
XMP   Northern Mariana Isl.
XMQ   Martinique (Fr.)
XMR   Mauritania
XMS   Montserrat
XMT   Malta
XMU   Mauritius
XMV   Maldives
XMW   Malawi
XMX   Mexico
XMY   Malaysia
XMZ   Mozambique
XNA   Namibia
XNC   New Caledonia (Fr.)
XNE   Niger
XNF   Norfolk Island
XNG   Nigeria
XNI   Nicaragua
XNL   Netherlands
XNO   Norway
XNP   Nepal
XNR   Nauru
XNT   Neutral Zone
XNU   Niue
XNZ   New Zealand
XOM   Oman
XPA   Panama
XPE   Peru
XPF   Polynesia (Fr.)
XPG   Papua New
XPH   Philippines
XPK   Pakistan
XPL   Poland
XPM   St. Pierre & Miquelon
XPN   Pitcairn
XPT   Portugal
XPR   Puerto Rico (US)
XPW   Palau
XPY   Paraguay
XQA   Qatar
XRE   Reunion (Fr.)
XRO   Romania
XRU   Russian Federation
XRW   Rwanda
XSA   Saudi Arabia
XSB   Solomon Islands
XSC   Seychelles
XSD   Sudan
XSE   Sweden
XSG   Singapore
XSH   St. Helena
XSI   Slovenia
XSJ   Svalbard & Jan Mayen Is
XSK   Slovak Republic
XSL   Sierra Leone
XSM   San Marino
XSN   Senegal
XSO   Somalia
XSR   Suriname
XST   St. Tome and Principe
XSU   Soviet Union
XSV   El Salvador
XSY   Syria
XSZ   Swaziland
XTC   Turks & Caicos Islands
XTD   Chad
XTF   French Southern Terr.
XTG   Togo
XTH   Thailand
XTJ   Tadjikistan
XTK   Tokelau
XTM   Turkmenistan
XTN   Tunisia
XTO   Tonga
XTP   East Timor
XTR   Turkey
XTT   Trinidad & Tobago
XTV   Tuvalu
XTW   Taiwan
XTZ   Tanzania
XUA   Ukraine
XUG   Uganda
XUK   United Kingdom
XUM   US Minor outlying Isl.
XUS   United States
XUY   Uruguay
XUZ   Uzbekistan
XVA   Vatican City State
XVC   St.Vincent & Grenadines
XVE   Venezuela
XVG   Virgin Islands (British)
XVI   Virgin Islands (US)
XVN   Vietnam
XVU   Vanuatu
XWF   Wallis & Futuna Islands
XWS   Samoa
XYE   Yemen
XYU   Yugoslavia
XZA   South Africa
XZM   Zambia
XZR   Zaire
XZW   Zimbabwe
XARPA   Old style Arpanet
XCOM   US Commercial
XEDU   US Educational
XGOV   US Government
XINT   International
XMIL   US Military
XNATO   Nato field
XNET   Network
XORG   Non-Profit
X
X
END-of-country-codes
echo x - fwgstat
sed 's/^X//' >fwgstat << 'END-of-fwgstat'
X#!/usr/local/bin/perl
X# ---------------------------------------------------------------------------
X#
X# USAGE: fwgstat <options>
X#
X# OPTIONS:
X#       -f <filename>   Use <filename> for the log file
X#       -r              include real users
X#       -a              include anonymous users
X#       -h             include report on hourly traffic
X#       -d             include report on domain traffic
X#       -t             report on total traffic by section
X#       -D <domain>     report only on traffic from <domain>
X#       -l <depth>      Depth of path detail for sections
X#       -s <section>    Section to report on, For example: -s /pub will report
X#                              only on paths under /pub
X#                              (left in for backward compatibility)
X#       -g <section>    Process a Gopher file, followed by an optional section
X#       -w <section>    Process a WAIS file, followed by an optional section
X#      -p <section>    Process an Plexus HTTPD file, followed by an optional
X#                              section
X#      -n <section>    Process an NCSA HTTPD file, followed by an optional
X#                              section
X#      -F <section>    Process a FTP file, followed by an optional section
X#                              (the default)
X#      -m              Process multiple file types
X#
X# ---------------------------------------------------------------------------
X
X
X# added support for the Plexus HTTPD. (which is now the -p switch). changed
X# switch for NCSA httpd to -n.  04-Oct-1993 [email protected] v.035
X#
X# changed format for government data report including support for summarizing
X# multiple protocol logs into one report and added optional arguements to
X# getopts 30-Sep-1993 [email protected]. v.03
X#
X# added WWW (NCSA httpd) logging  9-Sep-1993 [email protected]
X#
X# added file-size, proper DocID request, and host counting for WAIS
X# [email protected]  24-Aug-1993 v.02 (first public release)
X#
X# initial take at WAIS logfile parsing- [email protected] 18-Aug-1993
X#
X# bug fixes in gopher routines, added full country names- by Jonathan Magid
X# [email protected] 18-Aug-1993
X#
X# changes by David Datta ([email protected]) to write stats for gopher logfiles
X# 14-Aug-1993 v.01
X#
X# original version- from the Wuarchive enhanced FTPD distribution
X
X# edit the next two lines to customize for your domain.
X# This will allow your domain to be seperated in the domain listing.
X
X$mydom1 = "unc";
X$mydom2 = "edu";
X
X# edit the next line to identify the top of your Gopher data tree
X$gopherroot= "/etc/gopher-data";
X
X# edit the next line to identify the top of your HTTPD (WWW) data tree
X$httpdroot = "/usr/local/etc/http/data";
X
X# edit the next line to locate the country-codes file. This is a file
X# of the format:
X# domain text
X# which will allow expansion from domain to country name.
X$countrycodefile="/usr/local/etc/country-codes";
X
X# edit the next line to customize for your default log file
X%usagefiles = (
X       'opt_F',        '/usr/adm/xferlog',     #for FTP
X       'opt_g',        '/usr/adm/gopher.log',  #for gopher
X       'opt_w',        '/usr/adm/server.log',  #for wais
X       'opt_p',        'plexus_log',   #for plexus httpd
X       'opt_n',        '/usr/adm/access_log'   #for NCSA httpd
X);
X
X#options for all the types of files which we can parse
X%filetypes=(
X       'opt_F',        'FTP',
X       'opt_g',        'GOPHER',
X       'opt_p',        'WWW',
X       'opt_n',        'WWW',
X       'opt_w',        'WAIS',
X);
X
X# Edit the following lines for default report settings.
X# Entries defined here will be over-ridden by the command line.
X
X$opt_h = 1;
X$opt_d = 1;
X$opt_t = 1;
X$opt_l = 2;
X
Xrequire 'mygetopts.pl';
X&MyGetopts('f:ramhdp?F?D:l:s:g?w?n?');
X
Xif ($opt_r) { $real = 1;}
Xif ($opt_a) { $anon = 1;}
Xif ($real == 0 && $anon == 0) { $anon = 1; }
Xif ($opt_f) {$usage_file = $opt_f;}
Xif (!($opt_g  || $opt_w || $opt_p || $opt_n)) {$opt_F = 1;}
X
X
X
Xtype:
Xforeach $_ (keys %filetypes) {
X       if (eval "defined(\$$_);") {
X               if ($foundone) {
X                       print STDERR "More than one report type specified\n";
X                       print STDERR "You must use the -m switch to summarize multiple types\n";
X                       exit;
X               }
X               $filestogrind{$_}=$usagefiles{$_};
X               $foundone=1 unless $opt_m;
X               next type;
X       }
X}
X
Xgrep ($reporttype="$filetypes{$_} $reporttype",keys(%filestogrind));
Xprint "This report is for $reporttype transfers.\n\n";
X
Xforeach $filetype (keys(%filestogrind)) {
X
X       $usage_file = $filestogrind{$filetype} unless $opt_f;
X       $optarg = eval "\$$filetype";
X       $opt_s = $optarg unless $optarg==1;
X
X
X       if ($opt_D) {
X               print "$filetypes{$filetype} Transfer Totals include the '$opt_D' domain only.\n";
X               print "All other domains are filtered out for this report.\n\n";
X       }
X
X       if ($opt_s) {
X               print "$filetypes{$filetype} Transfer Totals include the '$opt_s' section only.\n";
X               print "All other sections are filtered out for this report.\n\n";
X       }
X
X       open (LOG,$usage_file) || die "Error opening usage log file: $usage_file\n";
X
X
X
X       line: while (<LOG>) {
X
X               @line = split;
X               $finished=0;
X               if ($filetype eq 'opt_F') {
X                       next line if ($#line != 16);
X                       next line if (!$anon && $line[12] eq "a");
X                       next line if (!$real && $line[12] eq "r");
X               }
X               if ($filetype eq 'opt_p') {
X                       next line if /^----/; #informational message
X                       next line if $line[7] ne 'GET'; #does this happen?
X               }
X               if ($filetype eq 'opt_w') {
X                       if ($line[7] eq "Accepted") {
X                               $hostpid{$line[0]}=$line[10];
X                               next line;
X                       }
X                       if ($line[7] eq "Done") {
X                               $afield=$hostpid{$line[0]};
X                               $hostpid{$line[0]} =~ /^\[(\d+\.\d+\.\d+\.\d+)\],$/;
X                               $afield = $1 if $1;
X                               $fsize=$sizepid{$line[0]};
X                               $numfiles=$numpid{$line[0]};
X                               ($daytime,$time,$fname)=split('/',$infopid{$line[0]});
X                               delete $hostpid{$line[0]};
X                               delete $numpid{$line[0]};
X                               delete $docidpid{$line[0]};
X                               delete $sizepid{$line[0]};
X                               delete $infopid{$line[0]};
X                               if ($daytime eq '' || $afield eq '' || $fsize == 0) {
X                                       #no retrievals for this search
X                                       next line;
X                               }
X                               $finished=1;
X                       }
X                       next line if ($line[8] ne "DocID:");
X               }
X
X               if (!$finished) {
X
X                  #fill in these fields for each logtype (daytime,time,fsize,fname)
X                       LOGTYPE: {
X                               if ($filetype eq 'opt_F' || $filetype eq 'opt_g') {
X                                       $afield=$line[6];
X                                       $daytime = substr($_, 4, 6) . substr($_, 19, 5);
X                                       $time = substr($_,11,2);
X                               }
X                               if ($filetype eq 'opt_F') {
X                                       $fname=$line[8];
X                                       $fsize = $line[7];
X                                       $xfsecs = $line[5];
X                                       if ($fname eq "\.") { $fname = "/unreadable/filename";}
X                                       $numfiles=1;
X                                       last LOGTYPE;
X                               }
X                               if ($filetype eq 'opt_n') {
X                                       $fname=$line[7];
X                                       $fsize=(-s "$httpdroot/$fname");
X                                       /\[(.*)\]/;
X                                       $daytime = substr($1, 4, 6) . substr($1, 19, 5);
X                                       $time = substr($1,11,2);
X                                       $numfiles=1;
X                                       $afield=$line[0];
X                                       last LOGTYPE;
X                               }
X                               if ($filetype eq 'opt_p') {
X                                       $fname=$line[8];
X                                       $fsize=(-s "$httpdroot/$fname");
X                                       /^\S+\s+(.*)/;
X                                       $daytime = substr($1, 4, 6) . substr($1, 23, 5);
X                                       $time = substr($1,11,2);
X                                       $numfiles=1;
X                                       $afield=$line[0];
X                                       last LOGTYPE;
X                               }
X                               if ($filetype eq 'opt_w') {
X                                       /^\d+: \d+: (.*)/; #get rid of stupid variable length stuff
X                                       $daytime = substr($1, 0, 7) . substr($1, 16, 4);
X                                       $time = substr($line[4],0,2);
X                                       @path=split('/',$line[17]);
X                                       $infopid{$line[0]} = "$daytime/$time/$path[$#path]";
X                                       $line[13] =~ s/,$//;
X                                       $sizepid{$line[0]} += ($line[14]-$line[13]);
X                                       $numpid{$line[0]}++ if $docidpid{$line[0]} != "$line[10] $line[11]";
X                                       $docidpid{$line[0]} =  "$line[10] $line[11]";
X                                       $xfsecs = 0;
X                                       $avgrate = '0.0 KB/s';
X                                       last LOGTYPE;
X                                       next line;
X                               }
X                               if ($filetype eq 'opt_g') {
X                                       if ( $line[9] eq "range") {
X                                               $fsize=$line[12]-$line[10];
X                                               $fname=$line[15];
X                                               $fname=~s:^(/../)+:/:;
X                                       }
X                                       else {
X                                           next line if ( $line[9] ne "file");
X                                           $fname=$line[10];
X                                           $fname=~s:^(/../)+:/:;
X                                           $fname=~s://:/:;
X                                           $fsize = (-s "$gopherroot/$fname");
X                                       }
X                                       $numfiles=1;
X                                       last LOGTYPE;
X                               }
X                       }
X                       next if (substr($fname,0,length("$opt_s")) ne "$opt_s");
X                       $fname = substr($fname,length("$opt_s"));
X                       @path = split(/\//, $fname);
X               }
X
X               # Uncomment this line to show records being processed.
X               # print $daytime," ",$time," ",$fsize," ",$fname,"\n";
X
X               # Things in the top-level directory are assumed to be informational files
X
X               LOGTYPE: {
X                       if ($filetype eq 'opt_F' || $filetype eq 'opt_g' || $filetype eq 'opt_p') {
X                               if ($#path == 1) {  $pathkey = "Index/Informational Files"; }
X                               else {
X                                       $pathkey = "";
X                                       for ($i=1; $i <= $#path-1 && $i <= $opt_l;$i++) {
X                                               $pathkey = "$pathkey/$path[$i]";
X                                       }
X                               }
X                               last LOGTYPE;
X                       }
X                       if ($filetype eq 'opt_w') {
X                               $pathkey=$fname;
X                               last LOGTYPE;
X                       }
X
X               }
X
X               next line if $pathkey eq '';
X
X               $afield =~ tr/A-Z/a-z/;
X
X               @address = split(/\./, $afield);
X
X               $domain = $address[$#address];
X               if ($domain eq "$mydom2" && $address[$#address-1] eq "$mydom1")
X                       { $domain = "$mydom1.$mydom2"; }
X               if ( $address[0] =~ /^[0-9]+$/ ) { $domain = "unresolved"; }
X               if ( $#address < 2 ) { $domain = "localhost"; }
X
X               $count = 1;
X               if ($opt_D) {
X                       if (substr($domain,0,length("$opt_D")) eq "$opt_D" ) { $count = 1;}
X                       else {$count = 0;}
X               }
X
X               if ($count) {
X
X                       $xferfiles             +=$numfiles;          # total files sent
X                       $xferfiles{$daytime}   +=$numfiles;          # files per day
X                       $groupfiles{$pathkey}++;                     # per-group accesses
X                       $domainfiles{$domain}++;
X
X                       $xfersecs{$daytime}    += $xfsecs;          # xmit seconds per day
X                       $domainsecs{$domain}   += $xfsecs;              # xmit seconds for domain
X                       $xferbytes{$daytime}   += $fsize;               # bytes per day
X                       $domainbytes{$domain}  += $fsize;               # xmit bytes to domain
X                       $xferbytes             += $fsize;               # total bytes sent
X                       $groupbytes{$pathkey}  += $fsize;               # per-group bytes sent
X
X                       $xfertfiles{$time}++;                        # files per hour
X                       $xfertsecs{$time}      += $xfsecs;          # xmit seconds per hour
X                       $xfertbytes{$time}     += $fsize;               # bytes per hour
X                       $xfertbytes            += $fsize;               # total bytes sent
X               }
X       }
X       close LOG;
X}
X
X
X@dates = sort datecompare keys(xferbytes);
X
Xif ($xferfiles == 0) {die "There was no data to process.\n";}
X
X
Xprint "TOTALS FOR SUMMARY PERIOD ", $dates[0], " TO ", $dates[$#dates], "\n\n";
Xprintf ("Files Transmitted During Summary Period  %12.0f\n", $xferfiles);
Xprintf ("Bytes Transmitted During Summary Period  %12.0f\n", $xferbytes);
X
Xprintf ("Average Files Transmitted Daily          %12.0f\n",
X   $xferfiles / ($#dates + 1));
Xprintf ("Average Bytes Transmitted Daily          %12.0f\n",
X   $xferbytes / ($#dates + 1));
X
Xformat top1 =
X
XDaily Transmission Statistics
X
X                 Number Of    Number of    Average    Percent Of  Percent Of
X     Date        Files Sent  Bytes  Sent  Xmit  Rate  Files Sent  Bytes Sent
X---------------  ----------  -----------  ----------  ----------  ----------
X.
X
Xformat line1 =
X@<<<<<<<<<<<<<<  @>>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>  @>>>>>>>    @>>>>>>>
X$date,           $nfiles,    $nbytes,     $avgrate,   $pctfiles,  $pctbytes
X.
X
X$^ = top1;
X$~ = line1;
X
Xforeach $date ( sort datecompare keys(xferbytes) ) {
X
X       $nfiles   = $xferfiles{$date};
X       $nbytes   = $xferbytes{$date};
X       $avgrate  = sprintf("%5.1f KB/s", $xferbytes{$date}/$xfersecs{$date}/1000) if$xfersecs{$date};
X       $pctfiles = sprintf("%8.2f", 100*$xferfiles{$date} / $xferfiles);
X       $pctbytes = sprintf("%8.2f", 100*$xferbytes{$date} / $xferbytes);
X       write;
X}
X
Xif ($opt_t) {
X       format top2 =
X
XTotal Transfers from each Archive Section (By bytes)
X
X                                                 ---- Percent  Of ----
X     Archive Section      Files Sent Bytes Sent  Files Sent Bytes Sent
X------------------------- ---------- ----------- ---------- ----------
X.
X
X       format line2 =
X@<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>>   @>>>>>>>
X$section,                 $files,    $bytes,     $pctfiles, $pctbytes
X.
X
X       $| = 1;
X       $- = 0;
X       $^ = top2;
X       $~ = line2;
X
X       foreach $section ( sort bytecompare keys(groupfiles) ) {
X
X               $files = $groupfiles{$section};
X               $bytes = $groupbytes{$section};
X               $pctbytes = sprintf("%8.2f", 100 * $groupbytes{$section} / $xferbytes);
X               $pctfiles = sprintf("%8.2f", 100 * $groupfiles{$section} / $xferfiles);
X               write;
X
X       }
X
X       if ( $xferfiles < 1 ) { $xferfiles = 1; }
X       if ( $xferbytes < 1 ) { $xferbytes = 1; }
X}
X
Xif ($opt_d) {
X       format top3 =
X
XTotal Transfer Amount By Domain
X#changes listing by domain to listing by country
X
X             Number Of    Number of     Average    Percent Of  Percent Of
XDomain Name  Files Sent   Bytes Sent   Xmit  Rate  Files Sent  Bytes Sent
X-----------  ----------  ------------  ----------  ----------  ----------
X.
X
X       format line3 =
X@<<<<<<<<<<<<<<< @>>>>>  @>>>>>>>>>>>  @>>>>>>>>>  @>>>>>>>    @>>>>>>>
X$country,     $files,     $bytes,       $avgrate,   $pctfiles,  $pctbytes
X.
X
X       $- = 0;
X       $^ = top3;
X       $~ = line3;
X
X       %codetable=&initcountryname();
X       foreach $domain ( sort domnamcompare keys(domainfiles) ) {
X
X               if ( $domainsecs{$domain} < 1 ) { $domainsecs{$domain} = 1; }
X
X               $country = $domain; #added by jem
X               $country = &countryname($domain,%codetable);
X               $country = $domain if $country eq '';
X               $files = $domainfiles{$domain};
X               $bytes = $domainbytes{$domain};
X               if ($domainsec{$domain}) {
X                       $avgrate  = sprintf("%5.1f KB/s",
X                       $domainbytes{$domain}/$domainsecs{$domain}/1000);
X               }
X               $pctfiles = sprintf("%8.2f", 100 * $domainfiles{$domain} / $xferfiles);
X               $pctbytes = sprintf("%8.2f", 100 * $domainbytes{$domain} / $xferbytes);
X               write;
X
X       }
X
X
X}
X
Xif ($opt_h) {
X
X       format top8 =
X
XHourly Transmission Statistics
X
X                 Number Of    Number of    Average    Percent Of  Percent Of
X     Time        Files Sent  Bytes  Sent  Xmit  Rate  Files Sent  Bytes Sent
X---------------  ----------  -----------  ----------  ----------  ----------
X.
X
X       format line8 =
X@<<<<<<<<<<<<<<  @>>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>  @>>>>>>>    @>>>>>>>
X$time,           $nfiles,    $nbytes,     $avgrate,   $pctfiles,  $pctbytes
X.
X
X
X       $| = 1;
X       $- = 0;
X       $^ = top8;
X       $~ = line8;
X
X       foreach $time ( sort keys(xfertbytes) ) {
X
X               $nfiles   = $xfertfiles{$time};
X               $nbytes   = $xfertbytes{$time};
X               $avgrate  = sprintf("%5.1f KB/s", $xfertbytes{$time}/$xfertsecs{$time}/1000) if $xfertsecs{$time};
X               $pctfiles = sprintf("%8.2f", 100*$xfertfiles{$time} / $xferfiles);
X               $pctbytes = sprintf("%8.2f", 100*$xfertbytes{$time} / $xferbytes);
X               write;
X       }
X}
Xexit(0);
X
Xsub initcountryname {
X       #read in table of ISO codes and country names -added by jem
X       open (blah, "<$countrycodefile") || die "Can't open $countrycodefile";
X       while (<blah>) {
X               chop;
X               local($iso,$name)=split('   ');
X               $iso =~ y/A-Z/a-z/;
X               $code{$iso}=$name;
X       }
X       close blah;
X       return %code;
X}
X
Xsub countryname {
X       #returns country name for an iso code
X       local($iso, %codetable) = @_;
X       return $codetable{$iso};
X}
X
Xsub datecompare {
X
X       $date1  = substr($a, 7, 4) * 4800;
X       $date2  = substr($b, 7, 4) * 4800;
X       $date1 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($a, 0, 3))*400;
X       $date2 += index("JanFebMarAprMayJunJulAugSepOctNovDec",substr($b, 0, 3))*400;
X       $date1 += substr($a, 4, 2);
X       $date2 += substr($b, 4, 2);
X       $date1 - $date2;
X
X}
X
Xsub domnamcompare {
X
X       $sdiff = length($a) - length($b);
X       ($sdiff < 0) ? -1 : ($sdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
X
X}
X
Xsub bytecompare {
X
X       $bdiff = $groupbytes{$b} - $groupbytes{$a};
X       ($bdiff < 0) ? -1 : ($bdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
X
X}
X
Xsub faccompare {
X
X       $fdiff = $fac{$b} - $fac{$a};
X       ($fdiff < 0) ? -1 : ($fdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
X
X}
X
END-of-fwgstat
echo x - mygetopts.pl
sed 's/^X//' >mygetopts.pl << 'END-of-mygetopts.pl'
X;# mygetopts.pl - getopts.pl with optional args added (a kludge)
X
X;# Usage:
X;#      do MyGetopts('a:b?c');  # -a takes arg. -b takes optional arg.
X;#     & -c takes no arg. Sets opt_* as a side effect.
X
Xsub MyGetopts {
X    local($argumentative) = @_;
X    local(@args,$_,$first,$rest);
X    local($errs) = 0;
X    local($[) = 0;
X
X    @args = split( / */, $argumentative );
X    while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
X       ($first,$rest) = ($1,$2);
X       $pos = index($argumentative,$first);
X       if($pos >= $[) {
X           if($args[$pos+1] eq ':' || $args[$pos+1] eq '?') {
X               shift(@ARGV);
X               if($rest eq '') {
X                   ++$errs unless @ARGV ||  $args[$pos+1] eq '?';
X                   $rest = shift(@ARGV);
X               }
X               if ($args[$pos+1] eq ':') {
X                       eval "\$opt_$first = \$rest;" ;
X               }
X               else {
X                       if ($rest ne '') {
X                               if ($rest !~ /^-/) {
X                                       eval "\$opt_$first = \$rest;"
X                               }
X                               else {
X                                       unshift(@ARGV,$rest);
X                                       eval "\$opt_$first = 1";
X                               }
X                       }
X                       else {
X                               eval "\$opt_$first = 1";
X                       }
X
X               }
X           }
X           else {
X               eval "\$opt_$first = 1";
X               if($rest eq '') {
X                   shift(@ARGV);
X               }
X               else {
X                   $ARGV[0] = "-$rest";
X               }
X           }
X       }
X       else {
X           print STDERR "Unknown option: $first\n";
X           ++$errs;
X           if($rest ne '') {
X               $ARGV[0] = "-$rest";
X           }
X           else {
X               shift(@ARGV);
X           }
X       }
X    }
X    $errs == 0;
X}
X
X1;
END-of-mygetopts.pl
exit