#!/usr/bin/perl
##############################################################################
# Counter                        Version 1.1.1                               #
# Copyright 1996                 worldwidemart.com                           #
# Created 04/25/96               Last Modified 04/25/96                      #
# Scripts Archive:               https://www.worldwidemart.com/scripts/          #
##############################################################################
# COPYRIGHT NOTICE                                                           #
# This script is distributed under the Artistic License.                     #
# You may freely use and modify it, keeping this copyright notice intact.    #
##############################################################################
# DESCRIPTION                                                                #
# This script creates a graphical hit counter that displays the number of    #
# visitors to your page using customizable digit images.                     #
##############################################################################

use strict;
use warnings;
use CGI qw(:standard);

# Configuration
my $count_file = './count.txt';       # Path to count file
my $lock_file  = './count.lock';      # Lock file for concurrency
my $log_file   = './access_log';      # Access log file
my $digits_dir = './digits/';         # Directory containing digit images

# Valid referers (leave empty to allow all)
my @valid_referers = ();

# Image settings
my $img_width  = 15;                  # Width of each digit image
my $img_height = 20;                  # Height of each digit image
my $pad_char   = '0';                 # Character to pad numbers (0 or space)
my $num_digits = 6;                   # Number of digits to display

##############################################################################
# Main Script - No modifications needed below this line
##############################################################################

# Get environment variables
my $remote_host = $ENV{'REMOTE_HOST'} || $ENV{'REMOTE_ADDR'} || 'unknown';
my $referer     = $ENV{'HTTP_REFERER'} || '';

# Check referer if validation is enabled
if (@valid_referers) {
    my $valid = 0;
    foreach my $ref (@valid_referers) {
        if ($referer =~ /\Q$ref\E/i) {
            $valid = 1;
            last;
        }
    }
    unless ($valid) {
        print header('image/gif');
        output_error_image();
        exit;
    }
}

# Read current count
my $count = read_count();

# Increment and save
$count++;
write_count($count);

# Log access
log_access($count);

# Output the counter image
output_counter($count);

##############################################################################
# Subroutines
##############################################################################

sub read_count {
    my $count = 0;

    if (-e $count_file) {
        open(my $fh, '<', $count_file) or return 0;
        $count = <$fh>;
        close($fh);
        chomp($count);
        $count = 0 unless $count =~ /^\d+$/;
    }

    return $count;
}

sub write_count {
    my ($count) = @_;

    # Simple file locking
    my $max_tries = 10;
    my $tries = 0;

    while (-e $lock_file && $tries < $max_tries) {
        sleep(1);
        $tries++;
    }

    # Create lock
    open(my $lock, '>', $lock_file);
    close($lock);

    # Write count
    open(my $fh, '>', $count_file) or do {
        unlink($lock_file);
        return;
    };
    print $fh $count;
    close($fh);

    # Remove lock
    unlink($lock_file);
}

sub log_access {
    my ($count) = @_;

    my $timestamp = localtime();

    open(my $fh, '>>', $log_file) or return;
    print $fh "[$timestamp] Count: $count | Host: $remote_host | Referer: $referer\n";
    close($fh);
}

sub output_counter {
    my ($count) = @_;

    # Pad the count
    my $padded = sprintf("%0${num_digits}d", $count);

    # For simplicity, output as text (real implementation would use GD or FLY)
    print header('text/html');
    print "<div style='font-family: monospace; font-size: 24px; background: #000; color: #0f0; padding: 5px; display: inline-block;'>";
    print $padded;
    print "</div>\n";

    # Note: Original script used FLY graphics library to generate actual images
    # Modern alternative: Use CSS-styled HTML or JavaScript counter
}

sub output_error_image {
    # Output a simple error indicator
    # In real implementation, this would be a GIF image
    print "GIF89a"; # Minimal GIF header
}

__END__

=head1 NAME

counter.pl - Graphical Hit Counter

=head1 SYNOPSIS

Place in your cgi-bin directory and call via:

  <img src="/cgi-bin/counter.pl" alt="Hit Counter">

=head1 DESCRIPTION

This script maintains a count of page visits and displays it as a graphical
counter. It includes features like:

- File locking for concurrent access
- Referer validation for security
- Access logging
- Customizable digit images

=head1 CONFIGURATION

Edit the configuration section at the top of the script to set:

- $count_file: Path to the file storing the count
- $digits_dir: Directory containing digit images (0.gif through 9.gif)
- @valid_referers: List of valid referring domains
- $num_digits: Number of digits to display

=head1 REQUIREMENTS

- Perl 5.x
- CGI.pm module
- Write permissions to count and log files

=head1 MODERN ALTERNATIVES

For modern web analytics, consider:
- Google Analytics
- Plausible Analytics
- Matomo
- Simple Analytics

=head1 LICENSE

Artistic License

=cut
