#!/usr/bin/perl -w ############################################################################# # Pagestats -- Dale McNeill # # COPYRIGHT & DISCLAIMER: # ----------------------- # Copyright 1997 by Dale McNeill # The following code is provided as is. You may copy it, distribute # is as you wish. All this as long as you maintain this header which # includes my name, this copyright & disclaimer notice. # # Every commercial usage of this program is prohibited unless given # explicit permision by the author. # # The author holds no responsibility for this code. You may use it as you # wish at your on risk. # # If you like this code, send me a postcard, Email or preferably $10 :-) # so I can free more time to work on the next version (I do have to eat, # you know). If you found a bug, change the code, please drop me a note # at the Email address below. # # Dale McNeill # 515 North Grant St Apt #4 # West Lafayette, IN 47906 # # Email: neill@expert.cc.purdue.edu # Homepage & Other programs: http://shay.ecn.purdue.edu/~neill ############################################################################# # This is the version of the program that you are running. Please # do not change this line. $version = "3.01 Multi-page"; # For set up go to the location: # http://shay.ecn.purdue.edu/~neill/pagestats # # This program is set up in the hope that you will use this program # to keep a page count for multiple pages. If you have any questions # on how to use this program then use the command: # pagestats.cgi -command help # # If you run into any problems then check the page: # http://shay.ecn.purdue.edu/~neill/pagestats # # If the script doesn't work and you want to contact me, please check # the following first: # - did you upload the script in ASCII mode (*not* binary)? # - did you chmod the script 755 # - did you check the path to your server's Perl executable? # # If you still have a problem and you want me to help you, I need to know: # - a detailed description of your problem # - URL of page # - HTML code that was added # - script related error messages from your server's error log file # ##### HTML to be entered. Replace "filename" with name chosen. ####### ##### My program will display proper HTML code on initialization ##### # #
# PAGE STATS # # There are two places that you need to enter the filename in this code. ####################################################################### # CUSTOMIZATION # Some of the things you can customize are: # - the counter's digits # - Set your own color scheme for the statistical page. # - On the statistical page, the number of last days (right now 8) # - On the statistical page, the number of last weeks (right now 8) # - Where all ".txt" files are stored # # For an explaination of all the customization options go to: # http://shay.ecn.purdue.edu/~neill/pagestats # # From here down is ment for customization. If you are unsure about # a change leave it be. # The datafile will be where the data from the program will be stored. $datafile = "data.txt"; # This is the file that will store all the data from where everyone # is coming from. $domain_data = "domain.txt"; # This file is used to check for reloads. $hostfile = "hostfile.txt"; # If you would like all of the datafiles(.txt) stored in one directory # then state the path here. This is nice if you have the program # counting multiple pages. This variable can also be stated using # the flag "-datasource path". Example: #
# PAGE STATS # In this example all datafiles(.txt) are found at "text/data.txt", # "text/domain.txt",..etc. If you don't want to use this option leave # it blank. $text_dir = ""; # Please enter the name of the pagestats html file. This will be the # file that will have the visual representation of all the hits. # The program will automatically append the name of the file to the # begining of the pagestats html file. Example: If the file being # counted is named "scripts.html" then the pagestats html file would # be "scripts_pagestats.html". %html_doc = ( "page" => "pagestats.html", "body_tag" => { "bgcolor" => "white", "text" => "black", "link" => "blue", "vlink" => "purple", "alink" => "#9966CC", }, "table_options" => { "bgcolor_for_tables" => "white", "text_color_4_headers" => "black", "bgcolor_for_headers" => "#FFFFDD", }, "title_options" => { "image_on" => "1", "title_image" => "http://shay.ecn.purdue.edu/~neill/images/pagestat.gif", "color_for_title" => "blue", }, ); # The number's directory is where the ".gif" or ".jpg" images can be # found. The images should be named: "1.gif" "2.gif"...etc. # NOTE: If you do not have any images in your account then leave unchanged. # Right now the program is set up to reference my numbers. # View the different types at the URL: # http://shay.ecn.purdue.edu/~neill/numbers.html # To change to a new type of number, just remove the "#" from the # begining of the line and add a "#" to the front of the old numbers. # $num_dir = "plain text"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/T2"; $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/X_files"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/embossed_blue"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/embossed_green"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/fat_purple"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/purple_glow"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/yellow_glow"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/red_glow"; # $num_dir = "http://shay.ecn.purdue.edu/~neill/numbers/classic"; # The following array will let you select what number images are to # be used when entering the html code. Here's an example: #
# PAGE STATS # This code will display "X_files" images because "X_files" is number 2 # in the list. The major use of this # is for when using the program to count multiple pages you can # select different number images for each page. %numbers_dir = ( "1" => "http://shay.ecn.purdue.edu/~neill/numbers/T2", "2" => "http://shay.ecn.purdue.edu/~neill/numbers/X_files", "3" => "http://shay.ecn.purdue.edu/~neill/numbers/embossed_blue", "4" => "http://shay.ecn.purdue.edu/~neill/numbers/embossed_green", "5" => "http://shay.ecn.purdue.edu/~neill/numbers/fat_purple", "6" => "http://shay.ecn.purdue.edu/~neill/numbers/purple_glow", "7" => "http://shay.ecn.purdue.edu/~neill/numbers/yellow_glow", "8" => "http://shay.ecn.purdue.edu/~neill/numbers/red_glow", "9" => "http://shay.ecn.purdue.edu/~neill/numbers/classic", "10" => "plain text", ); # The bar image is basically just a colored square. If you do not have # this image then leave unchanged to use mine. $bar_img = "http://shay.ecn.purdue.edu/~neill/images/bargraph.gif"; # These will be the last number of days and weeks. $num_of_temp_days = 8; $num_of_temp_weeks = 8; $num_of_hosts = 25; # This is the length of time before a person gets noted as a reload. # This is measured in seconds. $interval = 1000; # This will print out what date the counter was reset. A one means # that the start date will be printed. Zero means that the start # date will not be printed. $start_date_enable = 1; ##### DO NOT MODIFY ANYTHING BEYOND THIS POINT ##### ############################################################################### ##### ##### MAIN PROGRAM ##### ############################################################################### $start_time = (times)[0]; @Days_of_Week = (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday); #### Table of domains Start #### %domain_name_lookup = ( "com", "USA Commercial", "org", "USA Organization", "int", "International Organization", "net", "Network", "NET", "Network", "gov", "USA Government", "edu", "USA Educational", "af", "Afghanistan", "al", "Albania", "dz", "Algeria", "as", "American Somoa", "ad", "Andorra", "ao", "Angola", "ai", "Anguilla", "aq", "ANtarctica", "ag", "Antigua and Barbuda", "ar", "Argentina", "am", "Armenia", "aw", "Aruba", "au", "Australia", "at", "Austria", "az", "Azerbaijan", "bh", "Bahrain", "bd", "Bangladesh", "bb", "Barbados", "by", "Belarus", "be", "Belgium", "bz", "Belize", "bj", "Benin", "bm", "Bermuda", "bt", "Bhutan", "bo", "Bolivia", "ba", "Bosnia and Herzegovina", "bw", "Botswana", "bv", "Bouvet Island", "br", "Brazil", "io", "British Indian Ocean Territory", "bn", "Brunei", "bg", "Bulgaria", "bf", "Burkina Faso", "bi", "Burundi", "kh", "Cambodia", "cm", "Cameroon", "ca", "Canada", "cv", "Cape Verde", "cf", "Central African Republic", "td", "Chad", "gg", "Channel Islands, Guernsey", "je", "Channel Islands, Jersey", "cl", "Chile", "cn", "China", "cx", "Christmas Island", "cc", "Cocos (Keeling) Islands", "co", "Colombia", "km", "Comoros", "cg", "Congo", "ck", "Cook Islands", "cr", "Costa Rica", "ci", "Cote d'Ivoire", "hr", "Croatia", "cu", "Cuba", "cy", "Cyprus", "cz", "Czech Republic", "dk", "Denmark", "dj", "Djibouti", "dm", "Dominica", "do", "Dominican Republic", "tp", "East Timor", "ec", "Ecuador", "eg", "Egypt", "sv", "El Salvador", "gq", "Equatorial Guinea", "er", "Eritrea", "ee", "Estonia", "et", "Ethiopia", "fk", "Falklands Islands", "fo", "Faroe Islands", "fj", "Fiji", "fi", "Finland", "fr", "France", "gf", "French Guiana", "pf", "French Polynesia", "tf", "French Southern Territories", "fx", "French, Metropolitan", "ga", "Gabon", "ge", "Georgia", "de", "Germany", "gh", "Ghana", "gi", "Gibraltar", "gr", "Greece", "gl", "Greenland", "gd", "Grenada", "gp", "Guadeloupe", "gu", "Guam", "gt", "Guatemala", "gn", "Guinea", "gy", "Guyana", "ht", "Haiti", "hm", "Heard and McDonald Islands", "hn", "Honduras", "hk", "Hong Kong", "hu", "Hungary", "is", "Iceland", "in", "India", "id", "Indonesia", "ir", "Iran", "iq", "Iraq", "ie", "Ireland", "il", "Israel", "it", "Italy", "jm", "Jamaica", "jp", "Japan", "jo", "Jordan", "kz", "Kazakhstan", "ke", "Kenya", "ki", "Kiribati", "kp", "Korea, Democratic People's Republic of", "kr", "Korea, Republic of", "kw", "Kuwait", "kg", "Kyrgyzstan", "la", "Laos", "lv", "Latvia", "lb", "Lebanon", "ls", "Lesotho", "lr", "Liberia", "ly", "Libyan Arab Jamahiriya", "li", "Liechtenstein", "lt", "Lithuania", "lu", "Luxembourg", "mo", "Macao", "mk", "Macedonia", "mw", "Malawi", "my", "Malaysia", "ml", "Mali", "mt", "Malta", "mh", "Marshall Islands", "mq", "Martinique", "mr", "Mauritania", "mu", "Mauritius", "yt", "Mayotte", "mx", "Mexico", "fm", "Micronesia", "md", "Moldova", "mc", "Monaco", "mn", "Mongolia", "ms", "Montserrat", "ma", "Morocco", "mz", "Mozambique", "mm", "Myanmar", "na", "Namibia", "nr", "Nauru", "np", "Nepal", "nl", "Netherlands", "an", "Netherlands Antilles", "nc", "New Caledonia", "nz", "New Zealand", "ni", "Nicaragua", "ne", "Niger", "ng", "Nigeria", "nu", "Niue", "nf", "Norfolk Island", "mp", "Northern Mariana Islands", "no", "Norway", "om", "Oman", "pk", "Pakistan", "pw", "Palau", "pa", "Panama", "pq", "Papua New Guinea", "py", "Paraguay", "pe", "Peru", "ph", "Philippines", "pn", "Pitcairn", "pl", "Poland", "pt", "Portugal", "pr", "Puerto Rico", "qa", "Qatar", "re", "Reunion", "ro", "Romania", "ru", "Russia", "rw", "Rwanda", "kn", "Saint Kitts and Nevis", "lc", "Saint Lucia", "vc", "Saint Vincent and the Grenadines", "ws", "Samoa", "sm", "San Marino", "st", "Sao Tome and Principe", "sa", "Saudi Arabia", "sn", "Senegal", "sc", "Seychelles", "sl", "Sierra Leone", "sg", "Singapore", "sk", "Slovakia", "si", "Slovenia", "sb", "Solomon Islands", "so", "Somalia", "za", "South Africa", "gs", "South Georgia and the South Sandwich Islands", "es", "Spain", "lk", "Sri Lanka", "sh", "St. Helena", "pm", "St. Pierre and Miquelon", "sd", "Sudan", "sr", "Suriname", "sj", "Svalbard and Jan Mayen Islands", "sz", "Swaziland", "se", "Sweden", "ch", "Switzerland", "sy", "Syria", "tw", "Taiwan", "tj", "Tajikistan", "tz", "Tanzania", "th", "Thailand", "bs", "The Bahamas", "ky", "The Cayman Islands", "to", "Tonga", "tt", "Trinidad and Tobago", "tn", "Tunisia", "tr", "Turkey", "tm", "Turkmenistan", "tc", "Turks and Caicos Islands", "tv", "Tuvalu", "ug", "Uganda", "ua", "Ukraine", "ae", "United Arab Emirates", "uk", "United Kingdom", "us", "United States", "um", "United States Minor Outlying Islands", "uy", "Urugauy", "uz", "Uzbekistan", "vu", "Vanuatu", "va", "Vatican City State", "ve", "Venezuela", "vn", "Vietnam", "vg", "Virgin Islands (British)", "vi", "Virgin Islands (US)", "wf", "Wallis and Futuna Islands", "eh", "Western Sahara", "ye", "Yemen", "yu", "Yugoslavia", "zr", "Zaire", "zm", "Zambia", "zw", "Zimbabwe", "other", "Unknown Location", ); #### Table of domains End #### &init_date; # subroutine to initialize the date &init_last_days; &init_last_weeks; &get_para_and_exec; # subroutine to decide which path of execution is to be taken $end_time = (times)[0]; # printf "\nThat took %.3f CPU seconds\n\n", $end_time - $start_time; ## Performance evaluation ## exit; ################################# End of the main program ##################################################### ################################# subroutines from here down ################################################## ########################################## # init_data # # The purpose of this subroutine is to # initialize all the datafiles ########################################## sub init_data { open(DATAFILE, "> $datafile") || die "ERROR: Can't create the file $datafile. \n Please check the file path for directories that do not exist.\n"; print DATAFILE "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"; print DATAFILE "0 0 0 0 0 0 0\n"; print DATAFILE "0\n"; #$temp_year = `date +%y`; $temp_date = sprintf("${num_month}/%02d/${year}", $num_day); print DATAFILE "$temp_date\n"; foreach $i (@last_days) { print DATAFILE "$i\n"; } foreach $i (@last_weeks) { print DATAFILE "$i\n"; } close(DATAFILE); } ########################################## # read_data # # The purpose of this subroutine is to # read in all the data from the datafiles ########################################## sub read_data { open(DATAFILE,"$datafile") || die "ERROR: Can't open $datafile.\n"; for ($cnt = 0; $temp_data = ; $cnt++) { chop $temp_data; if ($cnt == 0) { ($hour_hits[0], $hour_hits[1], $hour_hits[2], $hour_hits[3], $hour_hits[4], $hour_hits[5], $hour_hits[6], $hour_hits[7], $hour_hits[8], $hour_hits[9], $hour_hits[10], $hour_hits[11], $hour_hits[12], $hour_hits[13], $hour_hits[14], $hour_hits[15], $hour_hits[16], $hour_hits[17], $hour_hits[18], $hour_hits[19], $hour_hits[20], $hour_hits[21], $hour_hits[22], $hour_hits[23]) = split(/\s+/,$temp_data); } elsif ($cnt == 1) { ($day_hits{ $Days_of_Week[0] }, $day_hits{ $Days_of_Week[1] }, $day_hits{ $Days_of_Week[2] }, $day_hits{ $Days_of_Week[3] }, $day_hits{ $Days_of_Week[4] }, $day_hits{ $Days_of_Week[5] }, $day_hits{ $Days_of_Week[6] } ) = split(/\s+/, $temp_data); } elsif ($cnt == 2) { $count = $temp_data; } elsif ($cnt == 3) { $start_date = $temp_data; } elsif ($cnt >= 4 && $cnt < (4 + $num_of_temp_days)) { $temp_num = $cnt - 4; $temp_last_days[$temp_num] = $temp_data; } elsif (($cnt >= (4 + $num_of_temp_days)) && ($cnt < ((4 + $num_of_temp_days) + $num_of_temp_weeks)) ) { $temp_num = $cnt - (4 + $num_of_temp_days); $temp_last_weeks[$temp_num] = $temp_data; } elsif (($cnt >= (4 + $num_of_temp_days + $num_of_temp_weeks)) && ($cnt < (4 + $num_of_temp_days + $num_of_temp_weeks + $num_of_hosts)) ) { push(@hosts, $temp_data); } } close(DATAFILE); # Read in the domain data open (DOMAIN_FILE, "$domain_data") || die "ERROR: $domain_data DNE\n"; while ($line = ) { chomp $line; ($temp_domain, $temp_num) = split(/\s+/, $line); $domains{$temp_domain} = $temp_num; } close (DOMAIN_FILE); } ########################################## # write_data # # The purpose of this subroutine is to # write all the data back to the datafiles ########################################## sub write_back { open(DATAFILE, "> $datafile"); foreach $item (@hour_hits) { print DATAFILE "$item "; } print DATAFILE "\n"; foreach $item (@Days_of_Week) { print DATAFILE "$day_hits{$item} "; } print DATAFILE "\n"; print DATAFILE "$count\n"; print DATAFILE "$start_date\n"; foreach $item (@finished_days) { print DATAFILE "$item\n"; } foreach $item (@finished_weeks) { print DATAFILE "$item\n"; } foreach $item (@hosts) { print DATAFILE "$item\n"; } close(DATAFILE); open (DOMAIN_FILE, "> $domain_data"); foreach $item (sort keys %domains) { print DOMAIN_FILE "$item $domains{$item}\n"; } close (DOMAIN_FILE); } sub init_last_weeks { $num = $week_num + 1; for ($i = 0; $i < $num_of_temp_weeks; $i++) { $new_value = "week $num:0"; push(@last_weeks, $new_value); $num--; if ($num < 1) { $num = 53; } } } sub init_last_days { %order_of_months = ( 'February', 'January', 'March', 'February', 'April', 'March', 'May', 'April', 'June', 'May', 'July', 'June', 'August', 'July', 'September', 'August', 'October', 'September', 'November', 'October', 'December', 'November', 'January', 'December', ); $temp_num_day = $num_day; $temp_month = $month; for ($i = 0; $i < $num_of_temp_days; $i++) { $new_value = "@Days_of_Week[${start_day}] $temp_month $temp_num_day, $year:0"; push(@last_days, $new_value); $temp_num_day--; if ($temp_num_day < 1) { if ($temp_month =~ /^May$/ || $temp_month =~ /^July$/ || $temp_month =~ /^October$/ || $temp_month =~ /^December$/ ) { $temp_num_day = 30; $temp_month = $order_of_months{ $temp_month }; } elsif ($temp_month =~ /^January$/ || $temp_month =~ /^February$/ || $temp_month =~ /^April$/ || $temp_month =~ /^June$/ || $temp_month =~ /^August$/ || $temp_month =~ /^September$/ || $temp_month =~ /^November$/ ) { $temp_num_day = 31; $temp_month = $order_of_months{ $temp_month }; if ($temp_month eq "December") { $year--; } } else { if (($year % 4) == 0) { $temp_num_day = 29; } else { $temp_num_day = 28; } $temp_month = $order_of_months{ $temp_month }; } } $start_day--; if ($start_day < 0) { $start_day = 6; } } } sub init_date { %months_fullname = ( 'Jan', 'January', 'Feb', 'February', 'Mar', 'March', 'Apr', 'April', 'May', 'May', 'Jun', 'June', 'Jul', 'July', 'Aug', 'August', 'Sep', 'September', 'Oct', 'October', 'Nov', 'November', 'Dec', 'December', ); @times=localtime(time); $times=localtime(time); ($day,$month,$num_day,$time,$year)= split(/\s+/, $times); $num_month=@times[4]+1; $ampm=($times[2]>=12)?"PM":"AM"; $hours=$times[2]; $week_num=int($times[7]/7); $start_day=$times[6]; $day=$Days_of_Week[$start_day]; $num_month=sprintf("%02d",$num_month); ($cor_hours, $minutes, $seconds) = split(/:/, $time); if ((split(//,$month)) < 4) { $month = $months_fullname{${month}}; } } sub print_stdout { print "\n\tTOTAL COUNT: $count\n\n"; $cnt = 0; foreach $item (@hour_hits) { print "$cnt = $item\n"; $cnt++; } print "\n"; foreach $item (@Days_of_Week) { print "$item = $day_hits{$item}\n"; } print "\n"; foreach $item (@finished_days) { print "$item\n"; } print "\n"; foreach $item (@finished_weeks) { print "$item\n"; } print "\n"; } sub check_reload { if (-e "$hostfile") { open(HOST,"$hostfile"); $hostline = ; chop($hostline) if $hostline =~ /\n$/; close(HOST); ($old_time,$old_number,$old_page,$old_browser) = split(/\|/,$hostline); } # save host and time info and check if this is a page reload open(HOST,">$hostfile"); $seconds = time; print HOST "$seconds\|$ENV{REMOTE_ADDR}\|$ENV{'DOCUMENT_URI'}\|$ENV{'HTTP_USER_AGENT'}"; close(HOST); # if (time - $old_time < $interval # && $ENV{REMOTE_ADDR} eq $old_number # && $ENV{'DOCUMENT_URI'} eq $old_page # || $host_name eq "ecnipc.ecn.purdue.edu") # { # return 0; # } return 1; } ############################################### # get_para_and_exec # # Purpose: # The purpose of this subroutine is to process # all of the parameters and find the correct # path of execution. ############################################### sub get_para_and_exec { die "Your system does not support PERL 5.003\n" if $] < 5.003; #### If the page does not support SSI's #### if (! defined @ARGV) { $in = $ENV{'QUERY_STRING'}; @in = split(/&/,$in); foreach $i (0 .. $#in) { # Convert plus's to spaces $in[$i] =~ s/\+/ /g; # Split into key and value. ($key, $val) = split(/=/,$in[$i],2); # splits on the first =. # Convert %XX from hex numbers to alphanumeric $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; # Associate key and value $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator $in{$key} .= $val; } $in{SSI} = "no"; # webpage does not have SSI's } else { use Getopt::Long; $result = GetOptions("command=s"=> \$in{command}, "file|filename=s" => \$in{filename}, "numbers=i" => \$in{number}, "nodisplay!" => \$in{nodisplay}, "datasource|data=s" => \$in{datasource}); if ($result != 1) { &print_error("You forgot a certain parameter"); exit; } $in{SSI} = "yes"; # webpage does have SSI's } if ($in{command} eq "version") { print "\n$0 \t\tVersion: $version\n\n"; exit; } if ($in{command} eq "help") { &print_help; exit; } if ((! defined $in{filename}) || (! defined $in{command})) { &print_error("You forgot either the filename or the command"); exit; } if (defined $in{number}) { $num_dir = $numbers_dir{($in{number})}; } if (defined $in{datasource}) { $text_dir = $in{datasource}; $text_dir =~ s/\/$//; $text_dir = sprintf("${text_dir}/"); } $in{filename} =~ s/\.html//; $hostfile = sprintf("${text_dir}${in{filename}}_${hostfile}"); $html_doc{page} = sprintf("${in{filename}}_${html_doc{page}}"); $domain_data = sprintf("${text_dir}${in{filename}}_${domain_data}"); $datafile = sprintf("${text_dir}${in{filename}}_${datafile}"); $html_doc{page} = sprintf("${text_dir}${html_doc{page}}") if ($in{SSI} eq "no"); $datafile =~ m%[\w./]+%; $datafile = $&; $hostfile =~ m%[\w./]+%; $hostfile = $&; $domain_data =~ m%[\w./]+%; $domain_data = $&; $html_doc{page} =~ m%[\w./]+%; $html_doc{page} = $&; if (($in{command} eq "count") && ($in{SSI} eq "no")) { &get_user_info; if (&check_reload == 1) { &read_data; &increment_data; &write_back; &print_html; } &print_image($in{digit}); exit; } if (($in{command} eq "count") && ($in{SSI} eq "yes")) { &get_user_info; &read_data; if (&check_reload == 0) { if (! defined $in{nodisplay}) { &print_display; } exit; } &increment_data; &write_back; if (! defined $in{nodisplay}) { &print_display; } &print_html; exit; } if ($in{command} eq "display") { if (! defined $in{digit}) { &print_error("You forgot to enter the number of the digit"); exit; } &read_data; &print_image($in{digit}); exit; } if (($in{command} eq "init") && ($in{SSI} eq "yes")) { unlink $domain_data; #system("touch $domain_data"); system "/bin/touch", $domain_data; &init_data; &read_data; &print_html; unlink $hostfile; #system("touch $hostfile"); system "/bin/touch", $hostfile; chmod 0666, $datafile; chmod 0666, $domain_data; chmod 0666, $html_doc{page}; chmod 0666, $hostfile; print "\n\tDONE\n\n"; print "HTML code to be added:\n\n"; if (defined $in{datasource}) { print<
PAGE STATS If your Service Provider does NOT support Server Side Includes then add: PAGE STATS EOF } else { print<
PAGE STATS If your Service Provider does NOT support Server Side Includes then add: PAGE STATS EOF } print "\n"; exit; } if (($in{command} eq "init") && ($in{SSI} eq "no")) { unlink $domain_data; system("touch $domain_data"); &init_data; &read_data; &print_html; unlink $hostfile; system("touch $hostfile"); chmod 0666, $datafile; chmod 0666, $domain_data; chmod 0666, $html_doc{page}; chmod 0666, $hostfile; if ((! -e $datafile) || (! -e $domain_data) || (! -e $html_doc{page}) || (! -e $hostfile)) { &print_error("Error: Check to make sure that directory for storage is readable and writable by others."); exit; } &print_html_code; #&print_image($in{digit}); exit; } if ($in{command} eq "debug") { &read_data; &increment_data; &print_stdout; &write_back; exit; } } sub increment_data { $temp_num_day = sprintf("%02d", $num_day); unshift(@hosts, "${month}-${temp_num_day}-${time} ${ampm}|$host_name"); @temp_host_array = split(/\./, $host_name); $temp_domain = pop(@temp_host_array); $temp_domain =~ tr/A-Z/a-z/; if (defined $domains{$temp_domain}) { $domains{$temp_domain}++; } elsif (defined $domain_name_lookup{$temp_domain}) { $domains{$temp_domain} = 1; } else { $domains{'other'}++; } $today = shift(@last_days); ($long_date, $day_count) = split(/:/, $today); $day_count++; $today = "${long_date}:${day_count}"; unshift(@last_days, $today); $thisweek = shift(@last_weeks); ($temp_week, $week_count) = split(/:/, $thisweek); $week_count++; $thisweek = "${temp_week}:${week_count}"; unshift(@last_weeks, $thisweek); $hour_hits[$hours]++; $day_hits{ $day }++; $count++; $temp_cnt = 0; for ($cnt = 0; $cnt < $num_of_temp_days; $cnt++) { ($real_date, $real_count) = split(/:/, $last_days[$cnt]); ($temp_date, $temp_count) = split(/:/, $temp_last_days[$temp_cnt]); if ($real_date eq $temp_date) { $total_count = $temp_count + $real_count; $finished_days[$cnt] = "${real_date}:${total_count}"; $temp_cnt++; } else { $finished_days[$cnt] = "${real_date}:${real_count}"; } } $temp_cnt = 0; for ($cnt = 0; $cnt < $num_of_temp_weeks; $cnt++) { ($real_week, $real_count) = split(/:/, $last_weeks[$cnt]); ($temp_week, $temp_count) = split(/:/, $temp_last_weeks[$temp_cnt]); if ($real_week eq $temp_week) { $total_count = $temp_count + $real_count; $finished_weeks[$cnt] = "${real_week}:${total_count}"; $temp_cnt++; } else { $finished_weeks[$cnt] = "${real_week}:${real_count}"; } } } sub get_user_info { # Some of Perl's network info functions required here ($part1,$part2,$part3,$part4)=split(/\./,$ENV{REMOTE_ADDR}); $IP_adr=pack("C4",$part1,$part2,$part3,$part4); ($host_name)=(gethostbyaddr("$IP_adr", 2)); $host_name = "Unknown" if $host_name =~ /^\s*$/; $page_from = $ENV{'HTTP_REFERER'}; $IP = $ENV{'REMOTE_ADDR'}; $machine = $ENV{'HTTP_USER_AGENT'}; $log_page = $ENV{'DOCUMENT_URI'}; } sub print_image { my $num = shift(@_); @temp_count = split(//, $count); @count = reverse @temp_count; if (defined ((@count)[$num])) { $num = (@count)[$num]; } else { $num = "0"; } print "Content-type: image/gif\n"; print "Pragma: no-cache\n"; print "Location: ${num_dir}/${num}.gif\n\n"; } sub print_display { if ($num_dir ne "plain text") { chop $num_dir if $num_dir =~ /\w+\/$/; print ""; print ""; @count = split(//, $count); while(@count) { $temp_num = shift(@count); print ""; } } else { print "$count"; } print "
Since $start_date" if $start_date_enable == 1; } sub print_info { # print HTML < # # About Pagestats # # # #
# Pagestats author is at Dale McNeill's Homepage
# To contact Dale McNeill email him at neill\@expert.cc.purdue.edu
# The Pagestats program is free for non-commercial users click to # Download Program
# Pagestats Version: $version
# Copyright © Dale McNeill 1997
# # # # # For number images go to: # Digitmania
# Here is a link to find out what # types of numbers I have to choose from: # My numbers
# # # # EOF } sub print_where_from { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; foreach $item (keys %domains) { if ($domains{$item} > $largest) { $largest = $domains{$item}; } } foreach $item (sort keys %domains) { $temp_name = $domain_name_lookup{$item}; print HTML " \n"; print HTML " \n"; if ($largest == 0 || (($domains{$item} / $largest) * 100) < 1) { print HTML " \n"; } else { printf HTML " \n", ($domains{$item} / $largest) * 100; } print HTML " \n"; print HTML " \n"; } print HTML "
Where Visitors Came From
$temp_name
$domains{$item}
\n"; } sub print_hosts { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; foreach $item (@hosts) { ($temp_date, $temp_host) = split(/\|/, $item); print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; } print HTML "
Last $num_of_hosts Visitors
$temp_date
$temp_host
\n"; } sub print_daily_hits { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; $largest = 0; foreach $item (@Days_of_Week) { if ($day_hits{$item} > $largest) { $largest = $day_hits{$item}; } } foreach $item (@Days_of_Week) { $num = $day_hits{$item}; print HTML " \n"; print HTML " \n"; if ($largest == 0 || (($num / $largest) * 100) < 1) { print HTML " \n"; } else { printf HTML " \n", ($num / $largest) * 100; } print HTML " \n"; print HTML " \n"; } print HTML "
Total Hits by Day
$item
$day_hits{$item}
\n"; } sub print_temp_days { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; $largest = 0; foreach $item (@finished_days) { $temp_count = (split(/:/, $item))[1]; if ($temp_count > $largest) { $largest = $temp_count; } } foreach $item (@finished_days) { ($temp_date, $temp_count) = split(/:/, $item); $num = $temp_count; print HTML " \n"; print HTML " \n"; if ($largest == 0 || (($num / $largest) * 100) < 1) { print HTML " \n"; } else { printf HTML " \n", ($num / $largest) * 100; } print HTML " \n"; print HTML " \n"; } print HTML "
Activity For the Last $num_of_temp_days Days
$temp_date
$temp_count
\n"; } sub print_temp_weeks { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; $largest = 0; foreach $item (@finished_weeks) { $temp_count = (split(/:/, $item))[1]; if ($temp_count > $largest) { $largest = $temp_count; } } foreach $item (@finished_weeks) { ($temp_week, $temp_count) = split(/:/, $item); $num = $temp_count; print HTML " \n"; print HTML " \n"; if ($largest == 0 || (($num / $largest) * 100) < 1) { print HTML " \n"; } else { printf HTML " \n", ($num / $largest) * 100; } print HTML " \n"; print HTML " \n"; } print HTML "
Activity For the Last $num_of_temp_weeks Weeks
$temp_week
$temp_count
\n"; } sub print_hour_hits { print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML " \n"; $largest = 0; foreach $item (@hour_hits) { if ($item > $largest) { $largest = $item; } } $cnt = 0; foreach $item (@hour_hits) { $num = $item; print HTML " \n"; print HTML " \n"; if ($largest == 0 || (($num / $largest) * 100) < 1) { print HTML " \n"; } else { printf HTML " \n", ($num / $largest) * 100; } print HTML " \n"; print HTML " \n"; $cnt++; } print HTML "
Total Hits by Hour
$times_of_day{$cnt}
$item
\n"; } sub print_html { %times_of_day = ( '0', 'Midnight to 1 AM', '1', '1 AM to 2 AM', '2', '2 AM to 3 AM', '3', '3 AM to 4 AM', '4', '4 AM to 5 AM', '5', '5 AM to 6 AM', '6', '6 AM to 7 AM', '7', '7 AM to 8 AM', '8', '8 AM to 9 AM', '9', '9 AM to 10 AM', '10', '10 AM to 11 AM', '11', '11 AM to Noon', '12', 'Noon to 1 PM', '13', '1 PM to 2 PM', '14', '2 PM to 3 PM', '15', '3 PM to 4 PM', '16', '4 PM to 5 PM', '17', '5 PM to 6 PM', '18', '6 PM to 7 PM', '19', '7 PM to 8 PM', '20', '8 PM to 9 PM', '21', '9 PM to 10 PM', '22', '10 PM to 11 PM', '23', '11 PM to Midnight', ); open(HTML, "> $html_doc{page}"); print HTML "\n\nPagestats for $in{filename}\n\n\n"; print HTML "\n
\n"; if ($html_doc{title_options}{image_on} == 1) { print HTML "
\n"; } else { print HTML "

$in{filename} Pagestats

"; } print HTML "Today's date: $day, $month $num_day"; print HTML "   Time: $time $ampm
"; print HTML "The current count of the page $in{filename} is: $count"; print HTML "   Since: $start_date

"; print HTML "\n"; print HTML "\n"; print HTML " \n\n"; print HTML " \n"; print HTML "\n"; print HTML "
\n"; &print_temp_days; print HTML " \n"; &print_temp_weeks; print HTML "
\n"; print HTML "


\n"; print HTML "\n"; print HTML "\n"; print HTML " \n\n"; print HTML " \n"; print HTML "\n"; print HTML "
\n"; &print_hour_hits; print HTML " \n"; &print_daily_hits; print HTML "
\n"; &print_where_from; print HTML "
\n"; # print HTML "


\n"; # # print HTML "\n"; # print HTML "\n"; # print HTML " \n"; # print HTML "\n"; # print HTML "
\n"; # &print_info; # print HTML "
\n"; # # print HTML "


\n"; # # print HTML "\n"; # print HTML "\n"; # print HTML " \n"; # print HTML "\n"; # print HTML "
\n"; # &print_hosts; # print HTML "
\n"; print HTML "
\n\n\n"; close HTML; } sub print_help { print <
PAGE STATS A good thing to remember is that "welcome" is not the name of the file but rather the name of the count data. The name "welcome" is used to separate data from one page from another. ================================================================= Here's an advanced example:
PAGE STATS In this example my data is stored in a lower directory call "text_stuff". For those of you who are UNIX amatures ".." means back one directory and "." means current directory. Here is the initialization for the code above. ../cgi-bin/pagestats.cgi -command init -filename welcome -datasource ../text_stuff ================================================================= EOF } sub print_error { print "Content-Type: text/html\n\n"; print < Error Screen EOF print "

@_

"; print "\n\n"; } sub print_html_code { print "Content-Type: text/html\n\n"; print < HTML CODE to be added

Initialization Done

The following code must be added to your HTML file. Please replace anything that is in blue.

  • This is the HTML code if your service provider does not support Server Side Includes:
    <img src="(path to cgi-bin directory from HTML document)/pagestats.cgi?command=count&digit=3&filename=$in{filename}&datasource=$in{datasource}"> <img src="(path to cgi-bin directory from HTML document)/pagestats.cgi?command=display&digit=2&filename=$in{filename}&datasource=$in{datasource}"> <img src="(path to cgi-bin directory from HTML document)/pagestats.cgi?command=display&digit=1&filename=$in{filename}&datasource=$in{datasource}"> <img src="(path to cgi-bin directory from HTML document)/pagestats.cgi?command=display&digit=0&filename=$in{filename}&datasource=$in{datasource}"> <a href="$in{filename}_pagestats.html">PAGE STATS</a>

  • This is the HTML code if your service provider supports Server Side Include's:
    <!--#exec cmd="(path to cgi-bin directory from HTML document)/pagestats.cgi -command count -file $in{filename} -datasource (relative path to data from HTML document)"-->
    <a href="$in{filename}_pagestats.html">PAGE STATS</a>

    You will need to figure out the relative path from your HTML document to your data directory if you use the Server Side Include code.
EOF } ########################## End of subroutines #################################