F:\WEBSITES\testbed\zipped\yabb_svn_new\branches\2.5.2\cgi-bin\yabb2\Admin\Maintenance.pl F:\WEBSITES\testbed\zipped\yabb_svn_new\trunk\cgi-bin\yabb2\Admin\Maintenance.pm
############################################################################### ###############################################################################
# Maintenance.pl                                                              # # Maintenance.pm                                                              #
  # $Date: 01.05.16 $                                                           #
############################################################################### ###############################################################################
# YaBB: Yet another Bulletin Board                                            # # YaBB: Yet another Bulletin Board                                            #
# Open-Source Community Software for Webmasters                               # # Open-Source Community Software for Webmasters                               #
# Version:        YaBB 2.5.2                                                  # # Version:        YaBB 2.6.12                                                 #
# Packaged:       October 21, 2012                                            # # Packaged:       January 5, 2016                                             #
# Distributed by: http://www.yabbforum.com                                    # # Distributed by: http://www.yabbforum.com                                    #
# =========================================================================== # # =========================================================================== #
# Copyright (c) 2000-2012 YaBB (www.yabbforum.com) - All Rights Reserved.     # # Copyright (c) 2000-2016 YaBB (www.yabbforum.com) - All Rights Reserved.     #
# Software by:  The YaBB Development Team                                     # # Software by:  The YaBB Development Team                                     #
#               with assistance from the YaBB community.                      # #               with assistance from the YaBB community.                      #
############################################################################### ###############################################################################
  use CGI::Carp qw(fatalsToBrowser);
  our $VERSION = '2.6.12';
   
$maintenanceplver = 'YaBB 2.5.2 $Revision: 1.0 $'; $maintenancepmver = 'YaBB 2.6.12 $Revision: 1710 $';
if ($action eq 'detailedversion') { return 1; } if ( $action eq 'detailedversion' ) { return 1; }
   
sub RebuildMessageIndex { sub RebuildMessageIndex {
   &is_admin_or_gmod();     is_admin_or_gmod(); 
   
   # Set up the multi-step action    # Set up the multi-step action
   $time_to_jump = time() + $max_process_time;    $time_to_jump = time() + $max_process_time;
   
   require "$boardsdir/forum.master";    require "$boardsdir/forum.master";
   
   my %rebuildboards;    my %rebuildboards;
   if (!$INFO{'rebuild'}) {    if ( !$INFO{'rebuild'} ) {
       $yymain .= qq~<b>$admin_txt{'530'}</b>        $yymain .= qq~<b>$admin_txt{'530'}</b>
       <a href="$adminurl?action=rebuildmesindex;rebuild=1"><b>$admin_txt{'531'}</b></a><br />        <a href="$adminurl?action=rebuildmesindex;rebuild=1"><b>$admin_txt{'531'}</b></a><br />
       ($admin_txt{'532'} $max_process_time $admin_txt{'533'}.)~;        ($admin_txt{'532'} $max_process_time $admin_txt{'533'}.)~;
       $yytitle = $admin_txt{'506'};        $yytitle     = $admin_txt{'506'};
       $action_area = 'rebuildmesindex';        $action_area = 'rebuildmesindex';
       &AdminTemplate;         AdminTemplate(); 
   
   # delete old rebuldings when starting or if maintenance mode was 'off'        # delete old rebuldings when starting or if maintenance mode was 'off'
   } elsif (!-e "$vardir/maintenance.lock" || (!$INFO{'next'} && $INFO{'rebuild'} == 1)) {     } 
       opendir(BOARDSDIR, $boardsdir) || &admin_fatal_error('cannot_open', "$boardsdir", 1);     elsif ( !-e "$vardir/maintenance.lock" 
       my @blist = grep { /\.tmp$/ } readdir(BOARDSDIR);         || ( !$INFO{'next'} && $INFO{'rebuild'} == 1 ) ) 
       closedir(BOARDSDIR);     { 
         opendir( BOARDSDIR, $boardsdir )
       foreach (@blist) { unlink "$boardsdir/$_"; }           || fatal_error( 'cannot_open', "$boardsdir", 1 ); 
         my @blist = grep { /\.tmp$/xsm } readdir BOARDSDIR;
       foreach (keys %board) { push(@{$rebuildboards{$_}}, ''); }         closedir BOARDSDIR; 
   
       &automaintenance('on');         foreach (@blist) { unlink "$boardsdir/$_"; } 
   }  
         foreach ( keys %board ) { push @{ $rebuildboards{$_} }, q{}; }
   if ($INFO{'rebuild'} == 1) {  
       require "$admindir/Attachments.pl";         automaintenance('on'); 
       my %attachfile;     } 
   
       # storing the 'board' and the 'status' of all threads     if ( $INFO{'rebuild'} == 1 ) { 
       foreach $oldboard (keys %board) {         require Admin::Attachments; 
           my @temparray;         my %attachfile; 
           fopen(OLDBOARD, "$boardsdir/$oldboard.txt") || &admin_fatal_error('cannot_open', "$boardsdir/$oldboard.txt", 1);  
           my @temparray = <OLDBOARD>;         # storing the 'board' and the 'status' of all threads 
           fclose(OLDBOARD);         foreach my $oldboard ( keys %board ) { 
           chomp(@temparray);             fopen( OLDBOARD, "$boardsdir/$oldboard.txt" ) 
               || fatal_error( 'cannot_open', "$boardsdir/$oldboard.txt",
           foreach (@temparray) {                 1 ); 
               ($mnum, undef, undef, undef, undef, undef, undef, undef, $mstate) = split(/\|/, $_);             my @temparray = <OLDBOARD>; 
               $thread_status{$mnum} = $mstate ? $mstate : "0";             fclose(OLDBOARD); 
               $thread_boards{$mnum} = $oldboard;             chomp @temparray; 
           }  
       }             foreach (@temparray) { 
                 (
       opendir(TXT, $datadir) || &admin_fatal_error('cannot_open', "$datadir", 1);                     $mnum, undef, undef, undef, undef, 
       my @threadlist = sort( grep { /\d+\.txt$/ } readdir(TXT) );                     undef, undef, undef, $mstate 
       closedir(TXT);                 ) = split /\|/xsm, $_; 
                 $thread_status{$mnum} = $mstate ? $mstate : '0';
       $totalthreads = @threadlist;                 $thread_boards{$mnum} = $oldboard; 
       for (my $j = ($INFO{'next'} || 0); $j < $totalthreads; $j++) {             } 
           $thread = $threadlist[$j];         } 
           $thread =~ s/\.txt$//;  
         opendir( TXT, $datadir )
           if ($thread eq '' || !-e "$datadir/$thread.txt" || -s "$datadir/$thread.txt" < 35) {           || fatal_error( 'cannot_open', "$datadir", 1 ); 
               unlink("$datadir/$thread.txt");         my @threadlist = sort grep { /\d+\.txt$/xsm } readdir TXT; 
               unlink("$datadir/$thread.ctb");         closedir TXT; 
               unlink("$datadir/$thread.mail");  
               unlink("$datadir/$thread.poll");         $totalthreads = @threadlist; 
               unlink("$datadir/$thread.polled");         for my $j ( ( $INFO{'next'} || 0 ) .. ( $totalthreads - 1 ) ) { 
               $attachfile{$thread} = undef;             $thread = $threadlist[$j]; 
               $INFO{'count_del_threads'}++;             $thread =~ s/\.txt$//xsm; 
               next;  
           }             if (   $thread eq q{} 
                 || !-e "$datadir/$thread.txt" 
           if (!-e "$datadir/$thread.ctb") {                 || ( -s "$datadir/$thread.txt" ) < 35 ) 
               ${$thread}{'board'} = '';             { 
           } else {                 unlink "$datadir/$thread.txt"; 
               # &MessageTotals("load", $thread) not used here                 unlink "$datadir/$thread.ctb"; 
               # for upgraders form 2-2.1 to the actual version.                 unlink "$datadir/$thread.mail"; 
               fopen(CTB, "$datadir/$thread.ctb",1);                 unlink "$datadir/$thread.poll"; 
               my @ctb = <CTB>;                 unlink "$datadir/$thread.polled"; 
               fclose(CTB);                 $attachfile{$thread} = undef; 
               if ($ctb[0] =~ /###/) { # new format                 $INFO{'count_del_threads'}++; 
                   foreach (@ctb) {                 next; 
                       if ($_ =~ /^'(.*?)',"(.*?)"/) { ${$thread}{$1} = $2; }            }
                   }  
                   @repliers = split(",", ${$thread}{'repliers'});             if ( !-e "$datadir/$thread.ctb" ) { 
               } else {                # old format                 ${$thread}{'board'} = q{}; 
                   chomp(@ctb);             } 
                   my @tag = qw(board replies views lastposter lastpostdate threadstatus repliers);             else { 
                   for (my $cnt = 0; 7 > $cnt; $cnt++) {  
                       ${$thread}{$tag[$cnt]} = $ctb[$cnt];                 # &MessageTotals("load", $thread) not used here 
                   }                 # for upgraders from 2-2.1 to the actual version. 
                   @repliers = ();                 fopen( CTB, "$datadir/$thread.ctb", 1 ); 
                   for (my $repcnt = 7; @ctb > $repcnt ; $repcnt++) {                 my @ctb = <CTB>; 
                       push(@repliers, $ctb[$repcnt]);                 fclose(CTB); 
                   }                 for (@ctb) { 
               }                        if ( $_ =~ /^'(.*?)',"(.*?)"/xsm ) { ${$thread}{$1} = $2; }
           }                    }
                     @repliers = split /\,/xsm, ${$thread}{'repliers'};
           # set correct board                 } 
           $theboard = exists $thread_boards{$thread} ? $thread_boards{$thread} : ${$thread}{'board'};  
           # if boardname is wrong - > put to recycle             # set correct board 
           if (!exists $board{$theboard}) {             $theboard = 
               if ($binboard) {               exists $thread_boards{$thread} 
                   $theboard = $binboard;               ? $thread_boards{$thread} 
               } else {               : ${$thread}{'board'}; 
                   unlink("$datadir/$thread.txt");  
                   unlink("$datadir/$thread.ctb");             # if boardname is wrong - > put to recycle 
                   unlink("$datadir/$thread.mail");             if ( !exists $board{$theboard} ) { 
                   unlink("$datadir/$thread.poll");                 if ($binboard) { 
                   unlink("$datadir/$thread.polled");                     $theboard = $binboard; 
                   $attachfile{$thread} = undef;                 } 
                   $INFO{'count_del_threads'}++;                 else { 
                   next;                     unlink "$datadir/$thread.txt"; 
               }                     unlink "$datadir/$thread.ctb"; 
           }                     unlink "$datadir/$thread.mail"; 
                     unlink "$datadir/$thread.poll";
           fopen(FILETXT, "$datadir/$thread.txt") || &admin_fatal_error('cannot_open', "$datadir/$thread.txt", 1);                     unlink "$datadir/$thread.polled"; 
           my @threaddata = <FILETXT>;                     $attachfile{$thread} = undef; 
           fclose(FILETXT);                     $INFO{'count_del_threads'}++; 
                     next;
           @firstinfo = split(/\|/, $threaddata[0]);                 } 
           @lastinfo = split(/\|/, $threaddata[$#threaddata]);             } 
           $lastpostdate = sprintf("%010d", $lastinfo[3]);  
             fopen( FILETXT, "$datadir/$thread.txt" )
           # rewrite/create a correct threadnumber.ctb               || fatal_error( 'cannot_open', "$datadir/$thread.txt", 1 ); 
           ${$thread}{'board'} = $theboard;             my @threaddata = <FILETXT>; 
           ${$thread}{'replies'} = $#threaddata;             fclose(FILETXT); 
           ${$thread}{'views'} = ${$thread}{'views'} || 1; # is never = 0 !  
           ${$thread}{'lastposter'} = $lastinfo[4] eq 'Guest' ? qq~Guest-$lastinfo[1]~ : $lastinfo[4];             @firstinfo = split /\|/xsm, $threaddata[0]; 
           ${$thread}{'lastpostdate'} = $lastpostdate;             @lastinfo  = split /\|/xsm, $threaddata[-1]; 
           ${$thread}{'threadstatus'} = $thread_status{$thread};             $lastpostdate = sprintf '%010d', $lastinfo[3]; 
           &MessageTotals("update", $thread);  
             # rewrite/create a correct threadnumber.ctb
           push(@{$rebuildboards{$theboard}}, qq~$lastpostdate|$thread|$firstinfo[0]|$firstinfo[1]|$firstinfo[2]|$lastinfo[3]|$#threaddata|$firstinfo[4]|$firstinfo[5]|$thread_status{$thread}\n~);             ${$thread}{'board'}   = $theboard; 
             ${$thread}{'replies'} = $#threaddata;
           if (time() > $time_to_jump && ($j + 1) < $totalthreads) {             ${$thread}{'views'}   = ${$thread}{'views'} || 1;   # is never = 0 ! 
               foreach (keys %rebuildboards) {             ${$thread}{'lastposter'} = 
                   fopen(REBBOARD, ">>$boardsdir/$_.tmp") || &admin_fatal_error('cannot_open', "$boardsdir/$_.tmp", 1);               $lastinfo[4] eq 'Guest' ? qq~Guest-$lastinfo[1]~ : $lastinfo[4]; 
                   print REBBOARD @{$rebuildboards{$_}};             ${$thread}{'lastpostdate'} = $lastpostdate; 
                   fclose(REBBOARD);             ${$thread}{'threadstatus'} = $thread_status{$thread}; 
               }             MessageTotals( 'update', $thread ); 
   
               &RemoveAttachments(\%attachfile);             push 
                 @{ $rebuildboards{$theboard} },
               &RebuildMessageIndexText($INFO{'rebuild'},$j,$totalthreads);  qq~$lastpostdate|$thread|$firstinfo[0]|$firstinfo[1]|$firstinfo[2]|$lastinfo[3]|$#threaddata|$firstinfo[4]|$firstinfo[5]|$thread_status{$thread}\n~; 
           }  
       }             if ( time() > $time_to_jump && ( $j + 1 ) < $totalthreads ) { 
                 foreach ( keys %rebuildboards ) {
       foreach (keys %rebuildboards) {                     fopen( REBBOARD, ">>$boardsdir/$_.tmp" ) 
           fopen(REBBOARD, ">>$boardsdir/$_.tmp") || &admin_fatal_error('cannot_open', "$boardsdir/$_.tmp", 1);                       || fatal_error( 'cannot_open', "$boardsdir/$_.tmp", 
           print REBBOARD @{$rebuildboards{$_}};                         1 ); 
           fclose(REBBOARD);                     print {REBBOARD} @{ $rebuildboards{$_} } 
       }                       or croak "$croak{'print'} REBBOARD"; 
                     fclose(REBBOARD);
       &RemoveAttachments(\%attachfile);                 } 
   
       $INFO{'next'} = 0;                 RemoveAttachments( \%attachfile ); 
       $INFO{'rebuild'} = 2;  
   }                 RebuildMessageIndexText( $INFO{'rebuild'}, $j, $totalthreads ); 
             }
   if ($INFO{'rebuild'} == 2) {         } 
       opendir(REBUILDS, $boardsdir);  
       my @rebuilds = sort( grep(/\.tmp$/, readdir(REBUILDS)) );         foreach ( keys %rebuildboards ) { 
       closedir(REBUILDS);             fopen( REBBOARD, ">>$boardsdir/$_.tmp" ) 
               || fatal_error( 'cannot_open', "$boardsdir/$_.tmp", 1 );
       $totalrebuilds = @rebuilds;             print {REBBOARD} @{ $rebuildboards{$_} } 
       for(my $j = 0; $j < $totalrebuilds; $j++) {               or croak "$croak{'print'} REBBOARD"; 
           my $boardname = $rebuilds[$j];             fclose(REBBOARD); 
           $boardname =~ s/\.tmp$//;         } 
   
           fopen(FILETXT, "$boardsdir/$boardname.tmp") || &admin_fatal_error('cannot_open', "$boardsdir/$boardname.tmp", 1);         RemoveAttachments( \%attachfile ); 
           my @tempboard = <FILETXT>;  
           fclose(FILETXT);         $INFO{'next'}    = 0; 
         $INFO{'rebuild'} = 2;
           fopen(NEWBOARD, ">$boardsdir/$boardname.txt") || &admin_fatal_error('cannot_open', "$boardsdir/$boardname.txt", 1);     } 
           print NEWBOARD map({ s/^.*?\|//; $_; } sort({ lc($b) cmp lc($a) } @tempboard) );  
           fclose(NEWBOARD);     if ( $INFO{'rebuild'} == 2 ) { 
         opendir REBUILDS, $boardsdir;
           unlink "$boardsdir/$boardname.tmp";         my @rebuilds = sort grep {/\.tmp$/xsm} readdir REBUILDS; 
         closedir REBUILDS;
           if (time() > $time_to_jump && ($j + 1) < $totalrebuilds) {  
               &RebuildMessageIndexText($INFO{'rebuild'},-1,$totalrebuilds);         $totalrebuilds = @rebuilds; 
           }         for my $j ( 0 .. ( $totalrebuilds - 1 ) ) { 
       }             my $boardname = $rebuilds[$j]; 
   }             $boardname =~ s/\.tmp$//xsm; 
   
   &RebuildMessageIndexText(3,0,0) if $INFO{'rebuild'} < 3;             fopen( FILETXT, "$boardsdir/$boardname.tmp" ) 
               || fatal_error( 'cannot_open', "$boardsdir/$boardname.tmp",
   foreach (keys %board) { &BoardCountTotals($_); }                 1 ); 
             my @tempboard = <FILETXT>;
   # remove from movedthreads.cgi only if it's the final thread             fclose(FILETXT); 
   # then look backwards to delete the other entries in  
   # the Moved-Info-row if their files were deleted             fopen( NEWBOARD, ">$boardsdir/$boardname.txt" ) 
   eval { require "$datadir/movedthreads.cgi" };               || fatal_error( 'cannot_open', "$boardsdir/$boardname.txt", 
   my $save_moved;                 1 ); 
   foreach my $th (keys %moved_file) {            print {NEWBOARD} map {
       if (exists $moved_file{$th}) { # 'exists' because may be deleted in &moved_loop                     s/^.*?\|//xsm; 
           while (exists $moved_file{$th}) { # to get the final/last thread                       $_; 
               $th = $moved_file{$th};                 } reverse sort { lc($a) cmp lc $b } @tempboard 
           }               or croak "$croak{'print'} NEWBOARD"; 
           unless (-e "$datadir/$th.txt") { &moved_loop($th); }             fclose(NEWBOARD); 
       }  
   }             unlink "$boardsdir/$boardname.tmp"; 
   sub moved_loop {  
       my $th = shift;             if ( time() > $time_to_jump && ( $j + 1 ) < $totalrebuilds ) { 
       foreach (keys %moved_file) {                 RebuildMessageIndexText( $INFO{'rebuild'}, -1, $totalrebuilds ); 
           if (exists $moved_file{$_} && $moved_file{$_} == $th && !-e "$datadir/$th.txt") {             } 
               delete $moved_file{$_};         } 
               $save_moved = 1;     } 
               &moved_loop($_);  
           }    if ( $INFO{'rebuild'} < 3 ) { RebuildMessageIndexText( 3, 0, 0 ); }
       }  
   }    foreach ( keys %board ) { BoardCountTotals($_); }
   &save_moved_file if $save_moved;  
     # remove from Movedthreads.pm only if it's the final thread
   &automaintenance('off');     # then look backwards to delete the other entries in 
   $yymain .= qq~<b>$admin_txt{'507'}</b>~;     # the Moved-Info-row if their files were deleted 
   $yytitle = $admin_txt{'506'};     eval { require Variables::Movedthreads }; 
   $action_area = 'rebuildmesindex';     my $save_moved; 
   &AdminTemplate;     *moved_loop = sub { 
         my $th = shift;
         foreach ( keys %moved_file ) {
             if (   exists $moved_file{$_}
                 && $moved_file{$_} == $th
                 && !-e "$datadir/$th.txt" )
             {
                 delete $moved_file{$_};
                 $save_moved = 1;
                 moved_loop($_);
             }
         }
     };
   
     foreach my $th ( keys %moved_file ) {
         if ( exists $moved_file{$th} )
         {    # 'exists' because may be deleted in &moved_loop
             while ( exists $moved_file{$th} ) {   # to get the final/last thread
                 $th = $moved_file{$th};
             }
             if ( !-e "$datadir/$th.txt" ) { moved_loop($th); }
         }
     }
     if ($save_moved) { save_moved_file(); }
   
  ## New forum.totals rebuild ##
     my @newtots = ();
     my @myline1 = ();
     while( ($key, $value) = each %board ) {
         $ftotals = 0;
         fopen ( TOTALS, "<$boardsdir/$key.txt" );
         my @ftotals = <TOTALS>;
         fclose(TOTALS);
         chomp @ftotals;
         $ftotals = @ftotals;
         if ( !$ftotals ) {
             $msgtot = 0;
             $myline1[4] = 'N/A';
             $myline1[0] = q{};
             $myline1[5] = q{};
             $myline1[7]= q{};
             $mesg[0] = q{};
             $messby = 'N/A';
             $msgts = 0;
         }
         else {
             @myline1 = split /[|]/xsm, $ftotals[0];
             $msgtot = 0;
             $msgts = $myline1[8];
             for (@ftotals) {
                 @totalsvars = split /[|]/xsm, $_;
                 $msgtot += $totalsvars[5] + 1;
             }
             fopen ( TOTALSN, "<$datadir/$myline1[0].txt" );
             my @ftotalsn = <TOTALSN>;
             fclose(TOTALSN);
             @mesg =  split /[|]/xsm, $ftotalsn[-1];
             $messby = $myline1[6];
             if ( $messby eq 'Guest') {
                 $messby = $myline1[2];
             }
         }
         push @newtots, qq~$key|$ftotals|$msgtot|$myline1[4]|$messby|$myline1[0]|$myline1[5]|$mesg[0]|$myline1[7]|$msgts\n~;
     }
     fopen ( NTOTALS, ">$boardsdir/forum.totals" );
     print {NTOTALS} @newtots;
     fclose(NTOTALS);
   
     automaintenance('off');
     $yymain .= qq~<b>$admin_txt{'507'}</b>~;
     $yytitle     = $admin_txt{'506'};
     $action_area = 'rebuildmesindex';
     AdminTemplate();
     return;
} }
   
sub RebuildMessageIndexText { sub RebuildMessageIndexText {
   my ($part,$j,$total) = @_;    my ( $part, $j, $total ) = @_;
   
   $j++;    $j++;
   $INFO{'st'} = int($INFO{'st'} + time() - $time_to_jump + $max_process_time);     $INFO{'st'} = 
       int( $INFO{'st'} + time() - $time_to_jump + $max_process_time );
   $yymain .= qq~<b>$admin_txt{'534'} <i>$max_process_time $admin_txt{'533'}</i>.<br />  
   $admin_txt{'535'} <i>~ . (time() - $time_to_jump + $max_process_time) . qq~ $admin_txt{'533'}</i>.<br />     $yymain .= 
   $admin_txt{'536'} <i>~ . int(($INFO{'st'} + 60)/60) . qq~ $admin_txt{'537'}</i>.<br />      qq~<b>$admin_txt{'534'} <i>$max_process_time $admin_txt{'533'}</i>.<br />
   <br />~;     $admin_txt{'535'} <i>~ 
   $yymain .= qq~$INFO{'count_del_threads'} $admin_txt{'538'}.<br />       . ( time() - $time_to_jump + $max_process_time ) 
   <br />~ if $INFO{'count_del_threads'};       . qq~ $admin_txt{'533'}</i>.<br /> 
     $admin_txt{'536'} <i>~
       . int( ( $INFO{'st'} + 60 ) / 60 ) . qq~ $admin_txt{'537'}</i>.<br />
   if ($part == 1) {     <br />~; 
       $yymain .= qq~$j/$total $admin_txt{'539'}~;     if ( $INFO{'count_del_threads'} ) { 
   } elsif ($part == 2) {         $yymain .= qq~$INFO{'count_del_threads'} $admin_txt{'538'}.<br /> 
       $yymain .= qq~$j/$total $admin_txt{'540'}~;     <br />~; 
   } else {     } 
       $yymain .= $admin_txt{'541'};  
   }     if ( $part == 1 ) { 
         $yymain .= qq~$j/$total $admin_txt{'539'}~;
   $yymain .= qq~</b>     } 
   <p id="memcontinued">$admin_txt{'542'} <a href="$adminurl?action=rebuildmesindex;rebuild=$part;st=$INFO{'st'};next=$j;count_del_threads=$INFO{'count_del_threads'}" onclick="PleaseWait();">$admin_txt{'543'}</a>...<br />$admin_txt{'544'}     elsif ( $part == 2 ) { 
   </p>         $yymain .= qq~$j/$total $admin_txt{'540'}~; 
     }
   <script type="text/javascript">     else { 
    <!--         $yymain .= $admin_txt{'541'}; 
       function PleaseWait() {     } 
           document.getElementById("memcontinued").innerHTML = '<font color="red"><b>$admin_txt{'545'}</b></font><br />&nbsp;<br />&nbsp;';  
       }     $yymain .= qq~</b> 
     <p id="memcontinued">$admin_txt{'542'} <a href="$adminurl?action=rebuildmesindex;rebuild=$part;st=$INFO{'st'};next=$j;count_del_threads=$INFO{'count_del_threads'}" onclick="PleaseWait();">$admin_txt{'543'}</a>...<br />$admin_txt{'544'}
       function stoptick() { stop = 1; }     </p> 
   
       stop = 0;     <script type="text/javascript"> 
       function membtick() {        function PleaseWait() {
           if (stop != 1) {             document.getElementById("memcontinued").innerHTML = '<span class="important"><b>$admin_txt{'545'}</b></span><br />&nbsp;<br />&nbsp;'; 
               PleaseWait();         } 
               location.href="$adminurl?action=rebuildmesindex;rebuild=$part;st=$INFO{'st'};next=$j;count_del_threads=$INFO{'count_del_threads'}";  
           }        function stoptick() { stop = 1; }
       }  
         stop = 0;
       setTimeout("membtick()",2000);         function membtick() { 
    // -->             if (stop != 1) { 
   </script>~;                 PleaseWait(); 
                 location.href="$adminurl?action=rebuildmesindex;rebuild=$part;st=$INFO{'st'};next=$j;count_del_threads=$INFO{'count_del_threads'}";
           $yytitle = $admin_txt{'506'};             } 
           $action_area = 'rebuildmesindex';         } 
           &AdminTemplate;  
         setTimeout("membtick()",2000);
     </script>~;
   
     $yytitle     = $admin_txt{'506'};
     $action_area = 'rebuildmesindex';
     AdminTemplate();
     return;
} }
   
sub AdminBoardRecount { sub AdminBoardRecount {
   &is_admin_or_gmod();     is_admin_or_gmod(); 
   &automaintenance('on');     automaintenance('on'); 
   
   $action_area = 'boardrecount';    $action_area = 'boardrecount';
   $yytitle = $admin_txt{'502'};    $yytitle     = $admin_txt{'502'};
   
   # Set up the multi-step action    # Set up the multi-step action
   $begin_time = time();     $begin_time = time; 
   $topicnum = $INFO{'topicnum'} || 0;    $topicnum = $INFO{'topicnum'} || 0;
   
   if (!$INFO{'tnext'}) {    if ( !$INFO{'tnext'} ) {
       # Get the thread list  
       opendir(TXT, $datadir);         # Get the thread list 
       @topiclist = sort( grep { /^\d+\.txt$/ } readdir(TXT) );         opendir TXT, $datadir; 
       closedir(TXT);         @topiclist = sort grep { /^\d+\.txt$/xsm } readdir TXT; 
         closedir TXT;
       for ($i = $topicnum; $i < @topiclist; $i++) {  
           ($filename, undef) = split(/\./, $topiclist[$i]);         for my $i ( $topicnum .. ( @topiclist - 1 ) ) { 
             ( $filename, undef ) = split /\./xsm, $topiclist[$i];
           fopen(MSG, "$datadir/$filename.txt");  
           @messages = <MSG>;             fopen( MSG, "$datadir/$filename.txt" ); 
           fclose(MSG);             @messages = <MSG>; 
             fclose(MSG);
           @lastmessage = split(/\|/, $messages[$#messages]);  
           &MessageTotals("load", $filename);             @lastmessage = split /\|/xsm, $messages[-1]; 
           ${$filename}{'replies'} = $#messages;             MessageTotals( 'load', $filename ); 
           if ($lastmessage[0] =~ /^\[m.*?\]/) { ${$filename}{'lastposter'} = $lastmessage[11]; }             ${$filename}{'replies'} = $#messages; 
           else { ${$filename}{'lastposter'} = $lastmessage[4] eq 'Guest' ? qq~Guest-$lastmessage[1]~ : $lastmessage[4]; }             if ( $lastmessage[0] =~ /^\[m.*?\]/xsm ) { 
           &MessageTotals("update", $filename);                 ${$filename}{'lastposter'} = $lastmessage[11]; 
             }
           $topicnum++;             else { 
           last if time() > ($begin_time + $max_process_time);                 ${$filename}{'lastposter'} = 
       }                   $lastmessage[4] eq 'Guest' 
                   ? qq~Guest-$lastmessage[1]~
       # Prepare to continue...                   : $lastmessage[4]; 
       $numleft = @topiclist - $topicnum;             } 
       if ($numleft == 0) { # go to finish             MessageTotals( 'update', $filename ); 
           $yySetLocation = qq~$adminurl?action=boardrecount;tnext=1~;  
           &redirectexit;             $topicnum++; 
       }             last if time() > ( $begin_time + $max_process_time ); 
         }
       # Continue  
       $sumtopic = @topiclist;         # Prepare to continue... 
       $resttopic = $sumtopic - $topicnum;        $numleft = @topiclist - $topicnum;
         if ( $numleft == 0 ) {    # go to finish
       $yymain .= qq~             $yySetLocation = qq~$adminurl?action=boardrecount;tnext=1~; 
       <br />             redirectexit(); 
       $rebuild_txt{'1'}         } 
       <br />  
       $rebuild_txt{'5'} $max_process_time $rebuild_txt{'6'}         # Continue 
       <br /><br />         $sumtopic  = @topiclist; 
       $rebuild_txt{'13'} $sumtopic         $resttopic = $sumtopic - $topicnum; 
       <br />  
       $rebuild_txt{'14'} $resttopic         $yymain .= qq~ 
       <br />        <br />
       <br />         $rebuild_txt{'1'} 
       <br />        <br />
       <div id="boardrecountcontinued">         $rebuild_txt{'5'} $max_process_time $rebuild_txt{'6'} 
       <br />        <br />
       $rebuild_txt{'1'}<br />        <br />
       $rebuild_txt{'2'} <a href="$adminurl?action=boardrecount;topicnum=$topicnum" onclick="rebRecount();">$rebuild_txt{'3'}</a>         $rebuild_txt{'13'} $sumtopic 
       </div>         <br /> 
       <script type="text/javascript" language="JavaScript">         $rebuild_txt{'14'} $resttopic 
       <!--         <br /> 
       function rebRecount() {         <br /> 
           document.getElementById("boardrecountcontinued").innerHTML = '$rebuild_txt{'4'}';         <div id="boardrecountcontinued"> 
       }         <br /> 
         $rebuild_txt{'1'}
       function recounttick() {         <br /> 
           rebRecount();         $rebuild_txt{'2'} <a href="$adminurl?action=boardrecount;topicnum=$topicnum" onclick="rebRecount();">$rebuild_txt{'3'}</a> 
           location.href="$adminurl?action=boardrecount;topicnum=$topicnum";         </div> 
       }         <script type="text/javascript"> 
         function rebRecount() {
       setTimeout("recounttick()",2000)             document.getElementById("boardrecountcontinued").innerHTML = '$rebuild_txt{'4'}'; 
       // -->         } 
       </script>  
       ~;         function recounttick() { 
       &AdminTemplate();             rebRecount(); 
   }             location.href="$adminurl?action=boardrecount;topicnum=$topicnum"; 
         }
   # Get the board list from the forum.master file  
   require "$boardsdir/forum.master";         setTimeout("recounttick()",2000) 
   foreach (keys %board) { &BoardCountTotals($_); }         </script> 
         ~;
   $yymain .= qq~<b>$admin_txt{'503'}</b>~;         AdminTemplate(); 
   &automaintenance('off');     } 
   &AdminTemplate;  
     # Get the board list from the forum.master file
     require "$boardsdir/forum.master";
     foreach ( keys %board ) { BoardCountTotals($_); }
   
     $yymain .= qq~<b>$admin_txt{'503'}</b>~;
     automaintenance('off');
     AdminTemplate();
     return;
} }
   
sub AdminMembershipRecount { sub AdminMembershipRecount {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
   &automaintenance('on');     automaintenance('on'); 
   &MembershipCountTotal;     MembershipCountTotal(); 
   &automaintenance('off');     automaintenance('off'); 
   
   $yymain     .= qq~<b>$admin_txt{'505'}</b>~;    $yymain .= qq~<b>$admin_txt{'505'}</b>~;
   $yytitle     = $admin_txt{'504'};    $yytitle     = $admin_txt{'504'};
   $action_area = "membershiprecount";     $action_area = 'membershiprecount'; 
   &AdminTemplate;     AdminTemplate(); 
     return;
} }
   
sub RebuildMemList { sub RebuildMemList {
   my (@contents, $begin_time, $start_time, $timeleft, $hour, $min, $sec, $sumuser, $savesettings, @grpexist);     my ( 
         @contents, $begin_time, $start_time, $timeleft,     $hour,
   # Security         $min,      $sec,        $sumuser,    $savesettings, @grpexist 
   &is_admin_or_gmod;     ); 
   &automaintenance("on");  
     # Security
   # Set up the multi-step action     is_admin_or_gmod(); 
   $begin_time = time();     automaintenance('on'); 
   
   if (-e "$memberdir/memberrest.txt.rebuild" && -M "$memberdir/memberrest.txt.rebuild" < 1) {     # Set up the multi-step action 
       fopen(MEMBERREST, "$memberdir/memberrest.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberrest.txt.rebuild", 1);     $begin_time = time; 
       @contents = <MEMBERREST>;  
       fclose(MEMBERREST);     if (   -e "$memberdir/memberrest.txt.rebuild" 
         && ( -M "$memberdir/memberrest.txt.rebuild" ) < 1 )
       fopen(MEMBERCALC, "$memberdir/membercalc.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/membercalc.txt.rebuild", 1);     { 
       $start_time = <MEMBERCALC>;         fopen( MEMBERREST, "$memberdir/memberrest.txt.rebuild" ) 
       $sumuser = <MEMBERCALC>;           || fatal_error( 'cannot_open', "$memberdir/memberrest.txt.rebuild", 
       fclose(MEMBERCALC);             1 ); 
       chomp ($start_time, $sumuser);         @contents = <MEMBERREST>; 
         fclose(MEMBERREST);
   } else {  
       unlink("$memberdir/memberlist.txt.rebuild");         fopen( MEMBERCALC, "$memberdir/membercalc.txt.rebuild" ) 
       unlink("$memberdir/memberinfo.txt.rebuild");           || fatal_error( 'cannot_open', "$memberdir/membercalc.txt.rebuild", 
   }             1 ); 
         $start_time = <MEMBERCALC>;
   if (!@contents) {         $sumuser    = <MEMBERCALC>; 
       # Get the list         fclose(MEMBERCALC); 
       opendir(MEMBERS, $memberdir) || die "$txt{'230'} ($memberdir) :: $!";         chomp $start_time; 
       @contents = map { $_ =~ s/\.vars$//; "$_\n"; } grep { /.\.vars$/ } readdir(MEMBERS);         chomp $sumuser; 
       closedir(MEMBERS);  
     }
       $start_time = $begin_time;     else { 
       $sumuser = @contents;         unlink "$memberdir/memberlist.txt.rebuild"; 
       fopen(MEMBERCALC, ">$memberdir/membercalc.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/membercalc.txt.rebuild", 1);         unlink "$memberdir/memberinfo.txt.rebuild"; 
       print MEMBERCALC "$start_time\n$sumuser\n";     } 
       fclose(MEMBERCALC);  
   }     if ( !@contents ) { 
   
   # Loop through each -rest- member         # Get the list 
   while (@contents) {         opendir MEMBERS, $memberdir or croak "$txt{'230'} ($memberdir) :: $!"; 
       my $member = pop @contents;         @contents = 
       chomp $member;           map { $_ =~ s/\.vars$//xsm; "$_\n"; } 
           grep { /.\.vars$/xsm } readdir MEMBERS;
       &LoadUser($member);         closedir MEMBERS; 
       &FromChars(${$uid.$member}{'realname'});  
         $start_time = $begin_time;
       $savesettings = 0;         $sumuser    = @contents; 
       @grpexist = ();         fopen( MEMBERCALC, ">$memberdir/membercalc.txt.rebuild" ) 
       foreach (split(/, ?/, ${$uid.$member}{'addgroups'})) {           || fatal_error( 'cannot_open', "$memberdir/membercalc.txt.rebuild", 
           if (!exists $NoPost{$_}) { $savesettings = 1; }             1 ); 
           else { push(@grpexist, $_); }         print {MEMBERCALC} "$start_time\n$sumuser\n" 
       }           or croak "$croak{'print'} MEMBERCALC"; 
       if ($savesettings) {         fclose(MEMBERCALC); 
           ${$uid.$member}{'addgroups'} = join(',', @grpexist);     } 
       }  
       if (!exists $Group{ ${$uid.$member}{'position'} } && !exists $NoPost{ ${$uid.$member}{'position'} }) {     # Loop through each -rest- member 
           ${$uid.$member}{'position'} = "";     while (@contents) { 
       }         my $member = pop @contents; 
       if (!${$uid.$member}{'position'}) {         chomp $member; 
           ${$uid.$member}{'position'} = &MemberPostGroup(${$uid.$member}{'postcount'});  
           $savesettings = 1;         LoadUser($member); 
       }         FromChars( ${ $uid . $member }{'realname'} ); 
       &UserAccount($member, "update") if $savesettings == 1;  
         $savesettings = 0;
       $memberlist{$member} = sprintf("%010d", (&stringtotime(${$uid.$member}{'regdate'}) || &stringtotime($forumstart)));         @grpexist     = (); 
       $memberinf{$member}  = qq~${$uid.$member}{'realname'}|${$uid.$member}{'email'}|${$uid.$member}{'position'}|${$uid.$member}{'postcount'}|${$uid.$member}{'addgroups'}~;         foreach ( split /, ?/sm, ${ $uid . $member }{'addgroups'} ) { 
             if ( !exists $NoPost{$_} ) { $savesettings = 1; }
       undef %{$uid.$member} if $member ne $username;             else                       { push @grpexist, $_; } 
       last if time() > ($begin_time + $max_process_time);         } 
   }         if ($savesettings) { 
             ${ $uid . $member }{'addgroups'} = join q{,}, @grpexist;
   # Save what we have rebuilt so far         } 
   fopen(MEMBERLIST, ">>$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt.rebuild", 1);         if (   !exists $Group{ ${ $uid . $member }{'position'} } 
   foreach (keys %memberlist) { print MEMBERLIST "$_\t$memberlist{$_}\n" };             && !exists $NoPost{ ${ $uid . $member }{'position'} } ) 
   fclose(MEMBERLIST);         { 
             ${ $uid . $member }{'position'} = q{};
   fopen(MEMBERINFO, ">>$memberdir/memberinfo.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberinfo.txt.rebuild", 1);         } 
   foreach (keys %memberinf) { print MEMBERINFO "$_\t$memberinf{$_}\n" };         if ( !${ $uid . $member }{'position'} ) { 
   fclose(MEMBERINFO);             ${ $uid . $member }{'position'} = 
               MemberPostGroup( ${ $uid . $member }{'postcount'} );
   # If it is completely done ...             $savesettings = 1; 
   if(!@contents) {         } 
       %memberlist = ();         if ( $savesettings == 1 ) { UserAccount( $member, 'update' ); } 
       # Sort memberlist.txt  
       fopen(MEMBERLIST, "$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt.rebuild", 1);         $memberlist{$member} = sprintf 
       my %memberlist = map {split(/\t/, $_)} <MEMBERLIST>;             '%010d', 
       fclose(MEMBERLIST);             ( 
                 stringtotime( ${ $uid . $member }{'regdate'} )
       fopen(MEMBERLIST, ">$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt.rebuild", 1);                   || stringtotime($forumstart) 
       foreach (sort {$memberlist{$a} <=> $memberlist{$b}} keys %memberlist) {             ); 
           print MEMBERLIST "$_\t$memberlist{$_}";         $memberinf{$member} = 
       }  qq~${$uid.$member}{'realname'}|${$uid.$member}{'email'}|${$uid.$member}{'position'}|${$uid.$member}{'postcount'}|${$uid.$member}{'addgroups'}~; 
       fclose(MEMBERLIST);  
         if ( $member ne $username ) { undef %{ $uid . $member }; }
       # Move the updated copy back         last if time() > ( $begin_time + $max_process_time ); 
       rename("$memberdir/memberlist.txt.rebuild", "$memberdir/memberlist.txt");     } 
       rename("$memberdir/memberinfo.txt.rebuild", "$memberdir/memberinfo.txt");  
       unlink("$memberdir/memberrest.txt.rebuild");     # Save what we have rebuilt so far 
       unlink("$memberdir/membercalc.txt.rebuild");     fopen( MEMBERLIST, ">>$memberdir/memberlist.txt.rebuild" ) 
       || fatal_error( 'cannot_open', "$memberdir/memberlist.txt.rebuild", 1 );
       $regcounter = &MembershipCountTotal();     foreach ( keys %memberlist ) { 
         print {MEMBERLIST} "$_\t$memberlist{$_}\n" 
       &automaintenance("off");           or croak "$croak{'print'} MEMBERLIST"; 
     }
       if ($INFO{'actiononfinish'}) {     fclose(MEMBERLIST); 
           $yySetLocation = qq~$adminurl?action=$INFO{'actiononfinish'}~;  
           &redirectexit;     fopen( MEMBERINFO, ">>$memberdir/memberinfo.txt.rebuild" ) 
       }       || fatal_error( 'cannot_open', "$memberdir/memberinfo.txt.rebuild", 1 ); 
       $yymain     .= qq~<b>$admin_txt{'594'} $regcounter $admin_txt{'594a'}</b>~;     foreach ( keys %memberinf ) { 
       $yytitle     = "$admin_txt{'593'}";         print {MEMBERINFO} "$_\t$memberinf{$_}\n" 
       $action_area = "rebuildmemlist";           or croak "$croak{'print'} MEMBERINFO"; 
     }
   # ... or continue looping     fclose(MEMBERINFO); 
   } else {  
       fopen(MEMBERREST, ">$memberdir/memberrest.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberrest.txt.rebuild", 1);     # If it is completely done ... 
       print MEMBERREST @contents;     if ( !@contents ) { 
       fclose(MEMBERREST);         %memberlist = (); 
   
       $restuser = @contents;         # Sort memberlist.txt 
       $run_time = int(time() - $start_time);         fopen( MEMBERLIST, "$memberdir/memberlist.txt.rebuild" ) 
       $run_time ||= 1;           || fatal_error( 'cannot_open', "$memberdir/memberlist.txt.rebuild", 
       $time_left = int($restuser / (($sumuser - $restuser + 1) / $run_time));             1 ); 
         my %memberlist = map { split /\t/xsm, $_ } <MEMBERLIST>;
       $hour= int($run_time/3600);         fclose(MEMBERLIST); 
       $min = int(($run_time-$hour*3600)/60);  
       $sec = $run_time - $hour*3600 - $min*60;         fopen( MEMBERLIST, ">$memberdir/memberlist.txt.rebuild" ) 
       $hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;           || fatal_error( 'cannot_open', "$memberdir/memberlist.txt.rebuild", 
             1 );
       $run_time = "$hour:$min:$sec";         foreach ( 
             sort { $memberlist{$a} <=> $memberlist{$b} }
       $hour= int($time_left/3600);             keys %memberlist 
       $min = int(($time_left-$hour*3600)/60);           ) 
       $sec = $time_left - $hour*3600 - $min*60;         { 
       $hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;             print {MEMBERLIST} "$_\t$memberlist{$_}" 
               or croak "$croak{'print'} MEMBERLIST";
       $time_left = "$hour:$min:$sec";         } 
         fclose(MEMBERLIST);
       if ($INFO{'actiononfinish'} eq 'modmemgr') {  
           $yymain     .= $rebuild_txt{'20'} ;         # Move the updated copy back 
           $yytitle     = $admin_txt{'8'};         rename "$memberdir/memberlist.txt.rebuild", 
           $action_area = "modmemgr";             "$memberdir/memberlist.txt"; 
       } else {         rename "$memberdir/memberinfo.txt.rebuild", 
           $yytitle     = $admin_txt{'593'};             "$memberdir/memberinfo.txt"; 
           $action_area = "rebuildmemlist";         unlink "$memberdir/memberrest.txt.rebuild"; 
       }         unlink "$memberdir/membercalc.txt.rebuild"; 
   
         $regcounter = MembershipCountTotal();
   
         automaintenance('off');
   
         if ( $INFO{'actiononfinish'} ) {
             $yySetLocation = qq~$adminurl?action=$INFO{'actiononfinish'}~;
             redirectexit();
         }
         $yymain .= qq~<b>$admin_txt{'594'} $regcounter $admin_txt{'594a'}</b>~;
         $yytitle     = "$admin_txt{'593'}";
         $action_area = 'rebuildmemlist';
   
         # ... or continue looping
     }
     else {
         fopen( MEMBERREST, ">$memberdir/memberrest.txt.rebuild" )
           || fatal_error( 'cannot_open', "$memberdir/memberrest.txt.rebuild",
             1 );
         print {MEMBERREST} @contents or croak "$croak{'print'} MEMBERREST";
         fclose(MEMBERREST);
   
         $restuser = @contents;
         $run_time = int( time() - $start_time );
         $run_time ||= 1;
         $time_left =
           int( $restuser / ( ( $sumuser - $restuser + 1 ) / $run_time ) );
   
         $hour = int( $run_time / 3600 );
         $min  = int( ( $run_time - $hour * 3600 ) / 60 );
         $sec  = $run_time - $hour * 3600 - $min * 60;
         if ( $hour < 10 ) { $hour = "0$hour"; }
         if ( $min < 10 )  { $min  = "0$min"; }
         if ( $sec < 10 )  { $sec  = "0$sec"; }
   
         $run_time = "$hour:$min:$sec";
   
         $hour = int( $time_left / 3600 );
         $min  = int( ( $time_left - $hour * 3600 ) / 60 );
         $sec  = $time_left - $hour * 3600 - $min * 60;
         if ( $hour < 10 ) { $hour = "0$hour"; }
         if ( $min < 10 )  { $min  = "0$min"; }
         if ( $sec < 10 )  { $sec  = "0$sec"; }
   
         $time_left = "$hour:$min:$sec";
   
         if ( $INFO{'actiononfinish'} eq 'modmemgr' ) {
             $yymain .= $rebuild_txt{'20'};
             $yytitle     = $admin_txt{'8'};
             $action_area = 'modmemgr';
         }
         else {
             $yytitle     = $admin_txt{'593'};
             $action_area = 'rebuildmemlist';
         }
   
       $yymain .= qq~        $yymain .= qq~
<br /> <br />
$rebuild_txt{'1'} $rebuild_txt{'1'}
<br /> <br />
$rebuild_txt{'5'} = $max_process_time $rebuild_txt{'6'} $rebuild_txt{'5'} = $max_process_time $rebuild_txt{'6'}
<br /><br /> <br />
  <br />
$rebuild_txt{'10'} $sumuser $rebuild_txt{'10'} $sumuser
<br /> <br />
$rebuild_txt{'10a'} $restuser $rebuild_txt{'10a'} $restuser
<br /> <br />
<br /> <br />
$rebuild_txt{'7'} $run_time $rebuild_txt{'7'} $run_time
<br /> <br />
$rebuild_txt{'8'} $time_left $rebuild_txt{'8'} $time_left
<br /> <br />
<br /> <br />
<div id="memcontinued"> <div id="memcontinued">
$rebuild_txt{'2'} <a href="$adminurl?action=rebuildmemlist;actiononfinish=$INFO{'actiononfinish'}" onclick="clearMeminfo();">$rebuild_txt{'3'}</a> $rebuild_txt{'2'} <a href="$adminurl?action=rebuildmemlist;actiononfinish=$INFO{'actiononfinish'}" onclick="clearMeminfo();">$rebuild_txt{'3'}</a>
</div> </div>
<script type="text/javascript" language="JavaScript">  <script type="text/javascript"> 
<!--     function clearMeminfo() { 
   function clearMeminfo() {         document.getElementById("memcontinued").innerHTML = '$rebuild_txt{'4'}'; 
       document.getElementById("memcontinued").innerHTML = '$rebuild_txt{'4'}';     } 
   }  
     function membtick() {
   function membtick() {         clearMeminfo(); 
       clearMeminfo();         location.href="$adminurl?action=rebuildmemlist;actiononfinish=$INFO{'actiononfinish'}"; 
       location.href="$adminurl?action=rebuildmemlist;actiononfinish=$INFO{'actiononfinish'}";     } 
   }  
   
   setTimeout("membtick()", 2000)    setTimeout("membtick()", 2000)
// -->  
</script>~; </script>~;
   }    }
   
   &AdminTemplate();     AdminTemplate(); 
     return;
} }
   
sub RebuildMemHistory { sub RebuildMemHistory {
   my (@contents,$begin_time,$start_time,$timeleft,$hour,$min,$sec,$sumtopic,$resttopic,$mdate,$user);     my ( 
         @contents,  $begin_time, $start_time, $timeleft,
         $hour,      $min,        $sec,        $sumtopic,
         $resttopic, $mdate,      $user
     );
   
     # Security
     is_admin_or_gmod();
     automaintenance('on');
   
     # Set up the multi-step action
     $begin_time = time;
   
     if (   -e "$datadir/topicrest.txt.rebuild" 
         && ( -M "$datadir/topicrest.txt.rebuild" ) < 1 )
     {
         fopen( TOPICREST, "$datadir/topicrest.txt.rebuild" )
           || fatal_error( 'cannot_open', "$datadir/topicrest.txt.rebuild", 1 );
         @contents = <TOPICREST>;
         fclose(TOPICREST);
   
         fopen( TOPICCALC, "$datadir/topiccalc.txt.rebuild" )
           || fatal_error( 'cannot_open', "$datadir/topiccalc.txt.rebuild", 1 );
         $start_time = <TOPICCALC>;
         $sumtopic   = <TOPICCALC>;
         fclose(TOPICCALC);
         chomp $begin_time;
         chomp $sumtopic;
     }
   
     if ( !@contents ) {
   
         # Delete all rlog
         opendir MEMBERS, $memberdir or croak "$txt{'230'} ($memberdir) :: $!";
         @contents = grep { /\.rlog$/xsm } readdir MEMBERS;
         closedir MEMBERS;
         foreach (@contents) {
             unlink "$memberdir/$_";
         }
   
         # Get and store the thread list
         opendir TXT, $datadir;
         @contents =
           map { $_ =~ s/\.txt$//xsm; "$_\n"; } grep { /^\d+\.txt$/xsm } readdir TXT;
         closedir TXT;
   
         $start_time = $begin_time;
         $sumtopic   = @contents;
         fopen( TOPICCALC, ">$datadir/topiccalc.txt.rebuild" )
           || fatal_error( 'cannot_open', "$datadir/topiccalc.txt.rebuild", 1 );
         print {TOPICCALC} "$start_time\n$sumtopic\n" 
           or croak "$croak{'print'} TOPICCALC";
         fclose(TOPICCALC);
     }
   
     # Loop through each -rest- topic
     while (@contents) {
         $topic = pop @contents;
         chomp $topic;
   
         fopen( TOPIC, "$datadir/$topic.txt" );
         my @topic = <TOPIC>;
         fclose(TOPIC);
   
         my %dates = ();
         my %posts = ();
         foreach (@topic) {
             ( undef, undef, undef, $mdate, $user, undef ) = split /\|/xsm, $_,
               6;
             if ( $user ne 'Guest' ) {
                 $posts{$user}++;
                 $dates{$user} = $mdate;
             }
         }
   
         foreach my $user ( keys %posts ) {
             if ( -e "$memberdir/$user.vars" ) {