#!/usr/bin/perl --
# $Id: YaBB AdminIndex$
# $HeadURL: YaBB $
# $Source: /AdminIndex.pl $
###############################################################################
# AdminIndex.pl                                                               #
# $Date: 06.01.17 $                                                           #
###############################################################################
# YaBB: Yet another Bulletin Board                                            #
# Open-Source Community Software for Webmasters                               #
# Version:        YaBB 2.7.00                                                 #
# Packaged:       June 1, 2017                                                #
# Distributed by: http://www.yabbforumsoftware.com                                    #
# =========================================================================== #
# Copyright (c) 2000-2017 YaBB (www.yabbforumsoftware.com) - All Rights Reserved.     #
# Software by:  The YaBB Development Team                                     #
#               with assistance from the YaBB community.                      #
###############################################################################
use strict;
use warnings;
use CGI::Carp qw(fatalsToBrowser);
use English qw(-no_match_vars);
delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV' };
our $VERSION = '2.7.00';

### Version Info ###
our $yabbversion     = 'YaBB 2.7.00';
our $adminindexplver = 'YaBB 2.7.00 $Revision: 2059 $';

our @adminindexmods = ();
our $adminindexmods = 0;
if (@adminindexmods) {
    $adminindexmods = 1;
}

## language ##
our ( %admin_txt, %admintxt, %croak, %load_txt, %modulecheck, %yabmtxt );
## locations ##
our (
    $admindir,  $adminurl,  $boarddir,     $boardurl, $htmldir,
    $imagesdir, $scripturl, $templatesdir, $vardir,   $yyhtml_root
);
## settings ##
our (
    $accept_permafull, $debug,          $extendedprofiles, $lastbackup,
    $maintenance,      $maxadminlog,    $mbname,           $perm_domain,
    $referersecurity,  $rememberbackup, $sessions,         $symlink,
    $default_tz,       $enabletz,       $dynamic_clock,
);
## system ##
our (
    $action_area,      $allow_gmod_admin, $date,
    $iamadmin,         $iamgmod,          $iamguest,
    $max_process_time, $randaction,       $sessionvalid,
    $started_ul,       $uid,              $useimages,
    $user_ip,          $username,         $yyadmin_alert,
    $yydebug,          $yyext,            $yyjavascript,
    $yymain,           $yysetlocation,    $yytitle,
    %director,         %gmod_access,      %INFO,
    %mod_list,         $yyiis,            $year,
    $timeselected,
);
## template ##
our ( $admin_template, $header, $leftmenu, $leftmenubottom, $leftmenutop,
    $mainbody, $topnav );

## our Mod Hook ##

our $script_root = $ENV{'SCRIPT_FILENAME'};
if ( !$script_root ) {
    $script_root = $ENV{'PATH_TRANSLATED'};
}
$script_root =~ s/\/AdminIndex[.](pl|cgi)//igxsm;
push @INC, $script_root;
require Paths;
push @INC, "$boarddir/Modules";

if ( $ENV{'SERVER_SOFTWARE'} =~ /IIS/sm ) {
    my ($yypath);
    $yyiis = 1;
    if ( $PROGRAM_NAME =~ m{(.*)([\\/])}xsm ) {
        $yypath = $1;
    }
    $yypath =~ s/\\/\//gxsm;
    chdir $yypath;
    push @INC, $yypath;
}

my $adminscreen = 1;

our $yyexec      = 'YaBB';
my $yyaext = 'pl';
if   ( -e ("$yyexec.cgi") ) { $yyaext = 'cgi'; }
else                        { $yyaext = 'pl'; }
$adminurl = qq~$boardurl/AdminIndex.$yyaext~;

if ( -e "$vardir/backup.lock" ) {
    my $back_url = "$boardurl/BackupFix.$yyaext";
    print "Location: $back_url\n\n" or croak 'cannot print location';
    exit;
}
require Variables::Settings;

# Check always for Time::HiRes
if ( eval { require Time::HiRes; import Time::HiRes qw(time); } ) {
    require Time::HiRes;
    import Time::HiRes qw(time);
}
our $START_TIME = time;

require "$boarddir/Sources/Subs.pm";
require Sources::System;
require Sources::DateTime;
require Sources::Load;

load_cookie();          # Load the user's cookie (or set to guest)
load_usersettings();    # Load user settings
write_log();            # write into the logfile
what_template();        # Figure out which template to be using.
what_language();        # Figure out which language file we should be using!
get_micon();

if ($debug) { require Sources::Debug; }
if ($referersecurity) {
    referer_check();
}                       # Check if the action is allowed from an external domain

require Sources::Security;
banning();              # Check for banned people

if ( !$maintenance && -e "$vardir/maintenance.lock" ) { $maintenance = 2; }

# some maintenance stuff will stop after $max_process_time
# in seconds, than the browser will call the script again
# until all is done. Don't put it too high or you will run
# into server or browser timeout.
$max_process_time = 20;

our $action = $INFO{'action'};
local $SIG{__WARN__} = sub { fatal_error( 'error_occurred', "@_" ); };

if ( eval { yymaina(); } ) {
    yymaina();
}
elsif ($EVAL_ERROR) { fatal_error( 'untrapped', ":<br />$EVAL_ERROR" ); }

sub yymaina {

    # Choose what to do based on the form action
    if ( $maintenance && $action && $action eq 'login2' ) {
        require Sources::LogInOut;
        login2();
    }

    # Do Sessions Checking
    if ( !$iamguest && $sessions && $sessionvalid != 1 ) {
        $yysetlocation = qq~$scripturl?action=revalidatesession~;
        redirectexit();
    }

    # Other users can do nothing here.
    if ( !$iamadmin && !$iamgmod ) {
        if ($maintenance) { require Sources::LogInOut; in_maintenance(); }
        $yysetlocation = $scripturl;
        redirectexit();
    }

    if ($iamgmod) {
        require Variables::Gmodset;
        if ( !$allow_gmod_admin ) {
            $yysetlocation = $scripturl;
            redirectexit();
        }
    }

    if ($action) {
        if ( $action eq $randaction ) {
            require Sources::Decoder;
            convert();
        }
        else {
            require Admin::AdminSubList;
            if ( $director{$action} ) {
                my @act = split /&/xsm, $director{$action};
                if ( $act[0] =~ /^([-\@\w.]+)$/xsm ) {
                    $act[0] = $1;
                }
                require "$admindir/$act[0]";
                {
                    no strict qw(refs);
                    &{ $act[1] };
                }
            }
            else {
                require Admin::Admin;
                admin();
            }
        }
    }
    else {
        trackadminlogins();
        require Admin::Admin;
        admin();
    }
    return;
}

sub parsenavarray {
    my @x = @_;
    foreach my $element (@x) {
        chomp $element;
        my ( $action_to_take, $vistext, $whatitdoes, $isheader ) =
          split /[|]/xsm, $element;
        my $currentclass = q{};
        if ( $action_area && $action_area eq $action_to_take ) {
            $currentclass = 'class="current"';
        }
        else {
            $currentclass = q{};
        }

        if ($isheader) {
            $started_ul = 1;
            $leftmenu .= qq~
        <h3><a href="javascript:toggleList('$isheader')" title="$whatitdoes">$vistext</a></h3>
        <ul id="$isheader">~;
            next;
        }

        if ( $iamgmod && !$gmod_access{$action_to_take} ) {
            next;
        }

        if ( $action_to_take ne q{#} ) {
            $leftmenu .= qq~
            <li><a href="$adminurl?action=$action_to_take" title="$whatitdoes" $currentclass>$vistext</a></li>~;
        }
        else {
            $leftmenu .= qq~
            <li><a title="none">$vistext</a></li>~;
        }
    }

    if ($started_ul) {
        $leftmenu .= q~
        </ul>~;
    }
    return;
}

sub admimgloc {
    my ($img) = @_;
    my $thisimgloc = qq~img src="$imagesdir/$img"~;
    if ( !-e "$htmldir/Templates/Forum/$useimages/$img" ) {
        $thisimgloc = qq~img src="$yyhtml_root/Templates/Forum/default/$img"~;
    }
    else { $thisimgloc = qq~img src="$imagesdir/$img"~; }
    return $thisimgloc;
}

sub admimgloc2 {
    my ($img) = @_;
    my $thisimgloc = qq~$imagesdir/$img~;
    if ( !-e "$htmldir/Templates/Forum/$useimages/$img" ) {
        $thisimgloc = qq~$yyhtml_root/Templates/Forum/default/$img~;
    }
    else { $thisimgloc = qq~$imagesdir/$img~; }
    return $thisimgloc;
}

sub admintemplate {
    my $adminstyle =
qq~<link rel="stylesheet" href="$yyhtml_root/Templates/Admin/default.css" type="text/css" />~;

    my $adminimages = qq~$yyhtml_root/Templates/Admin/default~;
    require "$templatesdir/admin/AdminCentre.template";
    require Variables::Gmodset;

    my @forum_settings = (
        "|$admintxt{'a1_title'}|$admintxt{'a1_label'} - $admintxt{'34'}|a1",
        "newsettings;page=main|$admintxt{'a1_sub1'}|$admintxt{'a1_label1'}|",
"newsettings;page=advanced|$admintxt{'a1_sub2'}|$admintxt{'a1_label2'}|",
        "gmodaccess|$admintxt{'a2_sub5'}|$admintxt{'a2_label5'}|",
        "editpaths|$admintxt{'a1_sub3'}|$admintxt{'a1_label3'}|",
        "editbots|$admintxt{'a1_sub4'}|$admintxt{'a1_label4'}|",
    );
    if ($extendedprofiles) {
        splice @forum_settings, 3, 0,
          "ext_admin|$admintxt{'a1_sub_ex'}|$admintxt{'a1_label_ex'}|";
    }

    my @general_controls = (
        "|$admintxt{'a2_title'}|$admintxt{'a2_label'} - $admintxt{'34'}|a2",
        "newsettings;page=news|$admintxt{'a2_sub1'}|$admintxt{'a2_label1'}|",
        "smilies|$admintxt{'a2_sub2'}|$admintxt{'a2_label2'}|",
        "eventcal_set|$admintxt{'a2_sub6'}|$admintxt{'a2_label6'}|",
        "bookmarks|$admintxt{'bookmarks'}|$admintxt{'bookmarks1'}|",
        "setcensor|$admintxt{'a2_sub3'}|$admintxt{'a2_label3'}|",
        "modagreement|$admintxt{'a2_sub4'}|$admintxt{'a2_label4'}|",
        "helpadmin|$admintxt{'a4_sub3'}|$admintxt{'a4_label3'}|",
        "editemailtemplates|$admintxt{'a4_sub4'}|$admintxt{'a4_label4'}|",
    );

    my @security_settings = (
        "|$admintxt{'a3_title'}|$admintxt{'a3_label'} - $admintxt{'34'}|a3",
"newsettings;page=security|$admintxt{'a3_sub2'}|$admintxt{'a3_label2'}|",
        "setreserve|$admintxt{'a6_sub6'}|$admintxt{'a6_label6'}|",
        "referer_control|$admintxt{'a3_sub1'}|$admintxt{'a3_label1'}|",
        "setup_guardian|$admintxt{'a3_sub3'}|$admintxt{'a3_label3'}|",
"newsettings;page=antispam|$admintxt{'a3_sub4'}|$admintxt{'a3_label4'}|",
        "spam_questions|$admintxt{'a3_sub6'}|$admintxt{'a3_label6'}|",
    );

    my @forum_controls = (
        "|$admintxt{'a4_title'}|$admintxt{'a4_label'} - $admintxt{'34'}|a4",
        "managecats|$admintxt{'a4_sub1'}|$admintxt{'a4_label1'}|",
        "manageboards|$admintxt{'a4_sub2'}|$admintxt{'a4_label2'}|",
    );

    my @forum_layout = (
        "|$admintxt{'a5_title'}|$admintxt{'a5_label'} - $admintxt{'34'}|a5",
        "modskin|$admintxt{'a5_sub1'}|$admintxt{'a5_label1'}|",
        "modcss|$admintxt{'a5_sub2'}|$admintxt{'a5_label2'}|",
    );

    my @member_controls = (
        "|$admintxt{'a6_title'}|$admintxt{'a6_label'} - $admintxt{'34'}|a6",
        "addmember|$admintxt{'a6_sub1'}|$admintxt{'a6_label1'}|",
        "view_reglog|$admintxt{'a8_sub5'}|$admintxt{'a8_label5'}|",
        "viewmembers|$admintxt{'a6_sub2'}|$admintxt{'a6_label2'}|",
        "modmemgr|$admintxt{'a6_sub3'}|$admintxt{'a6_label3'}|",
        "mailinggrps|$admintxt{'a6_sub4'}|$admintxt{'a6_label4'}|",
        "ipban|$admintxt{'a6_sub5'}|$admintxt{'a6_label5'}|",
    );

    my @maintence_controls = (
        "|$admintxt{'a7_title'}|$admintxt{'a7_label'} - $admintxt{'34'}|a7",
        "newsettings;page=maintenance|$admin_txt{'67'}|$admin_txt{'67'}|",
        "backup|$admintxt{'a3_sub5'}|$admintxt{'a3_label5'}|",
        "rebuildmesindex|$admintxt{'a7_sub2a'}|$admintxt{'a7_label2a'}|",
        "deleteoldthreads|$admintxt{'a7_sub5'}|$admintxt{'a7_label5'}|",
        "boardrecount|$admintxt{'a7_sub2'}|$admintxt{'a7_label2'}|",
        "rebuildmemhist|$admintxt{'a7_sub4a'}|$admintxt{'a7_label4a'}|",
        "rebuildmemlist|$admintxt{'a7_sub4'}|$admintxt{'a7_label4'}|",
        "membershiprecount|$admintxt{'a7_sub3'}|$admintxt{'a7_label3'}|",
        "rebuildnotifications|$admintxt{'a7_sub4b'}|$admintxt{'a7_label4b'}|",
        "clean_log|$admintxt{'a7_sub1'}|$admintxt{'a7_label1'}|",
        "manageattachments|$admintxt{'a7_sub6'}|$admintxt{'a7_label6'}|",
    );

    my @forum_stats = (
        "|$admintxt{'a8_title'}|$admintxt{'a8_label'} - $admintxt{'34'}|a8",
        "detailedversion|$admintxt{'a8_sub1'}|$admintxt{'a8_label1'}|",
        "stats|$admintxt{'a8_sub2'}|$admintxt{'a8_label2'}|",
        "showclicks|$admintxt{'a8_sub3'}|$admintxt{'a8_label3'}|",
        "errorlog|$admintxt{'a8_sub4'}|$admintxt{'a8_label4'}|",
    );

    my @boardmod_mods = (
        "|$admintxt{'a9_title'}|$admintxt{'a9_label'} - $admintxt{'34'}|a9",
        "modlist|$mod_list{'6'}|$mod_list{'7'}|",
        "yabmmodlist|$mod_list{'20'}|$mod_list{'19'}|",
    );

    # To add new items for your mods settings, add a new row below here, pushing
    # your item onto the @boardmod_mods array. Example below:
    #     $my_mod = "action_to_take|Name_Displayed|Tooltip_Title|";
    #     push (@boardmod_mods, "$my_mod");
    # before the first pipe character is the action that will appear in the URL
    # Next is the text that is displayed in the admin centre
    # Finally, you have the tooltip text, necessary for XHTML compliance

    # Also note, you should pick a unique name instead of "$my_mod".
    # If you mod is called "SuperMod For Doing Cool Things"
    # You could use "$SuperMod_CoolThings"

### BOARDMOD ANCHOR ###
### END BOARDMOD ANCHOR ###

    parsenavarray(@member_controls);
    parsenavarray(@maintence_controls);
    parsenavarray(@forum_settings);
    parsenavarray(@general_controls);
    parsenavarray(@security_settings);
    parsenavarray(@forum_controls);
    parsenavarray(@forum_layout);
    parsenavarray(@forum_stats);
    parsenavarray(@boardmod_mods);
    my $boardlink = qq~$boardurl/$yyexec.$yyext~;

    if ($accept_permafull) {
        $boardlink = qq~$perm_domain/$symlink/~;
    }
    my $topmenu_one = qq~<a href="$boardlink">$admintxt{'15'} $mbname</a>~;
    my $topmenu_two = qq~<a href="$adminurl">$admintxt{'33'}</a>~;
    my $topmenu_tree =
      qq~<a href="$scripturl?action=help;section=admin">$admintxt{'35'}</a>~;
    my $topmenu_four =
qq~<a href="http://www.yabbforumsoftware.com" target="_blank">$admintxt{'36'}</a>~;
    my $topmenu_five =
qq~<a href="$boardurl/$yyexec.$yyext?action=mycenter" target="_blank">$admin_txt{'usercp'}</a> ~;
    {
        no strict qw(refs);
        my $realname = ${ $uid . $username }{'realname'} || 'Administrator';
        $topmenu_five =~ s/USER/$realname/xsm;
    }
    my $yytime        = q{};
    my $yyjavascripta = q{};
    if ( $action ne 'detailedversion' ) {
        if ($maintenance) {
            $yyadmin_alert .=
qq~<br /><span style="font-size: 12px; background-color: #FFFF33;"><b>$load_txt{'616a'}</b></span><br /><br />~;
        }
        if ( $iamadmin && $rememberbackup && $action ne 'detailedversion' ) {
            if ( $lastbackup && $date > $rememberbackup + $lastbackup ) {
                require Sources::DateTime;
                $yyadmin_alert .=
qq~<br /><span style="font-size: 12px; background-color: #FFFF33;"><b>$load_txt{'617'} ~
                  . timeformat($lastbackup)
                  . q~</b></span>~;
            }
        }
        $yytime = timeformat( $date, 1 );
        my $zone = q{};
        {
            no strict qw(refs);
            my $mytimeselected = ${ $uid . $username }{'timeselect'} || 'UTC';
            if (
                ( !$enabletz && $default_tz eq 'UTC' )
                || (   $enabletz
                    && ${ $uid . $username }{'user_tz'}
                    && ${ $uid . $username }{'user_tz'} eq 'UTC' )
                || ( !$default_tz && !${ $uid . $username }{'user_tz'} )
              )
            {
                $zone = qq~ $admin_txt{'UTC'} ~;
            }
            my $toffs = toffs($date);
            if ( $dynamic_clock && ${ $uid . $username }{'dynamic_clock'} ) {
                my ( $aa, $bb );
                if ( $yytime =~ /(.*?)\d+:\d+((\w+)|:\d+)?/xsm ) {
                    ( $aa, $bb ) = ( $1, $3 );
                }
                $aa =~ s/<.+?>//gxsm;
                if ( !$bb ) { $bb = q{ }; }
                $yytime =
qq~&nbsp;<script type="text/javascript">\nWriteClock('yabbclock','$aa','$bb');\n</script>~;
                $yyjavascripta .= q~
        var OurTime = ~
                  . sprintf( '%d', ( $date + $toffs ) )
                  . qq~000;\n        var YaBBTime = new Date();\n        var TimeDif = YaBBTime.getTime() - (YaBBTime.getTimezoneOffset() * 60000) - OurTime - 1000; // - 1000 compromise to transmission time~;
            }
        }
        $yytime .= $zone;
    }

    $yyadmin_alert ||= q{};
    $yytitle = qq~$mbname $admin_txt{'208'}: $yytitle~;
    $header =~ s/\Q{yabb title}\E/$yytitle/gxsm;
    $header =~ s/\Q{yabb style}\E/$adminstyle/gxsm;
    $header =~ s/\Q{yabb javascript}\E/$yyjavascript/gxsm;
    $header =~ s/\Q{yabb javascripta}\E/$yyjavascripta/gxsm;

    $leftmenutop =~ s/\Q{yabb images}\E/$adminimages/gxsm;
    $leftmenutop =~ s/\Q{yabb maintenance}\E/$yyadmin_alert/gxsm;
    $leftmenutop =~ s/\Q{yabb time}\E/$yytime/gxsm;
    $topnav =~ s/\Q{yabb topmenu_one}\E/$topmenu_one/xsm;
    $topnav =~ s/\Q{yabb topmenu_two}\E/$topmenu_two/xsm;
    $topnav =~ s/\Q{yabb topmenu_tree}\E/$topmenu_tree/xsm;
    $topnav =~ s/\Q{yabb topmenu_four}\E/$topmenu_four/xsm;
    $topnav =~ s/\Q{yabb topmenu_five}\E/$topmenu_five/xsm;
    $topnav =~ s/\Q{yabb brdname}\E/$mbname/xsm;

    if ($debug) { debug(); }
    $yydebug ||= q{};
    $mainbody =~ s/\Q{yabb main}\E/$yymain/gxsm;
    $mainbody =~ s/\Q{yabb_admin debug}\E/$yydebug/gxsm;

    $mainbody =~ s/img src\=\"$imagesdir\/(.+?)\"/admimgloc($1)/eigxsm;
    $mainbody =~
s/img src\=\&quot;$imagesdir\/(.+?)\&quot;/"img src\=\&quot;" . admimgloc2($1) . "\&quot;"/eigxsm;
    $mainbody =~ s/\Q{yabb scripturl}\E/$scripturl/gxsm;
    $mainbody =~ s/\Q{yabb admintxt_35}\E/$admintxt{'35'}/gxsm;

    # For the template editing Javascript images

    print_output_header();
    our $output =
        $header
      . $leftmenutop
      . $leftmenu
      . $leftmenubottom
      . $topnav
      . $mainbody;
    $output =~ s/\Q{yabb adminurl}\E/$adminurl/gxsm;
    image_resize();
    $output =~ s/\Q{yabb mbname}/$mbname/gxsm;
    $output =~ s/\Q{yabb year}/$year/gxsm;

    print_html_output_and_finish();
    return;
}

sub trackadminlogins {
    my @adminlog;
    if ( -e "$vardir/adminlog.log" ) {
        open my $ADMINLOG, '<', "$vardir/adminlog.log"
          or croak "cannot open $vardir/adminlog.log";
        @adminlog = <$ADMINLOG>;
        close $ADMINLOG or croak "cannot close $vardir/adminlog.log";
        @adminlog = reverse sort @adminlog;
    }
    $maxadminlog ||= 5;
    my $adminlog = qq~$date|$username|$user_ip\n~;
    foreach my $i ( 0 .. ( $maxadminlog - 2 ) ) {
        if ( $adminlog[$i] ) {
            chomp $adminlog[$i];
            $adminlog .= qq~$adminlog[$i]\n~;
        }
    }
    open my $ADMINLOG, '>', "$vardir/adminlog.log"
      or croak "cannot open $vardir/adminlog.log";
    print {$ADMINLOG} $adminlog or croak 'cannot print ADMINLOG';
    close $ADMINLOG or croak "cannot close $vardir/adminlog.log";
    return;
}

1;
