############################################################################### # ErrorLog.pm # # $Date: 01 Sep 2026 $ # ############################################################################### # YaBB: Yet another Bulletin Board # # Open-Source Community Software for Webmasters # # Version: YaBBForum 3.2 # # Packaged: 01 Sep 2026 # # Distributed by: https://yabbforum.nz # # =========================================================================== # # Copyright (c) 2000-2026 YaBB (yabbforum.nz) - All Rights Reserved. # # Software by: The YaBB Development Team # # with assistance from the YaBB community. # ############################################################################### use CGI::Carp qw(fatalsToBrowser); our $VERSION = '3.2'; $errorlogpmver = 'YaBBForum 3.2'; if ( $action eq 'detailedversion' ) { return 1; } sub ErrorLog { is_admin_or_gmod(); $yytitle = "$errorlog{'1'}"; $errorcount = 0; fopen( ERRORFILE, "$vardir/errorlog.txt" ); @errors = ; fclose(ERRORFILE); $errorcount = @errors; $date2 = $date; $mytest = 0; for my $i ( 0 .. $#errors ) { my @tmpArray = split /\|/xsm, $errors[$i]; if ( $tmpArray[0] eq q{} || $tmpArray[0] =~ /\D/igsm || $tmpArray[1] eq q{} || $tmpArray[1] =~ /\D/igsm ) { next; } else { $date1 = $tmpArray[1]; calcdifference(); $date_ref = $result; $tmplist[$mytest] = qq~$date_ref|$errors[$i]~; $mytest++; } } $sortmode = $INFO{'sort'}; $sortorder = $INFO{'order'}; if ( $sortmode eq q{} ) { $sortmode = 'time'; } if ( $sortorder eq q{} ) { $sortorder = 'reverse'; } my @sortlist = (); my $field = '0'; # 0-based field defaults to the datecmp value my $type = '0'; # 0=numeric; 1=text my $case = '1'; # 0=case sensitive; 1=ignore case my $dir = '0'; # 0=increasing; 1=decreasing if ( $sortmode eq 'time' ) { $field = '1'; $type = '0'; $case = '1'; $dir = '0'; } elsif ( $sortmode eq 'users' ) { $field = '8'; $type = '1'; $case = '1'; $dir = '0'; } elsif ( $sortmode eq 'ip' ) { $field = '3'; $type = '0'; $case = '0'; $dir = '0'; } @sortlist = map { $_->[0] } sort { YaBBsort( $field, $type, $case, $dir ) } map { [ $_, split /\|/xsm ] } @tmplist; if ( $INFO{'order'} eq 'reverse' ) { @sortlist = reverse @sortlist; } else { if ( $sortmode eq 'time' ) { $order_time = ';order=reverse'; } elsif ( $sortmode eq 'users' ) { $order_users = ';order=reverse'; } elsif ( $sortmode eq 'ip' ) { $order_ip = ';order=reverse'; } } if ( $sortmode ne q{} ) { $sortmode = ';sort=' . $INFO{'sort'}; } if ( $sortorder ne q{} ) { $sortorder = ';order=' . $INFO{'order'}; } $errorlog_error = q{}; if ( $#errors > $#tmplist ) { $err = $#errors - $#tmplist; $errorlog_error = qq~
$errorlog{'27a'} $err $errorlog{'27b'}~; if ( $err == 1 ) { $errorlog_error = qq~
$errorlog{'27c'} $err $errorlog{'27d'}~; } } $yymain .= qq~\
~; $numshown = 0; $actualnum = 0; $bb = 0; while ( $numshown <= $errorcount ) { my ( $tmp_user, $username, $numb, $ids, $all ) = q{}; $numshown++; $sortlist[$bb] =~ s/
/\[br \/\]/gsm; $sortlist[$bb] =~ s//\[b\]/gxsm; $sortlist[$bb] =~ s/<\/b>/\[\/b\]/gxsm; $sortlist[$bb] =~ s//>/gxsm; $sortlist[$bb] =~ s/\[b\]//gxsm; $sortlist[$bb] =~ s/\[\/b\]/<\/b>/gxsm; $sortlist[$bb] =~ s/\[br \/\]/
/gsm; $sortlist[$bb] =~ s/\$/$/gsm; $sortlist[$bb] =~ s/\@/@/gsm; $sortlist[$bb] =~ s/\%/%/gsm; my ( $tmp_datecmp, $tmp_id, $tmp_date, $tmp_userip, $tmp_error, $tmp_action, $tmp_topic_number, $tmp_board, $tmp_username, $tmp_password ) = split /\|/xsm, $sortlist[$bb]; if ( !$tmp_id ) { next; } FormatUserName($tmp_username); if ( !$tmp_username ) { $tmp_user = 'Guest'; } else { $tmp_user = $tmp_username; } $userlist{$tmp_user} = $userlist{$tmp_user} + 1; $tmp_date = timeformat($tmp_date); LoadUser($tmp_user); my $ipBlock = q{}; my $lookupIP = qq{$tmp_userip}; my $ipBan = q{}; if ( $tmp_userip ne '127.0.0.1' ) { $ipBlock = ( $use_guardian && $use_htaccess ) ? qq~
$admin_txt{'ipblock'}~ : qq~
$admin_txt{'ipblock2'}~; $lookupIP = ($ipLookup) ? qq~$tmp_userip~ : qq~$tmp_userip~; $ipBan = qq~ - $admin_txt{'725f'}~; } if ( $tmp_user eq "$useraccount{$tmp_user}" ) { if ( $userprofile{$tmp_user}->[1] ) { $username = qq~$userprofile{$tmp_user}->[1]~; } else { $username .= qq~$useraccount{$tmp_user}~; } $username .= qq~
$lookupIP$ipBan$ipBlock~; } else { $username = qq~$tmp_user
$lookupIP$ipBan$ipBlock~; } if ( $tmp_topic_number eq q{} ) { $numb = "&action=$tmp_action"; } else { $numb = "&action=$tmp_action&num=$tmp_topic_number"; } if ( $tmp_board eq q{} ) { $ids = '?board='; } else { $ids = "?board=$tmp_board"; } if ( $tmp_action eq q{} && $tmp_board eq q{} ) { $all = "$boardurl/$yyexec.$yyext"; } else { $all = "$boardurl/$yyexec.$yyext$ids$numb"; } if ( $tmp_error eq $admin_txt{'39'} || $tmp_error eq $admin_txt{'40'} ) { $tmp_error = $tmp_error . qq~ - ($tmp_password)~; } $bb++; $addel = qq~
~; $actualnum++; $print_errorlog .= qq~ $addel ~; } if ( !($actualnum) ) { $print_errorlog = qq~~; } $yymain .= qq~ $print_errorlog ~; @userlist = reverse sort { $userlist{$a} <=> $userlist{$b} } keys %userlist; foreach my $member (@userlist) { $errmember .= qq~$member ($userlist{$member}), ~; } $errmember =~ s/, \Z//sm; $yymain .= qq~
$admin_img{'xx'} $yytitle
$errorlog{'18'} $errorlog_error
$errorlog{'21'} $errorlog{'5'} $errorlog{'11'} ( $errorlog{'6'} ) $errorlog{'7'} / $errorlog{'8'} $errorlog{'13'}
$actualnum $tmp_date $username
$tmp_error
$all
$errorlog{'19'}
$errorlog{'26'} $errmember
 ~; if ( $errorcount > 0 ) { $yymain .= qq~ ~; } $yymain .= q~  ~; if ( $errorcount > 0 ) { $yymain .= q~~; } $yymain .= q~
~; if ( $errorcount > 0 ) { $yymain .= qq~
$admin_img{'prefimg'} $errorlog{'14'}

$errorlog{'14a'}
~; } $yymain .= q~ ~; $action_area = 'errorlog'; AdminTemplate(); return; } sub CleanErrorLog { is_admin_or_gmod(); if ( -e ("$vardir/errorlog.txt") ) { unlink "$vardir/errorlog.txt" or croak qq~$!~; } $yySetLocation = qq~$adminurl?action=errorlog~; redirectexit(); return; } sub DeleteError { is_admin_or_gmod(); my ( $sortmode, $sortorder ); chomp $FORM{'button'}; if ( $FORM{'button'} ne '4' ) { fatal_error('no_access'); } fopen( FILE, "$vardir/errorlog.txt" ); @errors = ; fclose(FILE); unlink "$vardir/errorlog.txt"; fopen( FILE, ">>$vardir/errorlog.txt" ); foreach my $line (@errors) { chomp $line; my ( $tmp_id, $tmp_date, $tmp_username, $tmp_error, $tmp_board, $tmp_action ) = split /\|/xsm, $line; if ( !exists $FORM{"error$tmp_id"} ) { print {FILE} $line . "\n" or croak "$croak{'print'} FILE"; } } fclose(FILE); $yySetLocation = qq~$adminurl?action=errorlog~; redirectexit(); return; } # Moved here from Subs.pm since it was only used here sub YaBBsort { my $field = ( shift || 0 ) + 1; # 0-based field my $type = shift || 0; # 0=numeric; 1=text my $case = shift || 0; # 0=case sensitive; 1=ignore case my $dir = shift || 0; # 0=increasing; 1=decreasing if ( $type == 0 ) { if ( $dir == 0 ) { $a->[$field] <=> $b->[$field]; } else { $b->[$field] <=> $a->[$field]; } } else { if ( $case == 0 ) { if ( $dir == 0 ) { $a->[$field] cmp $b->[$field]; } else { $b->[$field] cmp $a->[$field]; } } else { if ( $dir == 0 ) { uc $a->[$field] cmp uc $b->[$field]; } else { uc $b->[$field] cmp uc $a->[$field]; } } } return 1; } sub update_htaccess { my ( $action, @values ) = @_; my ( $htheader, $htfooter, @denies, @htout ); if ( !$action ) { return 0; } fopen( HTA, '.htaccess' ); @htlines = ; fclose(HTA); # header to determine only who has access to the main script, not the admin script $htheader = q~~; $htfooter = q~~; $start = 0; foreach (@htlines) { chomp $_; if ( $_ eq $htheader ) { $start = 1; } if ( $start == 0 && $_ !~ m{#}sm && $_ ne q{} ) { push @htout, "$_\n"; } if ( $_ eq $htfooter ) { $start = 0; } if ( $start == 1 && $_ =~ s/Deny from //gsm ) { push @denies, $_; } } if ( $action eq 'load' ) { return @denies; } elsif ( $action eq 'save' ) { fopen( HTA, '>.htaccess' ); print {HTA} '# Last modified by YaBB: ' . timeformat( $date, 1 ) . " #\n\n" or croak "$croak{'print'} HTA"; print {HTA} @htout or croak "$croak{'print'} HTA"; if (@values) { print {HTA} "\n$htheader\n" or croak "$croak{'print'} HTA"; foreach (@values) { chomp $_; if ( $_ ne q{} ) { print {HTA} "Deny from $_\n" or croak "$croak{'print'} HTA"; } } print {HTA} "$htfooter\n" or croak "$croak{'print'} HTA"; } fclose(HTA); } elsif ( $action eq 'add' ) { push @denies, @values; update_htaccess( 'save', @denies ); } return; } sub blockip { is_admin_or_gmod(); my $blockIP = $INFO{'ip'}; update_htaccess( 'add', $blockIP ); $yySetLocation = qq~$adminurl?action=errorlog~; redirectexit(); return; } 1;