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