sub MainProg {
	print "Log analysis for $SystemName\n";
	if ($LogFile =~ /\*/) {
		if ($LogFile =~ /(.*)\/([^\/]+)/) {
			$dir = $1;
			$LogFile = $2;
		}
		else {
			$dir = "";
		}
		$LogFile =~ s/(\W)/\\$1/g;
		$LogFile =~ s/\\\*/\.\*/g;
		opendir (DIR,$dir) || die "  Error: Unable to read log files directory\n";
		@files = readdir (DIR);
		closedir (DIR);
		foreach $file (@files) {
			if ($file =~ $LogFile) {
				if ($dir) { $fullfile = $dir."/".$file; }
				else { $fullfile = $file; }
				push (@LogFiles,$fullfile);
			}
		}
	}
	else {
		push (@LogFiles,$LogFile);
	}
	foreach $LogFile (sort @LogFiles) {
		&Initialize;
		&ReadOldFile;
		&ReadLog;
		if ($LogLineCount || ($EndDate gt $InitialEndDate)) {
			unless ($NoSessions) { &GetSessions; }
			&PrintReport;
			if ($DetailsFile) { &PrintHostDetailsReport; }
			if ($RefsFile) { &PrintRefsReport; }
			if ($KeywordsFile) { &PrintKeywordsReport; }
			if ($AgentsFile) { &PrintAgentsReport; }
		}
	}
	print "Report complete\n";
}

sub Initialize {
	$version = "2.01";
	%MonthToNumber=
	  ('Jan','01','Feb','02','Mar','03',
	  'Apr','04','May','05','Jun','06',
	  'Jul','07','Aug','08','Sep','09',
	  'Oct','10','Nov','11','Dec','12');
	%NumberToMonth=
	  ('01','Jan','02','Feb','03','Mar',
	  '04','Apr','05','May','06','Jun',
	  '07','Jul','08','Aug','09','Sep',
	  '10','Oct','11','Nov','12','Dec');
	%RespCodes=
	  ('100','Code 100 Continue',
	  '101','Code 101 Switching Protocols',
	  '200','Code 200 OK',
	  '201','Code 201 Created',
	  '202','Code 202 Accepted',
	  '203','Code 203 Non-Authoritative Information',
	  '204','Code 204 No Content',
	  '205','Code 205 Reset Content',
	  '206','Code 206 Partial Content',
	  '300','Code 300 Multiple Choices',
	  '301','Code 301 Moved Permanently',
	  '302','Code 302 Moved Temporarily',
	  '303','Code 303 See Other',
	  '304','Code 304 Not Modified',
	  '305','Code 305 Use Proxy',
	  '400','Code 400 Bad Request',
	  '401','Code 401 Unauthorized',
	  '402','Code 402 Payment Required',
	  '403','Code 403 Forbidden',
	  '404','Code 404 Not Found',
	  '405','Code 405 Method Not Allowed',
	  '406','Code 406 Not Acceptable',
	  '407','Code 407 Proxy Authentication Required',
	  '408','Code 408 Request Time-Out',
	  '409','Code 409 Conflict',
	  '410','Code 410 Gone',
	  '411','Code 411 Length Required',
	  '412','Code 412 Precondition Failed',
	  '413','Code 413 Request Entity Too Large',
	  '414','Code 414 Request-URI Too Large',
	  '415','Code 415 Unsupported Media Type',
	  '500','Code 500 Internal Server Error',
	  '501','Code 501 Not Implemented',
	  '502','Code 502 Bad Gateway',
	  '503','Code 503 Service Unavailable',
	  '504','Code 504 Gateway Time-Out',
	  '505','Code 505 HTTP Version Not Supported');
	%DoWCounter=
	  (1,'Sun',2,'Mon',3,'Tue',4,'Wed',5,'Thu',6,'Fri',7,'Sat');
	$InitialEndDate="0000 00 00 00 00 00";
	$EndDate="0000 00 00 00 00 00";
	$FileEndDate="0000 00 00 00 00 00";
	$FileStartDate="9999 99 99 99 99 99";
	$time=time;
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
	  localtime($time);
	&date_to_count(($mon+1),$mday,$year);
	$DayBreak = $perp_days;
	@months=(Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
	$year = 1900+$year;
	$CurrDate="$mday $months[$mon] $year";
	$CurrMonth="$months[$mon]";
	$CurrYear="$year";
	&SetupCountryCodes;
	$DefaultPageName = "(index\.[^.]*|welcome\.[^.]*)";
	if ($NoSessions) {
		$DetailsFile = "";
		if ($GraphBase eq "visits") {
			$GraphBase = "";
		}
	}
	$AveragePages = 0;
	$DailyTotalBytesCounter = 0;
	$DailyTotalHitsCounter = 0;
	$DailyTotalPViewsCounter = 0;
	$DailyTotalVisitsCounter = 0;
	$DoWTotalBytesCounter = 0;
	$DoWTotalHitsCounter = 0;
	$DoWTotalPViewsCounter = 0;
	$DoWTotalVisitsCounter = 0;
	$endhour = 0;
	$GoDaily = 0;
	$GoMonthly = 0;
	$HourlyTotalBytesCounter = 0;
	$HourlyTotalHitsCounter = 0;
	$HourlyTotalPViewsCounter = 0;
	$HourlyTotalVisitsCounter = 0;
	$LocalPercent = 0;
	$MonthlyTotalBytesCounter = 0;
	$MonthlyTotalHitsCounter = 0;
	$MonthlyTotalPViewsCounter = 0;
	$MonthlyTotalVisitsCounter = 0;
	$OutsidePercent = 0;
	$refscounter = 0;
	$sessionstime = 0;
	$TodayBytes = 0;
	$TodayErrors = 0;
	$TodayHits = 0;
	$TodayHosts = 0;
	$TodayKB = 0;
	$TodayLocal = 0;
	$TodayOutside = 0;
	$TodayPages = 0;
	$TotalBytesCounter = 0;
	$TotalFilesCounter = 0;
	$usersessions = 0;
	$usersessions = 0;
	$ZipLock = 0;
	$TopDomain = "";
	$logsegment = "";
	%agentcounter = ();
	%agentreport = ();
	%altavista = ();
	%BytesDay = ();
	%BytesFileCounter = ();
	%BytesHour = ();
	%BytesUserIDCounter = ();
	%combinedreport = ();
	%dates = ();
	%DayFilesCounter = ();
	%dayusersessions = ();
	%day_counts = ();
	%DomainsBytesCounter = ();
	%DomainsDay = ();
	%DomainsFilesCounter = ();
	%DoWBytesCounter = ();
	%DoWFilesCounter = ();
	%DoWPViewsCounter = ();
	%DoWSessionsCounter = ();
	%dowusersessions = ();
	%excite = ();
	%fnfBytesFileCounter = ();
	%fnfHitsFileCounter = ();
	%fnfLastAccessFile = ();
	%HitsFileCounter = ();
	%HitsUserIDCounter = ();
	%hostlist = ();
	%hotbot = ();
	%HourFilesCounter = ();
	%hourusersessions = ();
	%infoseek = ();
	%LastAccessDomain = ();
	%LastAccessFile = ();
	%LastAccessUserID = ();
	%lycos = ();
	%MonthlyBytesCounter = ();
	%MonthlyCounter = ();
	%MonthlyFilesCounter = ();
	%MonthlyPViewsCounter = ();
	%MonthlySessionsCounter = ();
	%monthusersessions = ();
	%netfind = ();
	%othersearch = ();
	%platformreport = ();
	%prevday = ();
	%prevvisit = ();
	%PViewsDay = ();
	%PViewsHour = ();
	%Resolved = ();
	%snap = ();
	%TargetCounter = ();
	%TodayDomains = ();
	%TodayHosts = ();
	%TodayPages = ();
	%TopDomainAccess = ();
	%TopDomainBytesCounter = ();
	%TopDomainFilesCounter = ();
	%VisitsHour = ();
	%webcrawler = ();
	%yahoo = ();
	@Accesses = ();
	@RevAccesses = ();
	@files = ();
	@hosts = ();
	@lines = ();
}

sub ReadOldFile {
	$endTag="</PRE>";
	$InSegment = 0;
	return unless (-e "$FileDir/$ReportFile");
	open (OLD,"$FileDir/$ReportFile") || die "  Error opening file: $ReportFile\n";
	while (<OLD>) {
		chop;
		last if (m#</HTML>#oi);
		$NewFormat = 1 if (m#<!--WebLog 1.20 Format-->#oi);
		unless ($endhour || $logsegment) {
			($endhour,$endminute,$endsec,
			  $endday,$endmonth,$endyear) =
			  m#^.*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d)#o;
			if ($endhour) {
				$EndDate=
				  "$endyear $MonthToNumber{$endmonth} $endday $endhour $endminute $endsec";
				$InitialEndDate = $EndDate;
			}
		}
		if (/<A NAME="(monthly|daily|dayofweek|hourly|records|files|404|userids|topleveldomain|domains)">/oi) {
			$logsegment=$1;
			$InSegment=1;
			if ($logsegment ne 'records') {
				<OLD>;
				<OLD>;
				<OLD>;
			}
			next;
		}
		$InSegment = 0 if ($_ eq $endTag);
		next if (!$InSegment);
		if ($logsegment eq "monthly") {
			if ($NewFormat) {
				($Accesses,$Bytes,$Domains,$PViews,$Month) = 
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+([\d,]+)\s+(\w.{7})#o;
			} else {
				($Accesses,$Bytes,$Domains,$Month) = 
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+(\w.{7})#o;
				$PViews = 0;
			}
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$Domains =~ s/,//g;
			$PViews =~ s/,//g;
			$MonthlyFilesCounter{$Month}=$Accesses;
			$MonthlyBytesCounter{$Month}=$Bytes;
			$MonthlySessionsCounter{$Month}=$Domains;
			$MonthlyPViewsCounter{$Month}=$PViews;
			$MonthlyTotalBytesCounter+=$Bytes;
			$MonthlyTotalHitsCounter+=$Accesses;
			$MonthlyTotalVisitsCounter+=$Domains;
			$MonthlyTotalPViewsCounter+=$PViews;
			next;
		} elsif ($logsegment eq "daily") {
			if ($NewFormat) {
				($Accesses,$Bytes,$Domains,$PViews,$Day,$Month) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+([\d,]+)\s+(\d\d)\s+(\w\w\w)#o;
			} else {
				($Accesses,$Bytes,$Domains,$Day,$Month) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+(\d\d)\s+(\w\w\w)#o;
				$PViews = 0;
			}
			if ($Month) {
				$Accesses =~ s/,//g;
				$Bytes =~ s/,//g;
				$Domains =~ s/,//g;
				$PViews =~ s/,//g;
				$Year=$CurrYear;
				if (($Month =~ "(Nov|Dec)") &&
				  ($CurrMonth =~ "(Jan|Feb)")) {
					$Year=$Year-1;
				}
				$Today="$Year $MonthToNumber{$Month} $Day";
				$DayFilesCounter{$Today}=$Accesses;
				$BytesDay{$Today}=$Bytes;
				$DomainsDay{$Today}=$Domains;
				$PViewsDay{$Today}=$PViews;
				&date_to_count(int($MonthToNumber{$Month}),$Day,($Year-1900));
				if ($DayBreak-$perp_days < 35) {
					$DailyTotalBytesCounter+=$Bytes;
					$DailyTotalHitsCounter+=$Accesses;
					$DailyTotalVisitsCounter+=$Domains;
					$DailyTotalPViewsCounter+=$PViews;
				}
				$Today="$Today 00 00 00";
				$EndDate=$Today if ($Today gt $EndDate);
			}
			next;
		} elsif ($logsegment eq "dayofweek") {
			if ($NewFormat) {
				($Accesses,$Bytes,$Sessions,$PViews,$Day) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+([\d,]+)\s+(\w\w\w)#o;
			} else {
				($Accesses,$Bytes,$Sessions,$Day) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+(\w\w\w)#o;
				$PViews = 0;
			}
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$Sessions =~ s/,//g;
			$PViews =~ s/,//g;
			$DoWFilesCounter{$Day}=$Accesses;
			$DoWBytesCounter{$Day}=$Bytes;
			$DoWSessionsCounter{$Day}=$Sessions;
			$DoWPViewsCounter{$Day}=$PViews;
			$DoWTotalBytesCounter+=$Bytes;
			$DoWTotalHitsCounter+=$Accesses;
			$DoWTotalVisitsCounter+=$Sessions;
			$DoWTotalPViewsCounter+=$PViews;
			next;
		} elsif ($logsegment eq "hourly") {
			if ($NewFormat) {
				($Accesses,$Bytes,$Sessions,$PViews,$Hour) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+([\d,]+|-)\s+([\d,]+)\s+(\d\d)#o;
			} else {
				($Accesses,$Bytes,$Hour) =
				  m#^\s*([\d,]+)\s+([\d,]+)\s+(\d\d)#o;
				$Sessions = 0;
				$PViews = 0;
			}
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$Sessions =~ s/,//g;
			$PViews =~ s/,//g;
			$HourFilesCounter{$Hour}=$Accesses;
			$BytesHour{$Hour}=$Bytes;
			$VisitsHour{$Hour}=$Sessions;
			$PViewsHour{$Hour}=$PViews;
			$HourlyTotalBytesCounter+=$Bytes;
			$HourlyTotalHitsCounter+=$Accesses;
			$HourlyTotalVisitsCounter+=$Sessions;
			$HourlyTotalPViewsCounter+=$PViews;
			next;
		} elsif ($logsegment eq "records") {
			$line=$_;
			if ($line =~ m#Most Hits#o) {
				($RecordHits,$RecordHitsDate) =
				$line=~m#([\d,]*)\s\(([^)]*)\)#o;
				$RecordHits =~ s/,//g;
			} elsif ($line =~ m#Most Bytes#o) {
				($RecordBytes,$RecordBytesDate) =
				$line=~m#([\d,]*)\s\(([^)]*)\)#o;
				$RecordBytes =~ s/,//g;
			} elsif ($line =~ m#Most Visits#o) {
				($RecordVisits,$RecordVisitsDate) =
				$line=~m#([\d,]*)\s\(([^)]*)\)#o;
				$RecordVisits =~ s/,//g;
			} elsif ($line =~ m#Most PViews#o) {
				($RecordPViews,$RecordPViewsDate) =
				$line=~m#([\d,]*)\s\(([^)]*)\)#o;
				$RecordPViews =~ s/,//g;
			}
			next;
		} elsif ($logsegment eq "files") {
			($Hour,$Minute,$Second,$Day,$Month,$Year,
			  $Accesses,$Bytes,$FileName)=
			  m#^\s*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d) \s*([\d,]+)\s+([\d,]+)\s+(\S.*)#o;
			next unless ($Month =~ /$CurrMonth/);
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$TotalFilesCounter+=$Accesses;
			$TotalBytesCounter+=$Bytes;
			$HitsFileCounter{$FileName}=$Accesses;
			$BytesFileCounter{$FileName}=$Bytes;
			$LastAccessFile{$FileName}=
			  "$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
			next;
		} elsif ($logsegment eq "404") {
			($Hour,$Minute,$Second,$Day,$Month,$Year,
			  $Accesses,$Bytes,$FileName)=
			  m#^\s*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d) \s*([\d,]+)\s+([\d,]+)\s+(\S.*)#o;
			next unless ($Month =~ /$CurrMonth/);
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$fnfHitsFileCounter{$FileName}=$Accesses;
			$fnfBytesFileCounter{$FileName}=$Bytes;
			$fnfLastAccessFile{$FileName}="$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
			next;
		} elsif ($logsegment eq "userids") {
			($Hour,$Minute,$Second,$Day,$Month,$Year,
			  $Accesses,$Bytes,$UserID)=
			  m#^\s*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d) \s*([\d,]+)\s+([\d,]+)\s+(\S.*)#o;
			next unless ($Month =~ /$CurrMonth/);
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$HitsUserIDCounter{$UserID}=$Accesses;
			$BytesUserIDCounter{$UserID}=$Bytes;
			$LastAccessUserID{$UserID}=
			  "$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
			next;
		} elsif ($logsegment eq "topleveldomain") {
			($Hour,$Minute,$Second,$Day,$Month,$Year,
			  $Accesses,$Bytes,$TopDomain)=
			  m#^\s*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d) \s*([\d,]+)\s+([\d,]+)\s+(\w+)\s+=\s+#o;
			next unless ($Month =~ /$CurrMonth/);
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$TopDomainFilesCounter{$TopDomain}=$Accesses;
			$TopDomainBytesCounter{$TopDomain}=$Bytes;
			$TopDomainAccess{$TopDomain}="$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
			next;
		} elsif ($logsegment eq "domains") {
			($Hour,$Minute,$Second,$Day,$Month,$Year,
			  $Accesses,$Bytes,$Domain)=
			  m#^\s*(\d\d):(\d\d):(\d\d) (\d\d) (\w\w\w)\w* (\d\d\d\d) \s*([\d,]+)\s+([\d,]+)\s+(\S.*)#o;
			next unless ($Month =~ /$CurrMonth/);
			$Accesses =~ s/,//g;
			$Bytes =~ s/,//g;
			$DomainsFilesCounter{$Domain}=$Accesses;
			$DomainsBytesCounter{$Domain}=$Bytes;
			$LastAccessDomain{$Domain}="$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
			next;
		}
		close (OLD);
	}
}

sub ReadLog {
	unless ($NoResolve) {
		if ($IPLog) {
			if (-e "$IPLog") {
				open (IPLOG,"$IPLog") || die "  Error opening file: $IPLog\n";
				while(<IPLOG>) {
					($IP,$Domain)=m#^(\S+)\s+(.*)$#;
					$Resolved{$IP}=$Domain;
				}
				close (IPLOG);
			}
			open (IPLOG,">>$IPLog") || die "  Error opening file: $IPLog\n";
		}
	}
	$LogFile =~ s/.gz$//;
	if (-e "$LogFile.gz") {
		$ZipLock = 1;
		system ("gunzip -q $LogFile");
	}
	open (LOGFILE,"$LogFile") || die "  Error opening file: $LogFile\n";
	print "  Reading log file: $LogFile\n";
	$LogLineTotal = 0;
	$LogLineCount = 0;
	$logtype = "";
	while(<LOGFILE>) {
		$LogLineTotal++;
		chop;
		s/\s+/ /go;
		next if m/format\=\%/;
		if (($Domain,$rfc931,$authuser,$TimeDate,$Request,$Status,$Bytes,$referer,$Agent) =
		  /^(\S+) (\S+) (\S+) \[(.+)\] \"(.+)\" (\S+) (\S+) \"(.*)\" \"(.*)\"/o) {
			unless ($logtype) { $logtype = "combined"; }
			if (length($referer) < 5) { $referer = ""; }
			if (length($Agent) < 5) { $Agent = ""; }
		} elsif (($Domain,$rfc931,$authuser,$TimeDate,$Request,$Status,$Bytes) =
		  /^(\S+) (\S+) (\S+) \[(.+)\] \"(.+)\" (\S+) (\S+)/o) {
			unless ($logtype) { $logtype = "standard"; }
		} else {
			next;
		}
		next if (!($Domain && $rfc931 && $authuser && $TimeDate && $Request && $Status));
		($Day,$Month,$Year,$Hour,$Minute,$Second)=$TimeDate=~
		  m#^(\d+)/(\w\w\w)/(\d\d\d\d):(\d\d):(\d\d):(\d\d) #o;
		if (length($Day) == 1) { $Day = "0".$Day; }
		$Today="$Year $MonthToNumber{$Month} $Day $Hour $Minute $Second";
		$EndDate=$Today if ($Today gt $EndDate);
		$FileEndDate=$Today if ($Today gt $FileEndDate);
		$FileStartDate=$Today if ($Today lt $FileStartDate);
		next unless (!$LogOnlyNew || ($Today gt $InitialEndDate));
		($Method,$FileName,$Protocol)=split(/\s/,$Request,3);
		$FileName=~ s/\%7[eE]/~/o;
		$FileName=~ s#//#/#go;
		$FileName=~ s#^ *$#/#o;
		$FileName=~ s/#.+$//o;
		$target = $FileName;
		unless ($IncludeQuery) {
			$FileName=~s#\?.*$##o;
		}
		$FileName=~ s/${DefaultPageName}$//oi;
		next if (($IncludeOnlyRefsTo)
		  && !($FileName=~m#$IncludeOnlyRefsTo#o));
		next if (($ExcludeRefsTo)
		  && ($FileName=~m#$ExcludeRefsTo#o));
		$FileName=~s#&#\&amp\;#go;
		$FileName=~s#<#\&lt\;#go;
		$FileName=~s#>#\&gt\;#go;
		$FileName=~s#"#\&quot;#go;
		unless ($NoResolve) {
			if ($Domain =~ /\d+\.\d+\.\d+\.\d+/) {
				if ($Resolved{$Domain}) {
					$Domain = $Resolved{$Domain};
				} else {
					$Resolved{$Domain} = &addr_to_host($Domain);
					unless ($Resolved{$Domain}) {
						$Resolved{$Domain} = $Domain;
					}
					if ($IPLog) {
						print IPLOG "$Domain $Resolved{$Domain}\n";
					}
					$Domain = $Resolved{$Domain};
				}
			}
		}
		next if (($IncludeOnlyDomain)
		  && !($Domain=~m#$IncludeOnlyDomain#o));
		next if (($ExcludeDomain)
		  && ($Domain=~m#$ExcludeDomain#o));
		$PViewFilter = 0;
		if ((($Status>199)&&($Status<300))||($Status==304)) {
			unless ($DetailsFilter  && ($FileName=~m#$DetailsFilter#oi)) {
				$PViewFilter = 1;
			}
		}
		$Domain=~tr/A-Z/a-z/;
		$TrueDomain=$Domain;
		if ($PrintUserIDs && (length($authuser) > 1)) {
			$UserID = $authuser." (";
			if ($Domain =~ /\d$/) {
				$UserID = $UserID."Unresolved)";
			}
			elsif ($Domain =~ /([^.]*\.[^.]{3})$/) {
				$UserID = $UserID.$1.")";
			}
			elsif ($Domain =~ /([^.]*\.[^.]*\.[^.]{2})$/) {
				$UserID = $UserID.$1.")";
			}
			else {
				$UserID = $UserID."Unresolved)";
			}
		}
		if ($PrintDomains eq "2") {
			if ($Domain =~ /\d$/) {
				$Domain = "Unresolved";
			}
			elsif ($Domain =~ /([^.]*\.[^.]{3})$/) {
				$Domain = $1;
			}
			elsif ($Domain =~ /([^.]*\.[^.]*\.[^.]{2})$/) {
				$Domain = $1;
			}
			else {
				$Domain = "Unresolved";
			}
		}
		if ($referer && $RefsFile) {
			$target=~ s/\?.*$//o;
			$target=~ s/${DefaultPageName}$//oi;
			$target = &Simplify($target);
			$referer=~ s/\%7[eE]/~/o;
			$referer=~ s#^(http://[^/]+):80/#$1/#o;
			$refquery = "";
			if ($referer =~ m#^.+//([\w|\.|-]+)/.*\?(.+)#o) {
				$refdomain = $1;
				$refquery = $2;
			}
			$referer=~ s/#.+$//o;
			$referer=~ s/\?.*$//o;
			$referer=~ s/${DefaultPageName}$//oi;
			$referer = &Simplify($referer);
			unless (($refsexcludefrom && ($referer =~ m#$refsexcludefrom#oi))
			  || ($refsexcludeto && ($target =~ m#$refsexcludeto#oi))) {
				$keyform=$target.' '.$referer;
				$keyform=~ s#\&#\&amp\;#og;
				$keyform=~ s#<#\&lt\;#og;
				$keyform=~ s#>#\&gt\;#og;
				$keyform=~ s#"#\&quot\;#og;
				$referer=~ s#\&#\&amp\;#og;
				$referer=~ s#<#\&lt\;#og;
				$referer=~ s#>#\&gt\;#og;
				$referer=~ s#"#\&quot\;#og;
				$TargetCounter{$keyform}++;
			}
			else {
				$referer = "";
			}
			if ($referer && $refquery) {
				$refquery =~ tr/A-Z/a-z/;
				$refquery =~ s/\%.{2}/ /gi;
				$refquery =~ s/\+/ /g;
				$refquery =~ s/\-/ /g;
				$refquery =~ s/\s+/ /g;
				if (($refdomain =~ /altavista/i) && ($refquery =~ /\&q=\s*([^&]+)/i)) {
					$altavista{$1}++;
				}
				elsif ($refdomain =~ /netfind/i) {
					if (($refquery =~ /search=\s*([^&]+)/i)
					  || ($refquery =~ /\&s=\s*([^&]+)/i)) {
						$netfind{$1}++;
					}
				}
				elsif ($refdomain =~ /excite/i) {
					if (($refquery =~ /search=\s*([^&]+)/i)
					  || ($refquery =~ /\&s=\s*([^&]+)/i)) {
						$excite{$1}++;
					}
				}
				elsif (($refdomain =~ /hotbot/i) && ($refquery =~ /mt=\s*([^&]+)/i)) {
					$hotbot{$1}++;
				}
				elsif ($refdomain =~ /infoseek/i) {
					$iseek = "";
					if ($refquery =~ /qt=\s*([^&]+)/i) { $iseek .= $1; }
					if ($refquery =~ /oq=\s*([^&]+)/i) { $iseek .= " ".$1; }
					$iseek =~ s/^\s+//g;
					$iseek =~ s/\s+/ /g;
					if ($iseek) { $infoseek{$iseek}++; }
				}
				elsif (($refdomain =~ /lycos/i) && ($refquery =~ /query=\s*([^&]+)/i)) {
					$lycos{$1}++;
				}
				elsif (($refdomain =~ /snap/i) && ($refquery =~ /keyword=\s*([^&]+)/i)) {
					$snap{$1}++;
				}
				elsif ($refdomain =~ /webcrawler/i) {
					if (($refquery =~ /search=\s*([^&]+)/i)
					  || ($refquery =~ /searchtext=\s*([^&]+)/i)
					  || ($refquery =~ /text=\s*([^&]+)/i)) {
						$webcrawler{$1}++;
					}
				}
				elsif (($refdomain =~ /yahoo/i) && ($refquery =~ /p=\s*([^&]+)/i)) {
					$yahoo{$1}++;
				}
				elsif (($refquery =~ /general=\s*([^&]+)/i)
				  || ($refquery =~ /keyword=\s*([^&]+)/i)
				  || ($refquery =~ /keywords=\s*([^&]+)/i)
				  || ($refquery =~ /query=\s*([^&]+)/i)
				  || ($refquery =~ /search=\s*([^&]+)/i)
				  || ($refquery =~ /searchstring=\s*([^&]+)/i)
				  || ($refquery =~ /searchtext=\s*([^&]+)/i)
				  || ($refquery =~ /term=\s*([^&]+)/i)
				  || ($refquery =~ /terms=\s*([^&]+)/i)
				  || ($refquery =~ /text=\s*([^&]+)/i)) {
					$othersearch{$1}++;
				}
			}
		}
		if ($Agent && $AgentsFile) {
			unless ($AgentsIgnore && ($FileName=~m#$AgentsIgnore#oi)) {
				$refscounter++;
				$Agent =~ s/\&/\&amp\;/go;
				$Agent =~ s/"/\&quot\;/go;
				$Agent =~ s/</\&lt\;/go;
				$Agent =~ s/>/\&gt\;/go;
				($longagent,$other) = split(/ [ \n]/,$Agent,2);
				$agentcounter{$longagent}++;
			}
		}
		if ($Bytes eq "-") { $Bytes = 0; }
		if ($Status<400) { $Bytes+=250; }
		else { $Bytes+=500; }
		$HourFilesCounter{$Hour}++;
		if ($BytesHour{$Hour}) { $BytesHour{$Hour}+=$Bytes; }
		else { $BytesHour{$Hour} = $Bytes; }
		&date_to_count(int($MonthToNumber{$Month}),$Day,($Year-1900));
		$DoWFilesCounter{$perp_date}++;
		if ($DoWBytesCounter{$perp_date}) { $DoWBytesCounter{$perp_date}+=$Bytes; }
		else { $DoWBytesCounter{$perp_date} = $Bytes; }
		$MonthlyFilesCounter{"$Month $Year"}++;
		if ($MonthlyBytesCounter{"$Month $Year"}) { $MonthlyBytesCounter{"$Month $Year"}+=$Bytes; }
		else { $MonthlyBytesCounter{"$Month $Year"} = $Bytes; }
		$Today="$Year $MonthToNumber{$Month} $Day";
		$DayFilesCounter{$Today}++;
		if ($BytesDay{$Today}) { $BytesDay{$Today}+=$Bytes; }
		else { $BytesDay{$Today} = $Bytes; }
		if ($PViewFilter) {
			$MonthlyPViewsCounter{"$Month $Year"}++;
			$MonthlyTotalPViewsCounter++;
			$PViewsDay{$Today}++;
			$DoWPViewsCounter{$perp_date}++;
			$DoWTotalPViewsCounter++;
			$PViewsHour{$Hour}++;
			$HourlyTotalPViewsCounter++;
		}
		$Today="$Today $Hour $Minute $Second";
		$TopDomain=&GetTopDomain($Domain);
		if ($Month =~ /$CurrMonth/) {
			$DomainsFilesCounter{$Domain}++;
			if ($DomainsBytesCounter{$Domain}) { $DomainsBytesCounter{$Domain}+=$Bytes; }
			else { $DomainsBytesCounter{$Domain} = $Bytes; }
			unless ($LastAccessDomain{$Domain}) { $LastAccessDomain{$Domain} = 0; }
			if ($LastAccessDomain{$Domain} lt $Today) {
				$LastAccessDomain{$Domain}=$Today;
			}
			$TopDomainFilesCounter{$TopDomain}++;
			if ($TopDomainBytesCounter{$TopDomain}) { $TopDomainBytesCounter{$TopDomain}+=$Bytes; }
			else { $TopDomainBytesCounter{$TopDomain} = $Bytes; }
			if ($TopDomainAccess{$TopDomain} lt $Today) {
				$TopDomainAccess{$TopDomain} = $Today;
			}
		}
		$TotalBytesCounter+=$Bytes;
		$TotalFilesCounter++;
		$MonthlyTotalBytesCounter+=$Bytes;
		$MonthlyTotalHitsCounter++;
		if ($DayBreak-$perp_days < 35) {
			$DailyTotalBytesCounter+=$Bytes;
			$DailyTotalHitsCounter++;
			if ($PViewFilter) {
				$DailyTotalPViewsCounter++;
			}
		}
		$DoWTotalBytesCounter+=$Bytes;
		$DoWTotalHitsCounter++;
		$HourlyTotalBytesCounter+=$Bytes;
		$HourlyTotalHitsCounter++;
		$TodayBytes+=$Bytes;
		if ($PrintUserIDs && (length($authuser) > 1)) {
			if ($Month =~ /$CurrMonth/) {
				$HitsUserIDCounter{$UserID}++;
				if ($BytesUserIDCounter{$UserID}) { $BytesUserIDCounter{$UserID}+=$Bytes; }
				else { $BytesUserIDCounter{$UserID} = $Bytes; }
				if ($LastAccessUserID{$UserID} lt $Today) {
					$LastAccessUserID{$UserID}=$Today;
				}
			}
		}
		if ($Status==404) {
			if ($Month =~ /$CurrMonth/) {
				$fnfHitsFileCounter{$FileName}++;
				if ($fnfBytesFileCounter{$FileName}) { $fnfBytesFileCounter{$FileName}+=$Bytes; }
				else { $fnfBytesFileCounter{$FileName} = $Bytes; }
				if ($fnfLastAccessFile{$FileName} lt $Today) {
					$fnfLastAccessFile{$FileName}=$Today;
				}
			}
		}
		unless ((($Status>199)&&($Status<300))||($Status==304)) {
			$FileName = $RespCodes{$Status};
			if ($Month =~ /$CurrMonth/) {
				$HitsFileCounter{$FileName}++;
				if ($BytesFileCounter{$FileName}) { $BytesFileCounter{$FileName}+=$Bytes; }
				else { $BytesFileCounter{$FileName} = $Bytes; }
				if ($LastAccessFile{$FileName} lt $Today) {
					$LastAccessFile{$FileName}=$Today;
				}
			}
			if (($Status>299)&&($Status<400)) {
				$TodayHits++;
			}
			else {
				$TodayErrors++;
			}
		} else {
			if ($Month =~ /$CurrMonth/) {
				$HitsFileCounter{$FileName}++;
				if ($BytesFileCounter{$FileName}) { $BytesFileCounter{$FileName}+=$Bytes; }
				else { $BytesFileCounter{$FileName} = $Bytes; }
				if ($LastAccessFile{$FileName} lt $Today) {
					$LastAccessFile{$FileName}=$Today;
				}
			}
			$TodayHits++;
			if ($PViewFilter) {
				if ($OrgDomain) {
					if ($TrueDomain !~ /\./) {
						$TrueDomain .= ".$OrgDomain";
					}
					if ($TrueDomain =~ /.*$OrgDomain/) {
						$TodayLocal++;
					}
				}
				$TodayPages++;
				$TodayDomains{$TopDomain}++;
				$TodayHosts{$TrueDomain}++;
				$TodayPages{$FileName}++;
				unless ($RefsFile) { $referer = "-"; }
				unless ($referer) { $referer = "-"; }
				push (@Accesses, "$perp_days $Hour $Minute $Second $TrueDomain $FileName $referer");
			}
		}
		$LogLineCount++;
	}
	close (LOGFILE);
	unless ($NoResolve) {
		if ($IPLog) {
			close (IPLOG);
		}
	}
	if ($ZipLock) {
		system ("gzip $LogFile");
	}
	unless ($logtype eq "combined") {
		unless ($logtype eq "standard") {
			print "    Error: Unrecognized access log format\n";
			return;
		}
		$RefsFile = "";
		$AgentsFile = "";
	}
	print "    ",&commas($LogLineTotal)," log entries analyzed\n";
	print "    ",&commas($LogLineCount)," log entries processed for report\n";
	unless ($RefsFile) { $KeywordsFile = ""; }
}

sub GetTopDomain {
	local($domname) = $_[0];
	($TopDomain)=($domname=~m#\.(\w+)$#o);
	$TopDomain=~tr/A-Z/a-z/;
	$TopDomain=~s/\d//g;
	$TopDomain="xxx" if ($TopDomain eq "");
	return $TopDomain;
}

sub addr_to_host {
	local($ip_address) = $_[0];
	local(@bytes) = split(/\./, $ip_address);
	local($packaddr) = pack("C4",@bytes);
	local($host_name) = (gethostbyaddr($packaddr, 2))[0];
	return($host_name);
}

sub PrintReport {
	open (REPORT,">$FileDir/$ReportFile") || die "  Error opening file: $ReportFile\n";
	print REPORT "<HTML><HEAD><TITLE>Access Log: $SystemName</TITLE></HEAD>";
	print REPORT "<BODY BGCOLOR=\"#99ccff\" TEXT=\"#000000\">\n";
	print REPORT "<!--WebLog 1.20 Format-->\n";
	print REPORT "<H1 ALIGN=CENTER>Access Log:<BR>$SystemName</H1>\n";
	unless ($EndDate eq "0000 00 00 00 00 00") {
		print REPORT "<P ALIGN=CENTER><STRONG>(Accesses Through ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$EndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year)</STRONG></P>\n";
	}
	if ($DetailsFile || $RefsFile || $KeywordsFile || $AgentsFile) {
		print REPORT "<P ALIGN=CENTER>|";
		if ($DetailsFile) {
			print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
		}
		if ($RefsFile) {
			print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
		}
		if ($KeywordsFile) {
			print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
		}
		if ($AgentsFile) {
			print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
		}
		print REPORT "</P>\n";
	}
	print REPORT "<A NAME=\"index\"><HR></A>\n";
	print REPORT "<H2 ALIGN=CENTER>Index</H2>\n";
	print REPORT "<P><CENTER><TABLE><TR>\n";
	print REPORT "<TD VALIGN=TOP>\n";
	print REPORT "<P ALIGN=CENTER><STRONG>Long-Term Statistics:</STRONG></P><P><UL>\n";
	print REPORT "<LI><A HREF=\"#monthly\">Monthly Statistics</A>\n";
	print REPORT "<LI><A HREF=\"#daily\">Daily Statistics (Past Five Weeks)</A>\n";
	print REPORT "<LI><A HREF=\"#dayofweek\">Day of Week Statistics</A>\n";
	print REPORT "<LI><A HREF=\"#hourly\">Hourly Statistics</A>\n";
	print REPORT "<P><LI><A HREF=\"#records\">&quot;Record Book&quot;</A>\n";
	print REPORT "</UL></P></TD><TD><P>&nbsp; &nbsp; &nbsp</P>";
	print REPORT "</TD><TD VALIGN=TOP>\n";
	print REPORT "<P ALIGN=CENTER><STRONG>Statistics for the Current Month ($CurrMonth $CurrYear):</STRONG></P><P><UL>\n";
	if ($PrintFiles) {
		if ($PrintTopNFiles) {
			print REPORT "<LI><A HREF=\"#topnfilesbyhits\">Top $PrintTopNFiles Files by Number of Hits</A>\n";
			print REPORT "<LI><A HREF=\"#topnfilesbyvolume\">Top $PrintTopNFiles Files by Volume</A>\n";
		}
		print REPORT "<LI><A HREF=\"#files\">Complete File Statistics</A><P>\n";
	}
	if ($Print404) {
		if ($PrintTopNFiles) {
			print REPORT "<LI><A HREF=\"#topn404\">Top $PrintTopNFiles Most Frequently Requested 404 Files</A>\n";
		}
		print REPORT "<LI><A HREF=\"#404\">Complete 404 File Not Found Statistics</A><P>\n";
	}
	if ($PrintUserIDs) {
		print REPORT "<LI><A HREF=\"#userids\">User ID Statistics</A><P>\n";
	}
	print REPORT "<LI><A HREF=\"#topleveldomain\">\"Top Level\" Domains</A>\n";
	if ($PrintDomains) {
		if ($PrintTopNDomains) {
			print REPORT "<LI><A HREF=\"#topnsitesbyhits\">Top $PrintTopNDomains Domains by Number of Hits</A>\n";
			print REPORT "<LI><A HREF=\"#topnsitesbyvolume\">Top $PrintTopNDomains Domains by Volume</A>\n";
		}
		print REPORT "<LI><A HREF=\"#domains\">Complete Domain Statistics</A>\n";
	}
	print REPORT "</UL></P></TD></TR></TABLE></CENTER></P>\n";
	print REPORT "<P><CENTER><TABLE BORDER CELLPADDING=6><TR>\n";
	print REPORT "<TD><P ALIGN=CENTER><BIG><STRONG>Key Terms:</STRONG></BIG>\n";
	print REPORT "<P ALIGN=CENTER><STRONG>Hits:</STRONG> The total number of files requested from the server.\n";
	print REPORT "<BR><STRONG>Bytes:</STRONG> The amount of information transferred in filling those requests.\n";
	print REPORT "<BR><STRONG>Visits:</STRONG> The (approximate) number of actual individual visitors.\n";
	print REPORT "<BR><STRONG>PViews:</STRONG> The number of Web pages viewed by those visitors.\n";
	print REPORT "<P ALIGN=CENTER>The bar graphs below are based upon ";
	if ($GraphBase eq "hits") { print REPORT "number of hits"; }
	elsif ($GraphBase eq "visits") { print REPORT "number of visitors"; }
	elsif ($GraphBase eq "pviews") { print REPORT "page views"; }
	else { print REPORT "bytes transferred"; }
	print REPORT ".</P></TD>\n";
	print REPORT "</TR></TABLE></CENTER></P>\n";
	&PrintMonthlyReport;
	&PrintDailyReport;
	&PrintDayofWeekReport;
	&PrintHourlyReport;
	&PrintRecords;
	if ($PrintFiles) {
		if ($PrintTopNFiles) {
			&PrintTopNFilesByHitsReport;
			&PrintTopNFilesByVolumeReport;
		}
		&PrintFilesReport;
	}
	if ($Print404) {
		if ($PrintTopNFiles) {
			&PrintTopN404Report;
		}
		&Print404Report;
	}
	if ($PrintUserIDs) {
		&PrintUserIDsReport;
	}
	&PrintTopLevelDomainsReport;
	if ($PrintDomains) {
		if ($PrintTopNDomains) {
			&PrintTopNDomainsByHitsReport;
			&PrintTopNDomainsByVolumeReport;
		}
		&PrintReversedDomainsReport;
	}
	print REPORT "<HR>\n";
	if ($DetailsFile || $RefsFile || $AgentsFile) {
		print REPORT "<P ALIGN=CENTER>|";
		if ($DetailsFile) {
			print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
		}
		if ($RefsFile) {
			print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
		}
		if ($KeywordsFile) {
			print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
		}
		if ($AgentsFile) {
			print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
		}
		print REPORT "</P>\n";
	}
	print REPORT "<P ALIGN=CENTER>";
	print REPORT "<SMALL>This report was generated by ";
	print REPORT "<STRONG><A HREF=";
	print REPORT "\"http://awsd.com/scripts/weblog/\">";
	print REPORT "WebLog $version</A></STRONG></SMALL></P>\n";
	print REPORT "</BODY></HTML>\n";
	close (REPORT);
}

sub PrintMonthlyReport {
	print REPORT "<A NAME=\"monthly\"><HR></A><H2 ALIGN=CENTER>Monthly Statistics</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "        Hits               Bytes      Visits      PViews      Month\n\n";
	($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$EndDate);
	&date_to_count(int($Month),$Day,($Year-1900));
	$MonthlyCounter{$perp_mons}="$Month $Year";
	$MonthCounter = $perp_mons;
	foreach $key (1..$perp_mons) {
		&count_to_mon($key);
		if ($perp_mon < 10) { $perp_mon = "0".$perp_mon; }
		$perp_year = $perp_year + 1900;
		$MonthlyCounter{$key}="$NumberToMonth{$perp_mon} $perp_year";
		unless ($MonthlySessionsCounter{$MonthlyCounter{$key}}) {
			$MonthlySessionsCounter{$MonthlyCounter{$key}} = 0;
		}
		unless ($monthusersessions{$key}) { $monthusersessions{$key} = 0; }
		$MonthlySessionsCounter{$MonthlyCounter{$key}} +=
		  $monthusersessions{$key};
		$MonthlyTotalVisitsCounter += $monthusersessions{$key};
	}
	foreach $key (1..$perp_mons) {
		&count_to_mon($key);
		if ($perp_mon < 10) { $perp_mon = "0".$perp_mon; }
		$perp_year = $perp_year + 1900;
		$MonthlyCounter{$key}="$NumberToMonth{$perp_mon} $perp_year";
		unless ($MonthlyBytesCounter{$MonthlyCounter{$key}}) {
			unless ($GoMonthly) {
				$MonthCounter--;
				next;
			}
			$MonthlyFilesCounter{$MonthlyCounter{$key}} = 0;
			$MonthlyBytesCounter{$MonthlyCounter{$key}} = 0;
			$MonthlySessionsCounter{$MonthlyCounter{$key}} = 0;
			$MonthlyPViewsCounter{$MonthlyCounter{$key}} = 0;
		}
		unless ($MonthlyPViewsCounter{$MonthlyCounter{$key}}) {
			$MonthlyPViewsCounter{$MonthlyCounter{$key}} = 0;
		}
		$GoMonthly = 1;
		if ($NoSessions) { $MonthlySessionsCounter{$MonthlyCounter{$key}} = "-"; }
		printf REPORT "%12s%20s%12s%12s%13s",&commas($MonthlyFilesCounter{$MonthlyCounter{$key}}),
		  &commas($MonthlyBytesCounter{$MonthlyCounter{$key}}),&commas($MonthlySessionsCounter{$MonthlyCounter{$key}}),&commas($MonthlyPViewsCounter{$MonthlyCounter{$key}}),
		  " $MonthlyCounter{$key}  ";
		if ($GraphBase eq "hits") {
			if ($MonthlyTotalHitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($MonthlyFilesCounter{$MonthlyCounter{$key}}/$MonthlyTotalHitsCounter)*($MonthCounter*10))+.5;
			}
		}
		elsif ($GraphBase eq "visits") {
			if ($MonthlyTotalVisitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($MonthlySessionsCounter{$MonthlyCounter{$key}}/$MonthlyTotalVisitsCounter)*($MonthCounter*10))+.5;
			}
		}
		elsif ($GraphBase eq "pviews") {
			if ($MonthlyTotalPViewsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($MonthlyPViewsCounter{$MonthlyCounter{$key}}/$MonthlyTotalPViewsCounter)*($MonthCounter*10))+.5;
			}
		}
		else {
			if ($MonthlyTotalBytesCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($MonthlyBytesCounter{$MonthlyCounter{$key}}/$MonthlyTotalBytesCounter)*($MonthCounter*10))+.5;
			}
		}
		&PrintBarGraph;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintBarGraph {
	if ($GraphURL) {
		if ($Percent<5) {
			print REPORT "<IMG SRC=\"$GraphURL/bar1.gif\" HEIGHT=7 WIDTH=4 ALT=\"\">"x$Percent;
			$Percent=0;
		}
		else {
			print REPORT "<IMG SRC=\"$GraphURL/bar2.gif\" HEIGHT=7 WIDTH=20 ALT=\"\">";
			$Percent=$Percent-5;
		}
		if ($Percent<10) {
			print REPORT "<IMG SRC=\"$GraphURL/bar3.gif\" HEIGHT=7 WIDTH=4 ALT=\"\">"x$Percent;
			$Percent=0;
		}
		else {
			print REPORT "<IMG SRC=\"$GraphURL/bar4.gif\" HEIGHT=7 WIDTH=40 ALT=\"\">";
			$Percent=$Percent-10;
		}
		if ($Percent<10) {
			print REPORT "<IMG SRC=\"$GraphURL/bar5.gif\" HEIGHT=7 WIDTH=4 ALT=\"\">"x$Percent;
			$Percent=0;
		}
		else {
			print REPORT "<IMG SRC=\"$GraphURL/bar6.gif\" HEIGHT=7 WIDTH=40 ALT=\"\">";
			$Percent=$Percent-10;
		}
		print REPORT "<IMG SRC=\"$GraphURL/bar5.gif\" HEIGHT=7 WIDTH=4 ALT=\"\">"x$Percent;
	}
	print REPORT "\n";
}

sub PrintDailyReport {
	print REPORT "<A NAME=\"daily\"><HR></A><H2 ALIGN=CENTER>Daily Statistics (Past Five Weeks)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "        Hits               Bytes      Visits      PViews       Date\n\n";
	$DayCount=35;
	($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$EndDate);
	&date_to_count(int($Month),$Day,($Year-1900));
	$FinalDay = $perp_days;
	$DayCount = $DayCount-($DayBreak-$FinalDay);
	foreach $key (($DayBreak-34)..$FinalDay) {
		&count_to_date($key);
		$Year = $perp_year+1900;
		$Month = $perp_mon;
		if ($Month < 10) { $Month = "0".$Month; }
		$Day = $perp_day;
		if ($Day < 10) { $Day = "0".$Day; }
		$Today="$Year $Month $Day";
		unless ($DomainsDay{$Today}) { $DomainsDay{$Today} = 0; }
		unless ($dayusersessions{$key}) { $dayusersessions{$key} = 0; }
		$DomainsDay{$Today} += $dayusersessions{$key};
		$DailyTotalVisitsCounter += $dayusersessions{$key};
	}
	foreach $key (($DayBreak-34)..$FinalDay) {
		&count_to_date($key);
		$Year = $perp_year+1900;
		$Month = $perp_mon;
		if ($Month < 10) { $Month = "0".$Month; }
		$Day = $perp_day;
		if ($Day < 10) { $Day = "0".$Day; }
		$Today="$Year $Month $Day";
		unless ($BytesDay{$Today}) {
			unless ($GoDaily) {
				$DayCount--;
				next;
			}
			$DayFilesCounter{$Today} = 0;
			$BytesDay{$Today} = 0;
			$DomainsDay{$Today} = 0;
			$PViewsDay{$Today} = 0;
		}
		unless ($PViewsDay{$Today}) {
			$PViewsDay{$Today} = 0;
		}
		$GoDaily = 1;
		if ($key-(int($key/7)*7)==3) {
			print REPORT "\n";
		}
		$RecordDate = "$NumberToMonth{$Month} $Day, $Year";
		if ($DayFilesCounter{$Today} > $RecordHits) {
			$RecordHits = $DayFilesCounter{$Today};
			$RecordHitsDate = $RecordDate;
		}
		if ($BytesDay{$Today} > $RecordBytes) {
			$RecordBytes = $BytesDay{$Today};
			$RecordBytesDate = $RecordDate;
		}
		if ($DomainsDay{$Today} > $RecordVisits) {
			$RecordVisits = $DomainsDay{$Today};
			$RecordVisitsDate = $RecordDate;
		}
		if ($PViewsDay{$Today} > $RecordPViews) {
			$RecordPViews = $PViewsDay{$Today};
			$RecordPViewsDate = $RecordDate;
		}
		if ($NoSessions) { $DomainsDay{$Today} = "-"; }
		printf REPORT "%12s%20s%12s%12s%13s",&commas($DayFilesCounter{$Today}),&commas($BytesDay{$Today}),&commas($DomainsDay{$Today}),&commas($PViewsDay{$Today}),
		  "$Day $NumberToMonth{$Month}  ";
		if ($GraphBase eq "hits") {
			if ($DailyTotalHitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DayFilesCounter{$Today}/$DailyTotalHitsCounter)*($DayCount*10))+.5;
			}
		}
		elsif ($GraphBase eq "visits") {
			if ($DailyTotalVisitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DomainsDay{$Today}/$DailyTotalVisitsCounter)*($DayCount*10))+.5;
			}
		}
		elsif ($GraphBase eq "pviews") {
			if ($DailyTotalPViewsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($PViewsDay{$Today}/$DailyTotalPViewsCounter)*($DayCount*10))+.5;
			}
		}
		else {
			if ($DailyTotalBytesCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($BytesDay{$Today}/$DailyTotalBytesCounter)*($DayCount*10))+.5;
			}
		}
		&PrintBarGraph;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintDayofWeekReport {
	print REPORT "<A NAME=\"dayofweek\"><HR></A><H2 ALIGN=CENTER>Day of Week Statistics</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "        Hits               Bytes      Visits      PViews        Day\n\n";
	foreach $key (1..7) {
		unless ($DoWSessionsCounter{$DoWCounter{$key}}) {
			$DoWSessionsCounter{$DoWCounter{$key}} = 0;
		}
		unless ($dowusersessions{$DoWCounter{$key}}) {
			$dowusersessions{$DoWCounter{$key}} = 0;
		}
		$DoWSessionsCounter{$DoWCounter{$key}} +=
		  $dowusersessions{$DoWCounter{$key}};
		$DoWTotalVisitsCounter += $dowusersessions{$DoWCounter{$key}};
	}
	foreach $key (1..7) {
		if ($DoWBytesCounter{$DoWCounter{$key}} < 1) {
			$DoWFilesCounter{$DoWCounter{$key}} = 0;
			$DoWBytesCounter{$DoWCounter{$key}} = 0;
			$DoWSessionsCounter{$DoWCounter{$key}} = 0;
			$DoWPViewsCounter{$DoWCounter{$key}} = 0;
		}
		unless ($DoWPViewsCounter{$DoWCounter{$key}}) {
			$DoWPViewsCounter{$DoWCounter{$key}} = 0;
		}
		if ($NoSessions) { $DoWSessionsCounter{$DoWCounter{$key}} = "-"; }
		printf REPORT "%12s%20s%12s%12s%13s",&commas($DoWFilesCounter{$DoWCounter{$key}}),
		  &commas($DoWBytesCounter{$DoWCounter{$key}}),
		  &commas($DoWSessionsCounter{$DoWCounter{$key}}),
		  &commas($DoWPViewsCounter{$DoWCounter{$key}}),"      $DoWCounter{$key}  ";
		if ($GraphBase eq "hits") {
			if ($DoWTotalHitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DoWFilesCounter{$DoWCounter{$key}}/$DoWTotalHitsCounter)*70)+.5;
			}
		}
		elsif ($GraphBase eq "visits") {
			if ($DoWTotalVisitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DoWSessionsCounter{$DoWCounter{$key}}/$DoWTotalVisitsCounter)*70)+.5;
			}
		}
		elsif ($GraphBase eq "pviews") {
			if ($DoWTotalPViewsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DoWPViewsCounter{$DoWCounter{$key}}/$DoWTotalPViewsCounter)*70)+.5;
			}
		}
		else {
			if ($DoWTotalBytesCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($DoWBytesCounter{$DoWCounter{$key}}/$DoWTotalBytesCounter)*70)+.5;
			}
		}
		&PrintBarGraph;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintHourlyReport {
	print REPORT "<A NAME=\"hourly\"><HR></A><H2 ALIGN=CENTER>Hourly Statistics</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "        Hits               Bytes      Visits      PViews       Hour\n\n";
	foreach $key (00..23) {
		if ($key<10) { $key="0".$key; }
		unless ($VisitsHour{$key}) { $VisitsHour{$key} = 0; }
		unless ($hourusersessions{$key}) { $hourusersessions{$key} = 0; }
		$VisitsHour{$key} += $hourusersessions{$key};
		$HourlyTotalVisitsCounter += $hourusersessions{$key};
	}
	foreach $key (00..23) {
		if ($key<10) { $key="0".$key; }
		unless ($HourFilesCounter{$key}) { $HourFilesCounter{$key} = 0; }
		unless ($BytesHour{$key}) { $BytesHour{$key} = 0; }
		unless ($VisitsHour{$key}) { $VisitsHour{$key} = 0; }
		unless ($PViewsHour{$key}) { $PViewsHour{$key} = 0; }
		printf REPORT "%12s%20s%12s%12s%13s",&commas($HourFilesCounter{$key}),
		  &commas($BytesHour{$key}),&commas($VisitsHour{$key}),
		  &commas($PViewsHour{$key}),"      $key  ";
		if ($GraphBase eq "hits") {
			if ($HourlyTotalHitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($HourFilesCounter{$key}/$HourlyTotalHitsCounter)*240)+.5;
			}
		}
		elsif ($GraphBase eq "visits") {
			if ($HourlyTotalVisitsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($VisitsHour{$key}/$HourlyTotalVisitsCounter)*240)+.5;
			}
		}
		elsif ($GraphBase eq "pviews") {
			if ($HourlyTotalPViewsCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($PViewsHour{$key}/$HourlyTotalPViewsCounter)*240)+.5;
			}
		}
		else {
			if ($HourlyTotalBytesCounter < 1.0) { $Percent=0; }
			else {
				$Percent=(($BytesHour{$key}/$HourlyTotalBytesCounter)*240)+.5;
			}
		}
		&PrintBarGraph;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintRecords {
	print REPORT "<A NAME=\"records\"><HR></A><H2 ALIGN=CENTER>&quot;Record Book&quot;</H2>\n";
	print REPORT "<P><STRONG>Most Hits:</STRONG> ";
	print REPORT &commas($RecordHits)," ($RecordHitsDate)\n";
	print REPORT "<P><STRONG>Most Bytes:</STRONG> ";
	print REPORT &commas($RecordBytes)," ($RecordBytesDate)\n";
	unless ($NoSessions) {
		print REPORT "<P><STRONG>Most Visits:</STRONG> ";
		print REPORT &commas($RecordVisits)," ($RecordVisitsDate)\n";
	}
	print REPORT "<P><STRONG>Most PViews:</STRONG> ";
	print REPORT &commas($RecordPViews)," ($RecordPViewsDate)\n";
	print REPORT "<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub commas {
	local($_)=@_;
	1 while s/(.*\d)(\d\d\d)/$1,$2/;
	$_;
}

sub PrintTopNFilesByHitsReport {
	print REPORT "<A NAME=\"topnfilesbyhits\"><HR></A><H2 ALIGN=CENTER>Top $PrintTopNFiles Files ";
	print REPORT "by Number of Hits ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   File\n\n";
	$Counter=1;
	foreach $key (sort ByHitsFiles keys(%HitsFileCounter)) {
		last if ($Counter > $PrintTopNFiles);
		next if ($TopFileListFilter && ($key=~m#$TopFileListFilter#oi));
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessFile{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($HitsFileCounter{$key}),&commas($BytesFileCounter{$key}),$key;
		$Counter++;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByHitsFiles {
	$HitsFileCounter{$b}<=>$HitsFileCounter{$a};
}

sub PrintTopNFilesByVolumeReport {
	print REPORT "<A NAME=\"topnfilesbyvolume\"><HR></A><H2 ALIGN=CENTER>Top $PrintTopNFiles Files ";
	print REPORT "by Volume ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   File\n\n";
	$Counter=1;
	foreach $key (sort ByVolumeFiles keys(%HitsFileCounter)) {
		last if ($Counter > $PrintTopNFiles);
		next if ($TopFileListFilter && ($key=~m#$TopFileListFilter#oi));
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessFile{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($HitsFileCounter{$key}),&commas($BytesFileCounter{$key}),$key;
		$Counter++;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByVolumeFiles {
	$BytesFileCounter{$b}<=>$BytesFileCounter{$a};
}

sub PrintFilesReport {
	print REPORT "<A NAME=\"files\"><HR></A><H2 ALIGN=CENTER>Complete File Statistics ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   File\n\n";
	foreach $key (sort keys(%HitsFileCounter)) {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessFile{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($HitsFileCounter{$key}),&commas($BytesFileCounter{$key}),$key;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintTopN404Report {
	print REPORT "<A NAME=\"topn404\"><HR></A><H2 ALIGN=CENTER>Top $PrintTopNFiles Most Frequently Requested ";
	print REPORT "404 Files ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   File\n\n";
	$Counter=1;
	foreach $key (sort ByfnfHitsFiles keys(%fnfHitsFileCounter)) {
		last if ($Counter > $PrintTopNFiles);
		next if ($TopFileListFilter && ($key=~m#$TopFileListFilter#oi));
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$fnfLastAccessFile{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($fnfHitsFileCounter{$key}),&commas($fnfBytesFileCounter{$key}),$key;
		$Counter++;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByfnfHitsFiles {
	$fnfHitsFileCounter{$b}<=>$fnfHitsFileCounter{$a};
}

sub Print404Report {
	print REPORT "<A NAME=\"404\"><HR></A><H2 ALIGN=CENTER>Complete 404 File Not Found Statistics ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   File\n\n";
	foreach $key (sort keys(%fnfHitsFileCounter)) {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$fnfLastAccessFile{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($fnfHitsFileCounter{$key}),&commas($fnfBytesFileCounter{$key}),$key;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintUserIDsReport {
	print REPORT "<A NAME=\"userids\"><HR></A><H2 ALIGN=CENTER>User ID Statistics ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   User ID (Domain)\n\n";
	foreach $key (sort keys(%HitsUserIDCounter)) {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessUserID{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($HitsUserIDCounter{$key}),&commas($BytesUserIDCounter{$key}),$key;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub PrintTopLevelDomainsReport {
	print REPORT "<A NAME=\"topleveldomain\"><HR></A><H2 ALIGN=CENTER>\"Top Level\" Domains ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Accessed               Hits           Bytes   \"Top Level\" Domain\n\n";
	foreach $TopDomain (sort ByTopDomain keys(%TopDomainBytesCounter)) {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$TopDomainAccess{$TopDomain});
		$Month=$NumberToMonth{$Month};
		unless ($TopDomainFilesCounter{$TopDomain}<1) {
			printf REPORT "%-21s%11s%16s   %-4s = %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
			  &commas($TopDomainFilesCounter{$TopDomain}),
			  &commas($TopDomainBytesCounter{$TopDomain}),$TopDomain,$CountryCode{$TopDomain};
		}
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByTopDomain {
	$TopDomainBytesCounter{$b}<=>$TopDomainBytesCounter{$a};
}

sub PrintTopNDomainsByHitsReport {
	print REPORT "<A NAME=\"topnsitesbyhits\"><HR></A><H2 ALIGN=CENTER>Top $PrintTopNDomains Domains ";
	print REPORT "by Number of Hits ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Access                 Hits           Bytes   Domain\n\n";
	$Counter=1;
	foreach $key (sort ByNDomains keys(%DomainsFilesCounter)) {
		last if ($Counter > $PrintTopNDomains);
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessDomain{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($DomainsFilesCounter{$key}),&commas($DomainsBytesCounter{$key}),$key;
		$Counter++;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByNDomains {
	$DomainsFilesCounter{$b}<=>$DomainsFilesCounter{$a};
}

sub PrintTopNDomainsByVolumeReport {
	print REPORT "<A NAME=\"topnsitesbyvolume\"><HR></A><H2 ALIGN=CENTER>Top $PrintTopNDomains Domains ";
	print REPORT "by Volume ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Access                 Hits           Bytes   Domain\n\n";
	$Counter=1;
	foreach $key (sort ByVolumeDomains keys(%DomainsFilesCounter)) {
		last if ($Counter > $PrintTopNDomains);
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessDomain{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($DomainsFilesCounter{$key}),&commas($DomainsBytesCounter{$key}),$key;
		$Counter++;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByVolumeDomains {
	$DomainsBytesCounter{$b}<=>$DomainsBytesCounter{$a};
}

sub PrintReversedDomainsReport {
	print REPORT "<A NAME=\"domains\"><HR></A><H2 ALIGN=CENTER>Complete Domain Statistics ($CurrMonth $CurrYear)</H2>\n";
	print REPORT "<PRE>\n";
	print REPORT "Last Access                 Hits           Bytes   Domain\n\n";
	foreach $key (sort ByReversedSubDomain keys(%DomainsFilesCounter)) {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=split(/ /,$LastAccessDomain{$key});
		$Month=$NumberToMonth{$Month};
		printf REPORT "%-21s%11s%16s   %-s\n","$Hour:$Minute:$Second $Day $Month $Year",
		  &commas($DomainsFilesCounter{$key}),&commas($DomainsBytesCounter{$key}),$key;
	}
	print REPORT "</PRE>\n<P ALIGN=CENTER><SMALL>[ <A HREF=\"#index\">Return to Index</A> ]</SMALL></P>\n\n";
}

sub ByReversedSubDomain {
	local(@adomains,@bdomains,$aisIP,$bisIP,$counter,$acounter,$bcounter,$result);
	$result=0;
	(@adomains)=split(/\./,$a);
	(@bdomains)=split(/\./,$b);
	$aisIP=$a=~m#^\d+\.\d+\.\d+\.\d+$#o;
	$bisIP=$b=~m#^\d+\.\d+\.\d+\.\d+$#o;
	if ($aisIP && (!$bisIP)) {
		$result=-1;
	} elsif ((!$aisIP) && $bisIP) {
		$result=1;
	} elsif ($aisIP && $bisIP) {
		$counter=0;
		while ((!$result) && ($counter < 4)) {
			$result=$adomains[$counter] <=> $bdomains[$counter];
			$counter++;
		}
	} elsif ((!$aisIP) && (!$bisIP)) {
		$acounter=$#adomains;
		$bcounter=$#bdomains;
		while ((!$result) && ($acounter>=0) && ($bcounter>=0)) {
			$result=$adomains[$acounter] cmp $bdomains[$bcounter];
			$acounter--;
			$bcounter--;
		}
		if (!$result) {
			$result=1 if ($acounter>=0);
			$result=-1 if ($bcounter>=0);
		}
	}
	$result;
}

sub GetSessions {
	if (!$TodayHits) { $TodayHits=0; }
	if (!$TodayErrors) { $TodayErrors=0; }
	unless ($TodayPages < 1 ) {
		@RevAccesses=reverse(@Accesses);
		undef @Accesses;
		foreach $entry (@RevAccesses) {
			($daycount,$hour,$minute,$second,$remote,$page,$referer)=split(" ",$entry);
			$visit=(($hour*3600)+($minute*60)+$second);
			$duration=-.5;
			if ($prevvisit{$remote}) {
				$duration=($prevvisit{$remote}-$visit);
			}
			$prevvisit{$remote}=$visit;
			if (($duration < -.5)
			  && (($prevday{$remote}-$daycount)<2)) {
				$duration=$duration+86400;
			} elsif (($duration > -.5)
			  && ($prevday{$remote} ne $daycount)) {
				$duration=-.5;
			}
			$prevday{$remote} = $daycount;
			if ($duration > 1800) { $duration=-.5; }
			if ($duration < 0) {
				$usersessions ++;
				$sessionstime=$sessionstime+30;
				$dayusersessions{$daycount}++;
				&count_to_date($daycount);
				&date_to_count($perp_mon,$perp_day,$perp_year);
				$monthusersessions{$perp_mons}++;
				$dowusersessions{$perp_date}++;
				$hourusersessions{$hour}++;
			}
			else {
				$sessionstime=$sessionstime+$duration;
			}
			$durminute=int($duration/60);
			$dursecond=$duration-($durminute*60);
			if ($durminute < 10) { $durminute="0".$durminute; }
			if ($dursecond < 10) { $dursecond="0".$dursecond; }
			push (@Accesses, "$hour $minute $second $durminute $dursecond $remote $page $referer");
		}
	}
}

sub PrintHostDetailsReport {
	if ($DetailsDays<1) { $DetailsDays=1; }
	if ($DetailsDays>35) { $DetailsDays=35; }
	$datestamp = 0;
	if ((-e "$FileDir/$DetailsFile") && ($DetailsDays>1)) {
		open (FILE,"$FileDir/$DetailsFile") || die "  Error opening file: $DetailsFile\n";
		while (<FILE>) {
			if (m#DATESTAMP=\"(\d+)#o) {
				$datestamp = $1;
				$DetailsDays--;
			}
			if (($DetailsDays > 0) && ($datestamp > 0)) {
				push (@lines, $_);
			}
		}
		close (FILE);
	}
	open (REPORT,">$FileDir/$DetailsFile") || die "  Error opening file: $DetailsFile\n";
	print REPORT "<HTML><HEAD><TITLE>Access Details Report: $SystemName</TITLE></HEAD>";
	print REPORT "<BODY BGCOLOR=\"#99ccff\" TEXT=\"#000000\">\n";
	print REPORT "<H1 ALIGN=CENTER>Access Details:<BR>$SystemName</H1>\n";
	unless ($EndDate eq "0000 00 00 00 00 00") {
		print REPORT "<P ALIGN=CENTER><STRONG>(Accesses Through ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$EndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year)</STRONG></P>\n";
	}
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P><HR>\n";
	print REPORT "<P>This report keeps track of &quot;user sessions,&quot; ";
	print REPORT "showing the paths taken through the site by its visitors. ";
	print REPORT "It also provides an estimate of how many unique visitors ";
	print REPORT "the site has had and how long they've stayed. ";
	print REPORT "Please note, however, that precise tracking of ";
	print REPORT "the number of visitors is impossible; the information ";
	print REPORT "in this report is at best a reasonably close approximation ";
	print REPORT "based on the information in the server access log.\n";
	print REPORT "</P><HR>\n";
	unless ($TodayPages < 1 ) {
		$TodayOutside=$TodayPages-$TodayLocal;
		$LocalPercent=int(($TodayLocal/$TodayPages)*1000+.5)/10;
		$OutsidePercent=int(($TodayOutside/$TodayPages)*1000+.5)/10;
		$TodayHosts=keys(%TodayHosts);
		$TodayKB=int(($TodayBytes/1024)+.5);
		$AveragePages=sprintf("%3.1f",$TodayPages/$usersessions);
		@RevAccesses=reverse(@Accesses);
		undef @Accesses;
		foreach $entry (@RevAccesses) { 
			($hour,$minute,$second,$durminute,$dursecond,$remote,$page,$referer)=split(" ",$entry);
			$duration=$durminute.":".$dursecond;
			if (($duration eq "00:00") || ($duration =~ /-/)) {
				$duration="     ";
			}
			$timestring=$hour.":".$minute.":".$second;
			unless ($hostlist{$remote}) { $hostlist{$remote} = ""; }
			if ($referer ne "-") {
				$hostlist{$remote} .= "   <EM>".$referer."</EM>\n";
			}
			$hostlist{$remote} .= "      ".$timestring." -- ".$duration." -- ".$page."\n";
		}
		$averagesession=$sessionstime/$usersessions;
		$averageminute=int(($averagesession/60)+.5);
		if ($averageminute == 0) { $averagesession="less than a minute"; }
		elsif ($averageminute == 1) { $averagesession="1 minute"; }
		else { $averagesession=$averageminute." minutes"; }
	}
	print REPORT "<H2 ALIGN=CENTER>Detailed Access List</H2>\n";
	print REPORT "<!--DATESTAMP=\"$time\"-->\n";
	print REPORT "<H3 ALIGN=CENTER>Log Analyzed on $CurrDate</H3>\n";
	unless ($FileEndDate eq "0000 00 00 00 00 00") {
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$FileStartDate);
		print REPORT "<P ALIGN=CENTER>$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year to ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$FileEndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year</P>\n";
	}
	if ($TodayPages < 1 ) {
		print REPORT "<P ALIGN=CENTER><EM>No successful accesses.</EM></P>\n";
	} else {
		print REPORT "<P><EM>A total of <STRONG>",&commas($TodayPages),"</STRONG> pages were accessed ";
		print REPORT "by <STRONG>",&commas($TodayHosts),"</STRONG> unique hosts. ";
		if ($OrgDomain) {
			print REPORT "Of those pages, <STRONG>",&commas($TodayLocal)," ";
			printf REPORT ("(%.4g%%)",$LocalPercent);
			print REPORT "</STRONG> were ";
			if ($OrgName) {
				print REPORT "viewed by $OrgName, ";
			} else {
				print REPORT "viewed internally, ";
			}
			print REPORT "and <STRONG>",&commas($TodayOutside)," ";
			printf REPORT ("(%.4g%%)",$OutsidePercent);
			print REPORT "</STRONG> by outside domains. ";
		}
		print REPORT "There were approximately <STRONG>";
		print REPORT &commas($usersessions),"</STRONG> distinct visitors; ";
		print REPORT "the typical visitor seems to have spent about <STRONG>";
		print REPORT "$averagesession</STRONG> visiting the site and to have ";
		print REPORT "viewed some <STRONG>$AveragePages</STRONG> pages. ";
		print REPORT "There were a total of <STRONG>";
		print REPORT &commas($TodayHits),"</STRONG> hits and ";
		print REPORT "<STRONG>",&commas($TodayErrors),"</STRONG> errors ";
		print REPORT "related to $SystemName, consisting of <STRONG>";
		print REPORT &commas($TodayKB),"</STRONG> kilobytes ";
		print REPORT "of information.</EM></P>\n";
		@hosts=sort byDomain (keys %hostlist);
		$prevTD="###";
		print REPORT "<P><PRE>";
		foreach $host (@hosts) {
			$TopDomain=&GetTopDomain($host);
			if ($TopDomain ne $prevTD) {
				$prevTD = $TopDomain;
				print REPORT "\n<STRONG>$CountryCode{$TopDomain}:";
				print REPORT "</STRONG>\n";
			}
			$entry=$hostlist{$host};
			print REPORT "$host\n";
			print REPORT "$entry";
		}
		print REPORT "</PRE></P>\n";
	}
	foreach $line (@lines) {
		print REPORT $line;
	}
	print REPORT "<!--DATESTAMP=\"000000000\"-->\n";
	print REPORT "</P><HR>\n";
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P>\n";
	print REPORT "<P ALIGN=CENTER>";
	print REPORT "<SMALL>This report was generated by ";
	print REPORT "<STRONG><A HREF=";
	print REPORT "\"http://awsd.com/scripts/weblog/\">";
	print REPORT "WebLog $version</A></STRONG></SMALL></P>\n";
	print REPORT "</BODY></HTML>\n";
	close (REPORT);
}

sub byDomain {
	local($aHost) = "";
	local($bHost) = "";
	local(@aTemp,@bTemp)=();
	if ($a =~ /[^0-9].*\.[^0-9].*/) {
		@aTemp=reverse split(/\./, $a);
		foreach (@aTemp) { $aHost .= $_ };
	} else { $aHost="zzzzzzz".$a; }
	if ($b =~ /[^0-9].*\.[^0-9].*/) {
		@bTemp=reverse split(/\./, $b);
		foreach (@bTemp) { $bHost .= $_ };
	} else { $bHost="zzzzzzz".$b; }
	return ($aHost cmp $bHost);
}

sub PrintRefsReport {
	if (-e "$FileDir/$RefsFile") {
		open (OLDLOG,"$FileDir/$RefsFile") || die "  Error opening file: $RefsFile\n";
		while (<OLDLOG>) {
			chop;
			if (m#^<P><DT><STRONG>(.*)</STRONG></DT>#o) {
				$target = &Simplify($1);
				next;
			}
			next if (! $target);
			if (m#^<DD><A HREF=\"([^"]*)\">.*</A> \(([\d,]+) reference#o) {
				$refurl = $1;
				$count = $2;
				$count =~ s/,//g;
				$url = &Simplify($refurl);
				if ($TargetCounter{"$target $url"}) { $TargetCounter{"$target $url"} += $count; }
				else { $TargetCounter{"$target $url"} = $count; }
			}
		}
		close (OLDLOG);
	}
	foreach $key (keys (%TargetCounter)) {
		($target,$referer)=split(/ /,$key,2);
		if ($TargetCounter{"$target/ $referer"} && $TargetCounter{"$target $referer"}) {
			$TargetCounter{$key}=-1;
		}
	}
	open (REPORT,">$FileDir/$RefsFile") || die "  Error opening file: $RefsFile\n";
	print REPORT "<HTML><HEAD><TITLE>Referring URLs Report: $SystemName</TITLE></HEAD>";
	print REPORT "<BODY BGCOLOR=\"#99ccff\" TEXT=\"#000000\">\n";
	print REPORT "<H1 ALIGN=CENTER>Referring URLs:<BR>$SystemName</H1>\n";
	unless ($EndDate eq "0000 00 00 00 00 00") {
		print REPORT "<P ALIGN=CENTER><STRONG>(Accesses Through ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$EndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year)</STRONG></P>\n";
	}
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P><HR>\n";
	print REPORT "<P>This report logs the URLs reported by browsers as ";
	print REPORT "the &quot;referers&quot; directing them to the various ";
	print REPORT "listed pages. (Please be aware that this information ";
	print REPORT "is far from perfect. Many browsers do not provide any ";
	print REPORT "information on the referring page; even those that do ";
	print REPORT "can at times provide false or misleading data. And the ";
	print REPORT "fact that a page is listed as the referer to a given ";
	print REPORT "page does <EM>not</EM> necessarily mean that it ";
	print REPORT "actually contains a link to that page.)\n";
	if ($RefsMinHits > 1) {
		print REPORT "<P>Only referring URLs appearing at least ";
		print REPORT "<STRONG>$RefsMinHits</STRONG> times ";
		print REPORT "in at least one of the log files analyzed ";
		print REPORT "are listed in the report below.\n";
	}
	print REPORT "</P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Web Pages and Referring URLs</H2>\n";
	print REPORT "<DL>\n";
	$LastWebPage = '';
	foreach $key (sort bytargetthenhits keys(%TargetCounter)) {
		unless ($TargetCounter{$key} < $RefsMinHits) {
			($target,$referer) = split(/ /,$key,2);
			if ("$target" ne "$LastWebPage") {
				print REPORT "<P><DT><STRONG>$target</STRONG></DT>\n";
			}
			print REPORT "<DD><A HREF=\"$referer\">$referer</A> ";
			print REPORT "(",&commas($TargetCounter{$key})," reference";
			if ($TargetCounter{$key} > 1) { print REPORT "s"; }
			print REPORT ")</DD>\n";
			$LastWebPage = $target;
		}
	}
	print REPORT "</P></DL><HR>\n";
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P>\n";
	print REPORT "<P ALIGN=CENTER>";
	print REPORT "<SMALL>This report was generated by ";
	print REPORT "<STRONG><A HREF=";
	print REPORT "\"http://awsd.com/scripts/weblog/\">";
	print REPORT "WebLog $version</A></STRONG></SMALL></P>\n";
	print REPORT "</BODY></HTML>\n";
	close (REPORT);
}

sub Simplify {
	$url = $_[0];
	$url =~ s/ //g;
	unless ($RefsStripWWW) {
		return $url;
	}
	if ($url =~ m#(^.+)//([\w|\.|-]+)/(.+)#o) {
		$url_prefix = $1;
		$url_domain = $2;
		$url_path = $3;
		$url_domain = "\L$url_domain";
		$url_domain =~ s/^www\.//i;
		return $url_prefix."//".$url_domain."/".$url_path;
	}
	elsif ($url =~ m#(^.+)//([\w|\.|-]+)#o) {
		$url_prefix = $1;
		$url_domain = $2;
		$url_domain = "\L$url_domain";
		$url_domain =~ s/^www\.//i;
		return $url_prefix."//".$url_domain;
	}
	else {
		return $url;
	}
}

sub bytargetthenhits {
	($targeta)=($a=~m#^(.+)\s#o);
	($targetb)=($b=~m#^(.+)\s#o);
	$inequality=($targeta cmp $targetb);
	if ($inequality) {
		$inequality;
	} else {
		$TargetCounter{$b}<=>$TargetCounter{$a};
	}
}

sub PrintKeywordsReport {
	if (-e "$FileDir/$KeywordsFile") {
		open (OLDLOG,"$FileDir/$KeywordsFile") || die "  Error opening file: $KeywordsFile\n";
		while (<OLDLOG>) {
			chop;
			if (m#<P><STRONG>(.*)</STRONG>#o) {
				$SearchEngine = $1;
			}
			if (m#\s*([\d,]+)     (.*)$#o ) {
				$count = $1;
				$phrase = $2;
				$count =~ s/,//g;
				if ($SearchEngine eq "AltaVista:") {
					if ($altavista{$phrase}) { $altavista{$phrase} += $count; }
					else { $altavista{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "AOL Netfind:") {
					if ($netfind{$phrase}) { $netfind{$phrase} += $count; }
					else { $netfind{$phrase} = $count; }
				}
				elsif ($SearchEngine =~ /Excite/) {
					if ($excite{$phrase}) { $excite{$phrase} += $count; }
					else { $excite{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "HotBot:") {
					if ($hotbot{$phrase}) { $hotbot{$phrase} += $count; }
					else { $hotbot{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "Infoseek:") {
					if ($infoseek{$phrase}) { $infoseek{$phrase} += $count; }
					else { $infoseek{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "Lycos:") {
					if ($lycos{$phrase}) { $lycos{$phrase} += $count; }
					else { $lycos{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "Snap:") {
					if ($snap{$phrase}) { $snap{$phrase} += $count; }
					else { $snap{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "WebCrawler:") {
					if ($webcrawler{$phrase}) { $webcrawler{$phrase} += $count; }
					else { $webcrawler{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "Yahoo:") {
					if ($yahoo{$phrase}) { $yahoo{$phrase} += $count; }
					else { $yahoo{$phrase} = $count; }
				}
				elsif ($SearchEngine eq "Other Search Engines:") {
					if ($othersearch{$phrase}) { $othersearch{$phrase} += $count; }
					else { $othersearch{$phrase} = $count; }
				}
			}
		}
		close (OLDLOG);
	}
	open (REPORT,">$FileDir/$KeywordsFile") || die "  Error opening file: $KeywordsFile\n";
	print REPORT "<HTML><HEAD><TITLE>Keywords Report: $SystemName</TITLE></HEAD>";
	print REPORT "<BODY BGCOLOR=\"#99ccff\" TEXT=\"#000000\">\n";
	print REPORT "<H1 ALIGN=CENTER>Referring Keywords:<BR>$SystemName</H1>\n";
	unless ($EndDate eq "0000 00 00 00 00 00") {
		print REPORT "<P ALIGN=CENTER><STRONG>(Accesses Through ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$EndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year)</STRONG></P>\n";
	}
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P><HR>\n";
	print REPORT "<P>This report logs the keywords used by visitors to find ";
	print REPORT "this site in the various Internet search engines and directories. ";
	print REPORT "The major search engines are each listed individually. ";
	print REPORT "(Note that not all search engines provide search keywords ";
	print REPORT "in their URLs, and so some are not listed here.)\n";
	print REPORT "</P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Referring Keywords</H2>\n";
	if (%altavista) {
		print REPORT "<P><STRONG>AltaVista:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort AltaVistaByHits keys(%altavista)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($altavista{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%netfind) {
		print REPORT "<P><STRONG>AOL Netfind:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort NetfindByHits keys(%netfind)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($netfind{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%excite) {
		print REPORT "<P><STRONG>Excite:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort ExciteByHits keys(%excite)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($excite{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%hotbot) {
		print REPORT "<P><STRONG>HotBot:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort HotBotByHits keys(%hotbot)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($hotbot{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%infoseek) {
		print REPORT "<P><STRONG>Infoseek:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort InfoseekByHits keys(%infoseek)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($infoseek{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%lycos) {
		print REPORT "<P><STRONG>Lycos:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort LycosByHits keys(%lycos)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($lycos{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%snap) {
		print REPORT "<P><STRONG>Snap:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort SnapByHits keys(%snap)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($snap{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%webcrawler) {
		print REPORT "<P><STRONG>WebCrawler:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort WebCrawlerByHits keys(%webcrawler)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($webcrawler{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%yahoo) {
		print REPORT "<P><STRONG>Yahoo:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort YahooByHits keys(%yahoo)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($yahoo{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	if (%othersearch) {
		print REPORT "<P><STRONG>Other Search Engines:</STRONG>\n";
		print REPORT "<P><PRE>";
		foreach $phrase (sort OtherByHits keys(%othersearch)) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($othersearch{$phrase});
			print REPORT "     $phrase\n";
		}
		print REPORT "</PRE></P>\n";
	}
	print REPORT "<HR>\n";
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($AgentsFile) {
		print REPORT " <STRONG><A HREF=\"$AgentsFile\">Agents/Platforms Report</A></STRONG> |";
	}
	print REPORT "</P>\n";
	print REPORT "<P ALIGN=CENTER>";
	print REPORT "<SMALL>This report was generated by ";
	print REPORT "<STRONG><A HREF=";
	print REPORT "\"http://awsd.com/scripts/weblog/\">";
	print REPORT "WebLog $version</A></STRONG></SMALL></P>\n";
	print REPORT "</BODY></HTML>\n";
	close (REPORT);
}

sub AltaVistaByHits {
	$ahits=$altavista{$a};
	$bhits=$altavista{$b};
	$bhits<=>$ahits;
}

sub NetfindByHits {
	$ahits=$netfind{$a};
	$bhits=$netfind{$b};
	$bhits<=>$ahits;
}

sub ExciteByHits {
	$ahits=$excite{$a};
	$bhits=$excite{$b};
	$bhits<=>$ahits;
}

sub HotBotByHits {
	$ahits=$hotbot{$a};
	$bhits=$hotbot{$b};
	$bhits<=>$ahits;
}

sub InfoseekByHits {
	$ahits=$infoseek{$a};
	$bhits=$infoseek{$b};
	$bhits<=>$ahits;
}

sub LycosByHits {
	$ahits=$lycos{$a};
	$bhits=$lycos{$b};
	$bhits<=>$ahits;
}

sub SnapByHits {
	$ahits=$snap{$a};
	$bhits=$snap{$b};
	$bhits<=>$ahits;
}

sub WebCrawlerByHits {
	$ahits=$webcrawler{$a};
	$bhits=$webcrawler{$b};
	$bhits<=>$ahits;
}

sub YahooByHits {
	$ahits=$yahoo{$a};
	$bhits=$yahoo{$b};
	$bhits<=>$ahits;
}

sub OtherByHits {
	$ahits=$othersearch{$a};
	$bhits=$othersearch{$b};
	$bhits<=>$ahits;
}

sub PrintAgentsReport {
	if (-e "$FileDir/$AgentsFile") {
		open (OLDLOG,"$FileDir/$AgentsFile") || die "  Error opening file: $AgentsFile\n";
		while (<OLDLOG>) {
			chop;
			if (m#\s*([\d,]+)                 (.*)$#o ) {
				$count = $1;
				$agent = $2;
				$count =~ s/,//g;
				if ($agentcounter{$agent}) { $agentcounter{$agent} += $count; }
				else { $agentcounter{$agent} = $count; }
				$refscounter += $count;
			}
		}
		close (OLDLOG);
	}
	foreach $agent (keys %agentcounter) {
		&Identify_Agent;
		&Identify_Platform;
		unless ($agentreport{$longagent}) { $agentreport{$longagent} = 0; }
		unless ($platformreport{$longplatform}) { $platformreport{$longplatform} = 0; }
		unless ($combinedreport{"$shortagent ($shortplatform)"}) { $combinedreport{"$shortagent ($shortplatform)"} = 0; }
		$agentreport{$longagent} += $agentcounter{$agent};
		$platformreport{$longplatform} += $agentcounter{$agent};
		$combinedreport{"$shortagent ($shortplatform)"} += $agentcounter{$agent};
	}
	open (REPORT,">$FileDir/$AgentsFile") || die "  Error opening file: $AgentsFile\n";
	print REPORT "<HTML><HEAD><TITLE>Agents/Platforms Report: $SystemName</TITLE></HEAD>";
	print REPORT "<BODY BGCOLOR=\"#99ccff\" TEXT=\"#000000\">\n";
	print REPORT "<H1 ALIGN=CENTER>Agents/Platforms:<BR>$SystemName</H1>\n";
	unless ($EndDate eq "0000 00 00 00 00 00") {
		print REPORT "<P ALIGN=CENTER><STRONG>(Accesses Through ";
		($Year,$Month,$Day,$Hour,$Minute,$Second)=
		  split(/ /,$EndDate);
		print REPORT "$Hour:$Minute:$Second $Day ";
		print REPORT "$NumberToMonth{$Month} $Year)</STRONG></P>\n";
	}
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	print REPORT "</P><HR>\n";
	print REPORT "<P>These reports list the agents (browsers) and ";
	print REPORT "platforms (operating systems) utilized by visitors to ";
	print REPORT "these pages. (Browsers which &quot;spoof&quot; other ";
	print REPORT "browsers -- such as MSIE or newer versions of AOL's ";
	print REPORT "browser claiming to be Netscape, or WebTV claiming to ";
	print REPORT "be MSIE claiming to be Netscape -- are identified as ";
	print REPORT "what they really are, rather than as what they claim to ";
	print REPORT "be.)\n";
	print REPORT "<P>The first report details the agents utilized; the ";
	print REPORT "second, the platforms. The third report combines the ";
	print REPORT "data from the first two. The fourth report is a ";
	print REPORT "complete and essentially unprocessed listing ";
	print REPORT "of the raw data from the agent log.\n";
	print REPORT "<P>A total of <STRONG>",&commas($refscounter),"</STRONG> ";
	print REPORT "&quot;hits&quot; have thus far been recorded and ";
	print REPORT "analyzed.</P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Summary List<BR>(by Agent)</H2>\n";
	print REPORT "<P><PRE>        Hits     Percent     Agent\n\n";
	foreach $key (sort AgentByHits keys(%agentreport)) {
		$percentage=(100*$agentreport{$key}/$refscounter)+0.0051;
		if ($percentage < 10) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($agentreport{$key});
			$percentage=~s/(....).*/$1/;
			print REPORT "       ${percentage}%     ";
			print REPORT $key,"\n";
		}
		else {
			print REPORT "  ";
			printf REPORT "%10s",&commas($agentreport{$key});
			$percentage=~s/(.....).*/$1/;
			print REPORT "      ${percentage}%     ";
			print REPORT $key,"\n";
		}
	}
	print REPORT "</PRE></P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Summary List<BR>(by Platform)</H2>\n";
	print REPORT "<P><PRE>        Hits     Percent     Platform\n\n";
	foreach $key (sort PlatformByHits keys(%platformreport)) {
		$percentage=(100*$platformreport{$key}/$refscounter)+0.0051;
		if ($percentage < 10) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($platformreport{$key});
			$percentage=~s/(....).*/$1/;
			print REPORT "       ${percentage}%     ";
			print REPORT $key,"\n";
		}
		else {
			print REPORT "  ";
			printf REPORT "%10s",&commas($platformreport{$key});
			$percentage=~s/(.....).*/$1/;
			print REPORT "      ${percentage}%     ";
			print REPORT $key,"\n";
		}
	}
	print REPORT "</PRE></P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Summary List<BR>(by Agent and Platform)</H2>\n";
	print REPORT "<P><PRE>        Hits     Percent     Agent (Platform)\n\n";
	foreach $key (sort CombinedByHits keys(%combinedreport)) {
		$percentage=(100*$combinedreport{$key}/$refscounter)+0.0051;
		if ($percentage < 10) {
			print REPORT "  ";
			printf REPORT "%10s",&commas($combinedreport{$key});
			$percentage=~s/(....).*/$1/;
			print REPORT "       ${percentage}%     ";
			if ($key =~ "WebTV") { print REPORT "WebTV\n"; }
			else { print REPORT $key,"\n"; }
		}
		else {
			print REPORT "  ";
			printf REPORT "%10s",&commas($combinedreport{$key});
			$percentage=~s/(.....).*/$1/;
			print REPORT "      ${percentage}%     ";
			if ($key =~ "WebTV") { print REPORT "WebTV\n"; }
			else { print REPORT $key,"\n"; }
		}
	}
	print REPORT "</PRE></P><HR>\n";
	print REPORT "<H2 ALIGN=CENTER>Full List of Agents</H2>\n";
	print REPORT "<P><PRE>        Hits                 Agent\n\n";
	foreach $key (sort keys(%agentcounter)) {
		print REPORT "  ";
		printf REPORT "%10s",&commas($agentcounter{$key});
		print REPORT "                 $key\n";
	}
	print REPORT "</PRE></P><HR>\n";
	print REPORT "<P ALIGN=CENTER>| <STRONG><A HREF=\"$ReportFile\">Access Log</A></STRONG> |";
	if ($DetailsFile) {
		print REPORT " <STRONG><A HREF=\"$DetailsFile\">Access Details Report</A></STRONG> |";
	}
	if ($RefsFile) {
		print REPORT " <STRONG><A HREF=\"$RefsFile\">Referring URLs Report</A></STRONG> |";
	}
	if ($KeywordsFile) {
		print REPORT " <STRONG><A HREF=\"$KeywordsFile\">Keywords Report</A></STRONG> |";
	}
	print REPORT "</P>\n";
	print REPORT "<P ALIGN=CENTER>";
	print REPORT "<SMALL>This report was generated by ";
	print REPORT "<STRONG><A HREF=";
	print REPORT "\"http://awsd.com/scripts/weblog/\">";
	print REPORT "WebLog $version</A></STRONG></SMALL></P>\n";
	print REPORT "</BODY></HTML>\n";
	close (REPORT);
}

sub Identify_Agent {
	if ($agent =~ m#Mozilla/(\d)#oi) {
		if ($agent =~ m#compatible#oi) {
			if ($agent =~ m#WebTV#oi) {
				$longagent = "WebTV";
				$shortagent = "WebTV";
			}
			elsif ($agent =~ m#MSIE (\d)#oi) {
				$longagent = "MSIE v$1.X";
				$shortagent = "MSIE";
			}
			elsif ($agent =~ m#MSIE#oi) {
				$longagent = "MSIE";
				$shortagent = "MSIE";
			}
			elsif ($agent =~ m#AOL (\d)#oi) {
				$longagent = "AOL's Browser v$1.X";
				$shortagent = "AOL's Browser";
			}
			elsif ($agent =~ m#AOL-IWENG (\d)#oi) {
				$longagent = "AOL's Browser v$1.X";
				$shortagent = "AOL's Browser";
			}
			elsif ($agent =~ m#Opera/(\d)#oi) {
				$longagent = "Opera v$1.X";
				$shortagent = "Opera";
			}
			else {
				$longagent = "Other Agents";
				$shortagent = "Other Agents";
			}
		}
		else {
			$longagent = "Netscape v$1.X";
			$shortagent = "Netscape";
		}
	}
	elsif ($agent =~ m#Mozilla#oi) {
		$longagent = "Netscape";
		$shortagent = "Netscape";
	}
	elsif ($agent =~ m#Microsoft Internet Explorer/(\d)#oi) {
		$longagent = "MSIE v$1.X";
		$shortagent = "MSIE";
	}
	elsif ($agent =~ m#IWENG/(\d)#oi) {
		$longagent = "AOL's Browser v$1.X";
		$shortagent = "AOL's Browser";
	}
	elsif ($agent =~ m#aolbrowser/(\d)#oi) {
		$longagent = "AOL's Browser v$1.X";
		$shortagent = "AOL's Browser";
	}
	elsif ($agent =~ m#Lynx#oi) {
		$longagent = "Lynx";
		$shortagent = "Lynx";
	}
	elsif ($agent =~ m#QuarterDeck#oi) {
		$longagent = "QuarterDeck Mosaic";
		$shortagent = "QuarterDeck Mosaic";
	}
	elsif ($agent =~ m#SPRY#oi) {
		$longagent = "Compuserve's SPRY Mosaic";
		$shortagent = "Compuserve's SPRY Mosaic";
	}
	elsif ($agent =~ m#Enhanced_Mosaic#oi) {
		$longagent = "NCSA Mosaic (Enhanced)";
		$shortagent = "NCSA Mosaic (Enhanced)";
	}
	elsif ($agent =~ m#Mosaic#oi) {
		$longagent = "NCSA Mosaic";
		$shortagent = "NCSA Mosaic";
	}
	elsif ($agent =~ m#Crescent#oi) {
		$longagent = "Crescent Internet ToolPak";
		$shortagent = "Crescent Internet ToolPak";
	}
	elsif ($agent =~ m#IBM WebExplorer#oi) {
		$longagent = "IBM WebExplorer";
		$shortagent = "IBM WebExplorer";
	}
	elsif ($agent =~ m#PRODIGY#oi) {
		$longagent = "Prodigy's Browser";
		$shortagent = "Prodigy's Browser";
	}
	elsif ($agent =~ m#Teleport Pro#oi) {
		$longagent = "Teleport Pro";
		$shortagent = "Teleport Pro";
	}
	elsif ($agent =~ m#WebVCR#oi) {
		$longagent = "WebVCR";
		$shortagent = "WebVCR";
	}
	elsif ($agent =~ m#analyzer#oi
	  || $agent =~ m#bot#oi || $agent =~ m#check#oi
	  || $agent =~ m#crawl#oi || $agent =~ m#InfoSeek#oi
	  || $agent =~ m#roamer#oi || $agent =~ m#rover#oi
	  || $agent =~ m#Scooter#oi || $agent =~ m#siphon#oi
	  || $agent =~ m#Slurp#oi || $agent =~ m#spider#oi
	  || $agent =~ m#sweep#oi || $agent =~ m#URL#oi
	  || $agent =~ m#validator#oi || $agent =~ m#walker#oi) {
		$longagent = "Spiders/Robots";
		$shortagent = "Spiders/Robots";
	}
	else {
		$longagent = "Other Agents";
		$shortagent = "Other Agents";
	}
}

sub Identify_Platform {
	if ($agent =~ m#win#oi) {
		$shortplatform = "Windows";
	}
	if ($agent =~ m#win95#oi) {
		$longplatform = "Windows 95";
	}
	elsif ($agent =~ m#winNT#oi) {
		$longplatform = "Windows NT";
	}
	elsif ($agent =~ m#win16#oi) {
		$longplatform = "Windows 3.1/95 (16-bit)";
	}
	elsif ($agent =~ m#win32#oi) {
		$longplatform = "Windows 95/NT (32-bit)";
	}
	elsif ($agent =~ m#winweb#oi) {
		$longplatform = "Windows 3.1/95 (16-bit)";
	}
	elsif ($agent =~ m#Windows 95#oi) {
		$longplatform = "Windows 95";
	}
	elsif ($agent =~ m#Windows NT#oi) {
		$longplatform = "Windows NT";
	}
	elsif ($agent =~ m#Windows 3.1#oi) {
		$longplatform = "Windows 3.1";
	}
	elsif ($agent =~ m#Windows#oi) {
		if ($agent =~ m#32bit#oi) {
			$longplatform = "Windows 95/NT (32-bit)";
		}
		else {
			$longplatform = "Windows 3.1/95 (16-bit)";
		}
	}
	elsif ($agent =~ m#Window#oi) {
		$shortplatform = "X Windows";
		$longplatform = "X Windows";
	}
	elsif ($agent =~ m#Mac#oi) {
		$shortplatform = "Macintosh";
		if ($agent =~ m#PPC#oi) {
			$longplatform = "Macintosh (PowerPC)";
		}
		elsif ($agent =~ m#PowerPC#oi) {
			$longplatform = "Macintosh (PowerPC)";
		}
		else {
			$longplatform = "Macintosh (68K)";
		}
	}
	elsif ($agent =~ m#Amiga#oi) {
		$shortplatform = "Amiga";
		$longplatform = "Amiga";
	}
	elsif ($agent =~ m#OS/2#oi) {
		$shortplatform = "OS/2";
		$longplatform = "OS/2";
	}
	elsif ($agent =~ m#X11#oi) {
		$shortplatform = "UNIX";
		if ($agent =~ m#HP-UX#oi) {
			$longplatform = "UNIX (HP-UX)";
		}
		elsif ($agent =~ m#Linux#oi) {
			$longplatform = "UNIX (Linux)";
		}
		elsif ($agent =~ m#SunOS#oi) {
			$longplatform = "UNIX (SunOS)";
		}
		elsif ($agent =~ m#FreeBSD#oi) {
			$longplatform = "UNIX (FreeBSD)";
		}
		elsif ($agent =~ m#NetBSD#oi) {
			$longplatform = "UNIX (NetBSD)";
		}
		elsif ($agent =~ m#BSD#oi) {
			$longplatform = "UNIX (BSD)";
		}
		elsif ($agent =~ m#AIX#oi) {
			$longplatform = "UNIX (AIX)";
		}
		elsif ($agent =~ m#OSF1#oi) {
			$longplatform = "UNIX (OSF1)";
		}
		elsif ($agent =~ m#IRIX#oi) {
			$longplatform = "UNIX (IRIX)";
		}
		else {
			$longplatform = "UNIX (Other/Unspecified)";
		}
	}
	elsif ($agent =~ m#IWENG#oi) {
		$shortplatform = "Windows";
		$longplatform = "Windows 3.1/95 (16-bit)";
	}
	elsif ($agent =~ m#Lynx#oi) {
		$shortplatform = "UNIX";
		$longplatform = "UNIX (Other/Unspecified)";
	}
	elsif ($agent =~ m#WebTV#oi) {
		$shortplatform = "WebTV";
		$longplatform = "WebTV";
	}
	elsif ($agent =~ m#WebVCR#oi) {
		$shortplatform = "WebVCR";
		$longplatform = "WebVCR";
	}
	else {
		$shortplatform = "Unknown Platform";
		$longplatform = "Unknown Platform";
	}
}

sub AgentByHits {
	$ahits=$agentreport{$a};
	$bhits=$agentreport{$b};
	$bhits<=>$ahits;
}

sub PlatformByHits {
	$ahits=$platformreport{$a};
	$bhits=$platformreport{$b};
	$bhits<=>$ahits;
}

sub CombinedByHits {
	$ahits=$combinedreport{$a};
	$bhits=$combinedreport{$b};
	$bhits<=>$ahits;
}

sub date_to_count {
	($perp_mon,$perp_day,$perp_year) = @_;
	%day_counts =
	  (1,0,2,31,3,59,4,90,5,120,6,151,7,181,
	  8,212,9,243,10,273,11,304,12,334);
	%dates =
	  (0,'Thu',1,'Fri',2,'Sat',3,'Sun',4,'Mon',5,'Tue',6,'Wed');
	$perp_days = (($perp_year-93)*365)+(int(($perp_year-93)/4));
	$perp_mons = (($perp_year-93)*12);
	$perp_days = $perp_days + $day_counts{$perp_mon};
	$perp_mons = $perp_mons + $perp_mon;
	if ((int(($perp_year-92)/4) eq (($perp_year-92)/4)) && ($perp_mon>2)) {
		$perp_days++;
	}
	$perp_days = $perp_days + $perp_day;
	$perp_date = $perp_days-(int($perp_days/7)*7);
	$perp_date = $dates{$perp_date};
}

sub count_to_mon {
	local($perp_mons) = @_;
	$perp_year = 93+(int(($perp_mons-1)/12));
	$perp_mon = $perp_mons-(int(($perp_mons-1)/12)*12);
}

sub count_to_date {
	local($perp_days) = @_;
	%day_counts =
	  (1,0,2,31,3,59,4,90,5,120,6,151,
	  7,181,8,212,9,243,10,273,11,304,12,334);
	$perp_year = (int(($perp_days-1)/1461))*4;
	$perp_days = $perp_days-(int(($perp_days-1)/1461)*1461);
	if ($perp_days == 1461) {
		$perp_year = 93+$perp_year+3;
		$perp_days = $perp_days-1095;
	}
	else {
		$perp_year = 93+$perp_year+(int(($perp_days-1)/365));
		$perp_days = $perp_days-(int(($perp_days-1)/365)*365);
	}
		foreach $key (sort {$a <=> $b} keys %day_counts) {
		$perp_count = $day_counts{$key};
		if ((int(($perp_year-92)/4) eq (($perp_year-92)/4)) && ($key>2)) {
			$perp_count++;
		}
		if ($perp_days > $perp_count) {
			$perp_mon = $key;
			$perp_subtract = $perp_count;
		}
	}
	$perp_day = $perp_days-$perp_subtract;
}

sub SetupCountryCodes {
	%CountryCodes = (
	  'AD','Andorra',
	  'AE','United Arab Emirates',
	  'AF','Afghanistan',
	  'AG','Antigua and Barbuda',
	  'AI','Anguilla',
	  'AL','Albania',
	  'AM','Armenia',
	  'AN','Netherlands Antilles',
	  'AO','Angola',
	  'AQ','Antarctica',
	  'AR','Argentina',
	  'AS','American Samoa',
	  'AT','Austria',
	  'AU','Australia',
	  'AW','Aruba',
	  'AZ','Azerbaijan',
	  'BA','Bosnia and Herzegovina',
	  'BB','Barbados',
	  'BD','Bangladesh',
	  'BE','Belgium',
	  'BF','Burkina Faso',
	  'BG','Bulgaria',
	  'BH','Bahrain',
	  'BI','Burundi',
	  'BJ','Benin',
	  'BM','Bermuda',
	  'BN','Brunei Darussalam',
	  'BO','Bolivia',
	  'BR','Brazil',
	  'BS','Bahamas',
	  'BT','Bhutan',
	  'BV','Bouvet Island',
	  'BW','Botswana',
	  'BY','Belarus',
	  'BZ','Belize',
	  'CA','Canada',
	  'CC','Cocos (Keeling) Islands',
	  'CF','Central African Republic',
	  'CG','Congo',
	  'CH','Switzerland',
	  'CI','Cote DIvoire (Ivory Coast)',
	  'CK','Cook Islands',
	  'CL','Chile',
	  'CM','Cameroon',
	  'CN','China',
	  'CO','Colombia',
	  'CR','Costa Rica',
	  'CS','Czechoslovakia (Former)',
	  'CU','Cuba',
	  'CV','Cape Verde',
	  'CX','Christmas Island',
	  'CY','Cyprus',
	  'CZ','Czech Republic',
	  'DE','Germany',
	  'DJ','Djibouti',
	  'DK','Denmark',
	  'DM','Dominica',
	  'DO','Dominican Republic',
	  'DZ','Algeria',
	  'EC','Ecuador',
	  'EE','Estonia',
	  'EG','Egypt',
	  'EH','Western Sahara',
	  'ER','Eritrea',
	  'ES','Spain',
	  'ET','Ethiopia',
	  'FI','Finland',
	  'FJ','Fiji',
	  'FK','Falkland Islands (Malvinas)',
	  'FM','Micronesia',
	  'FO','Faroe Islands',
	  'FR','France',
	  'FX','France (Metropolitan)',
	  'GA','Gabon',
	  'GB','Great Britain (UK)',
	  'GD','Grenada',
	  'GE','Georgia',
	  'GF','French Guiana',
	  'GH','Ghana',
	  'GI','Gibraltar',
	  'GL','Greenland',
	  'GM','Gambia',
	  'GN','Guinea',
	  'GP','Guadeloupe',
	  'GQ','Equatorial Guinea',
	  'GR','Greece',
	  'GS','S. Georgia and S. Sandwich Islands',
	  'GT','Guatemala',
	  'GU','Guam',
	  'GW','Guinea-Bissau',
	  'GY','Guyana',
	  'HK','Hong Kong',
	  'HM','Heard and McDonald Islands',
	  'HN','Honduras',
	  'HR','Croatia (Hrvatska)',
	  'HT','Haiti',
	  'HU','Hungary',
	  'ID','Indonesia',
	  'IE','Ireland',
	  'IL','Israel',
	  'IN','India',
	  'IO','British Indian Ocean Territory',
	  'IQ','Iraq',
	  'IR','Iran',
	  'IS','Iceland',
	  'IT','Italy',
	  'JM','Jamaica',
	  'JO','Jordan',
	  'JP','Japan',
	  'KE','Kenya',
	  'KG','Kyrgyzstan',
	  'KH','Cambodia',
	  'KI','Kiribati',
	  'KM','Comoros',
	  'KN','Saint Kitts and Nevis',
	  'KP','North Korea',
	  'KR','South Korea',
	  'KW','Kuwait',
	  'KY','Cayman Islands',
	  'KZ','Kazakhstan',
	  'LA','Laos',
	  'LB','Lebanon',
	  'LC','Saint Lucia',
	  'LI','Liechtenstein',
	  'LK','Sri Lanka',
	  'LR','Liberia',
	  'LS','Lesotho',
	  'LT','Lithuania',
	  'LU','Luxembourg',
	  'LV','Latvia',
	  'LY','Libya',
	  'MA','Morocco',
	  'MC','Monaco',
	  'MD','Moldova',
	  'MG','Madagascar',
	  'MH','Marshall Islands',
	  'MK','Macedonia',
	  'ML','Mali',
	  'MM','Myanmar',
	  'MN','Mongolia',
	  'MO','Macau',
	  'MP','Northern Mariana Islands',
	  'MQ','Martinique',
	  'MR','Mauritania',
	  'MS','Montserrat',
	  'MT','Malta',
	  'MU','Mauritius',
	  'MV','Maldives',
	  'MW','Malawi',
	  'MX','Mexico',
	  'MY','Malaysia',
	  'MZ','Mozambique',
	  'NA','Namibia',
	  'NC','New Caledonia',
	  'NE','Niger',
	  'NF','Norfolk Island',
	  'NG','Nigeria',
	  'NI','Nicaragua',
	  'NL','Netherlands',
	  'NO','Norway',
	  'NP','Nepal',
	  'NR','Nauru',
	  'NT','Neutral Zone',
	  'NU','Niue',
	  'NZ','New Zealand (Aotearoa)',
	  'OM','Oman',
	  'PA','Panama',
	  'PE','Peru',
	  'PF','French Polynesia',
	  'PG','Papua New Guinea',
	  'PH','Philippines',
	  'PK','Pakistan',
	  'PL','Poland',
	  'PM','St. Pierre and Miquelon',
	  'PN','Pitcairn',
	  'PR','Puerto Rico',
	  'PT','Portugal',
	  'PW','Palau',
	  'PY','Paraguay',
	  'QA','Qatar',
	  'RE','Reunion',
	  'RO','Romania',
	  'RU','Russian Federation',
	  'RW','Rwanda',
	  'SA','Saudi Arabia',
	  'Sb','Solomon Islands',
	  'SC','Seychelles',
	  'SD','Sudan',
	  'SE','Sweden',
	  'SG','Singapore',
	  'SH','St. Helena',
	  'SI','Slovenia',
	  'SJ','Svalbard and Jan Mayen Islands',
	  'SK','Slovak Republic',
	  'SL','Sierra Leone',
	  'SM','San Marino',
	  'SN','Senegal',
	  'SO','Somalia',
	  'SR','Suriname',
	  'ST','Sao Tome and Principe',
	  'SU','USSR (Former)',
	  'SV','El Salvador',
	  'SY','Syria',
	  'SZ','Swaziland',
	  'TC','Turks and Caicos Islands',
	  'TD','Chad',
	  'TF','French Southern Territories',
	  'TG','Togo',
	  'TH','Thailand',
	  'TJ','Tajikistan',
	  'TK','Tokelau',
	  'TM','Turkmenistan',
	  'TN','Tunisia',
	  'TO','Tonga',
	  'TP','East Timor',
	  'TR','Turkey',
	  'TT','Trinidad and Tobago',
	  'TV','Tuvalu',
	  'TW','Taiwan',
	  'TZ','Tanzania',
	  'UA','Ukraine',
	  'UG','Uganda',
	  'UK','United Kingdom',
	  'UM','US Minor Outlying Islands',
	  'US','United States',
	  'UY','Uruguay',
	  'UZ','Uzbekistan',
	  'VA','Vatican City State (Holy See)',
	  'VC','Saint Vincent and the Grenadines',
	  'VE','Venezuela',
	  'VG','Virgin Islands (British)',
	  'VI','Virgin Islands (US)',
	  'VN','Viet Nam',
	  'VU','Vanuatu',
	  'WF','Wallis and Futuna Islands',
	  'WS','Samoa',
	  'YE','Yemen',
	  'YT','Mayotte',
	  'YU','Yugoslavia',
	  'ZA','South Africa',
	  'ZM','Zambia',
	  'ZR','Zaire',
	  'ZW','Zimbabwe',
	  'COM','US Commercial',
	  'EDU','US Educational',
	  'GOV','US Government',
	  'INT','International',
	  'MIL','US Military',
	  'NET','Network',
	  'ORG','Non-Profit Organization',
	  'ARPA','Old-Style Arpanet',
	  'NATO','NATO Field'
	  );
	while (($Code,$Description) = each %CountryCodes) {
		$Code=~tr/A-Z/a-z/;
		$CountryCode{$Code}=$Description;
	}
	$CountryCode{"xxx"}="Unresolved Domain";
}

1;

