F:\WEBSITES\testbed\zipped\yabb_svn_new\branches\2.5.2\cgi-bin\yabb2\Admin\Attachments.pl F:\WEBSITES\testbed\zipped\yabb_svn_new\trunk\cgi-bin\yabb2\Admin\Attachments.pm
############################################################################### ###############################################################################
# Attachments.pl                                                              # # Attachments.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';
   
$attachmentsplver = 'YaBB 2.5.2 $Revision: 1.0 $'; $attachmentspmver = 'YaBB 2.6.12 $Revision: 1710 $';
if ($action eq 'detailedversion') { return 1; } if ( $action eq 'detailedversion' ) { return 1; }
   
sub Attachments { sub Attachments {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
   fopen(AMS, "$vardir/attachments.txt");     fopen( AMS, "$vardir/attachments.txt" ); 
   my @attachments = <AMS>;    my @attachments = <AMS>;
   fclose(AMS);    fclose(AMS);
   
   my $attachment_space = 0;    my $attachment_space = 0;
   foreach (@attachments) {    foreach (@attachments) {
       $attachment_space += (split /\|/, $_, 7)[5];         $attachment_space += NumberFormat( ( split /\|/xsm, $_, 7 )[5] ); 
   }    }
   
   my $remaining_space;    my $remaining_space;
   if (!$dirlimit) {    if ( !$dirlimit ) {
       $remaining_space = "$fatxt{'23'}";        $remaining_space = "$fatxt{'23'}";
   } else {     } 
       $remaining_space = ($dirlimit - $attachment_space) . " KB";     else { 
   }         $remaining_space = NumberFormat( ( $dirlimit - $attachment_space ) ) . ' KB'; 
     }
   fopen(FILE, "$vardir/oldestattach.txt");  
   $maxdaysattach = <FILE>;     fopen( FILE, "$vardir/oldestattach.txt" ); 
   fclose(FILE);     $maxdaysattach = <FILE>; 
     fclose(FILE);
   fopen(FILE, "$vardir/maxattachsize.txt");  
   $maxsizeattach = <FILE>;     fopen( FILE, "$vardir/oldestpmattach.txt" ); 
   fclose(FILE);     $pmMaxDaysAttach = <FILE>; 
     fclose(FILE);
   my $totalattachnum = @attachments;  
   $yymain .= qq~     fopen( FILE, "$vardir/maxattachsize.txt" ); 
<table border="0" width="70%" cellspacing="1" cellpadding="3" class="bordercolor" align="center">     $maxsizeattach = <FILE>; 
<tr>    fclose(FILE); 
<td class="titlebg">  
<img src="$imagesdir/xx.gif" alt="" />     fopen( FILE, "$vardir/maxpmattachsize.txt" ); 
<b>$fatxt{'24'}</b></td>     $pmMaxSizeAttach = <FILE>; 
</tr><tr>     fclose(FILE); 
<td class="windowbg"><br /><span class="small">$fatxt{'25'}</span><br /><br /></td>  
</tr><tr>     fopen( PMATTACHLOG, "$vardir/pm.attachments" ); 
<td width="460" class="catbg"><b>$fatxt{'26'}</b></td>     my @pmAttachments = <PMATTACHLOG>; 
</tr><tr>     fclose(PMATTACHLOG); 
<td class="windowbg" height="21">  
<b>$fatxt{'27'}</b><br /></td>     my $pmAttachmentSpace = 0; 
</tr><tr>     foreach (@pmAttachments) { 
<td class="windowbg2">         $pmAttachmentSpace += NumberFormat( ( split /\|/xsm, $_, 4 )[2] ); 
<table border="0" cellpadding="3" cellspacing="0"><tr>     } 
<td><span class="small"><b>$fatxt{'28'}</b></span></td>  
<td><span class="small">$totalattachnum</span></td>     my $pmRemainingSpace; 
</tr><tr>     if ( !$pmDirLimit ) { 
<td><span class="small"><b>$fatxt{'29'}</b></span></td>         $pmRemainingSpace = "$fatxt{'23a'}"; 
<td><span class="small">$attachment_space KB</span><br /></td>     } 
</tr><tr>     else { 
<td><span class="small"><b>$fatxt{'30'}</b></span></td>         $pmRemainingSpace = NumberFormat( ( $pmDirLimit - $pmAttachmentSpace ) ) . ' KB'; 
<td><span class="small">$remaining_space</span></td>     } 
</tr>  
</table><br />     my $totalattachnum = @attachments; 
</td>     my $pmTotalAttachNum = @pmAttachments; 
</tr><tr>      $yymain .= qq~ 
<td class="windowbg" height="21">  <div class="bordercolor rightboxdiv"> 
<b>$fatxt{'31'}</b><br /></td>  <table class="border-space pad-cell"> 
</tr><tr>     <tr> 
<td class="windowbg2">         <td class="titlebg">$admin_img{'xx'} <b>$fatxt{'24'}</b></td> 
<table border="0" cellpadding="3" cellspacing="0">     </tr><tr> 
<tr>         <td class="windowbg"> 
<form action="$adminurl?action=removeoldattachments" method="post">             <div class="pad-more small">$fatxt{'25'}</div> 
<td><span class="small">$fatxt{'32'}</span></td>         </td> 
<td><span class="small"><input type="text" name="maxdaysattach" size="2" value="$maxdaysattach" /> $fatxt{'58'}&nbsp;</span></td>     </tr><tr> 
<td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>         <td class="catbg"><b>$fatxt{'26'}</b></td> 
</form>     </tr><tr> 
</tr><tr>         <td class="windowbg att_h_a"> 
<form action="$adminurl?action=removebigattachments" method="post">             <b>$fatxt{'27'}</b> 
<td><span class="small">$fatxt{'33'}</span></td>         </td> 
<td><span class="small"><input type="text" name="maxsizeattach" size="2" value="$maxsizeattach" /> KB&nbsp;</span></td>     </tr><tr> 
<td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>         <td class="windowbg2"> 
</form>             <table class="left pad-cell" style="margin-bottom:.5em"> 
</tr><tr>                 <tr> 
<td colspan="3"><span class="small" style="font-weight: bold;"><a href="$adminurl?action=manageattachments2">$fatxt{'31a'}</a></span> | <span class="small" style="font-weight: bold;"><a href="$adminurl?action=rebuildattach">$fatxt{'63'}</a></span></td>                     <td class="small"><b>$fatxt{'28'}</b></td> 
</tr>                     <td class="small">$totalattachnum</td> 
                 </tr><tr>
                     <td class="small"><b>$fatxt{'29'}</b></td>
                     <td class="small">$attachment_space KB<br /></td>
                 </tr><tr>
                     <td class="small"><b>$fatxt{'30'}</b></td>
                     <td class="small">$remaining_space</td>
                 </tr><tr>
                     <td colspan="2"><hr /></td>
                 </tr><tr>
                     <td class="small"><b>$fatxt{'28a'}</b></td>
                     <td class="small">$pmTotalAttachNum</td>
                 </tr><tr>
                     <td class="small"><b>$fatxt{'29a'}</b></td>
                     <td class="small">$pmAttachmentSpace KB<br /></td>
                 </tr><tr>
                     <td class="small"><b>$fatxt{'30a'}</b></td>
                     <td class="small">$pmRemainingSpace</td>
                 </tr>
             </table>
         </td>
     </tr><tr>
         <td class="windowbg att_h_a">
             <b>$fatxt{'31'}</b>
         </td>
     </tr><tr>
         <td class="windowbg2">
             <form action="$adminurl?action=removeoldattachments" method="post">
             <table class="pad-cell left" style="min-width:30%">
                 <colgroup>
                     <col style="width:60%" />
                     <col style="width:20%" span="2" />
                 </colgroup>
                 <tr>
                     <td class="small">$fatxt{'32'}</td>
                     <td class="small"><input type="text" name="maxdaysattach" size="2" value="$maxdaysattach" /> $fatxt{'58'}&nbsp;</td>
                     <td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>
                 </tr>
             </table>
             </form>
             <form action="$adminurl?action=removebigattachments" method="post">
             <table class="pad-cell left" style="min-width:30%">
                 <colgroup>
                     <col style="width:60%" />
                     <col style="width:20%" span="2" />
                 </colgroup>
                 <tr>
                     <td><span class="small">$fatxt{'33'}</span></td>
                     <td><span class="small"><input type="text" name="maxsizeattach" size="2" value="$maxsizeattach" /> KB&nbsp;</span></td>
                     <td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>
                 </tr><tr>
                     <td colspan="3">
                         <span class="small bold"><a href="$adminurl?action=manageattachments2">$fatxt{'31a'}</a></span> | <span class="small bold"><a href="$adminurl?action=rebuildattach">$fatxt{'63'}</a></span>
                     </td>
                 </tr>
             </table>
             </form>
         </td>
     </tr><tr>
         <td class="windowbg att_h_a">
             <b>$fatxt{'31b'}</b>
         </td>
     </tr><tr>
         <td class="windowbg2">
             <form action="$adminurl?action=removeoldpmattachments" method="post">
             <table class="pad-cell left" style="min-width:30%">
                 <colgroup>
                     <col style="width:60%" />
                     <col style="width:20%" span="2" />
                 </colgroup>
                 <tr>
                     <td><span class="small">$fatxt{'32a'}</span></td>
                     <td><span class="small"><input type="text" name="pmmaxdaysattach" size="2" value="$pmMaxDaysAttach" /> $fatxt{'58'}&nbsp;</span></td>
                     <td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>
                 </tr>
             </table>
             </form>
             <form action="$adminurl?action=removebigpmattachments" method="post">
             <table class="pad-cell left" style="min-width:30%">
                 <colgroup>
                     <col style="width:60%" />
                     <col style="width:20%" span="2" />
                 </colgroup>
                 <tr>
                     <td><span class="small">$fatxt{'33a'}</span></td>
                     <td><span class="small"><input type="text" name="pmmaxsizeattach" size="2" value="$pmMaxSizeAttach" /> KB&nbsp;</span></td>
                     <td><input type="submit" value="$admin_txt{'32'}" class="button" /></td>
                 </tr><tr>
                     <td colspan="3">
                         <span class="small bold"><a href="$adminurl?action=managepmattachments2">$fatxt{'31c'}</a></span> | <span class="small bold"><a href="$adminurl?action=rebuildpmattach">$fatxt{'63a'}</a></span>
                     </td>
                 </tr>
             </table>
             </form>
         </td>
     </tr>
</table> </table>
</td>  </div>~; 
</tr>  
</table>~;     $yytitle     = "$fatxt{'36'}"; 
     $action_area = 'manageattachments';
   $yytitle = "$fatxt{'36'}";     AdminTemplate(); 
   $action_area = "manageattachments";     return; 
   &AdminTemplate;  
} }
   
sub RemoveOldAttachments { sub RemoveOldAttachments {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
   my $maxdaysattach = $FORM{'maxdaysattach'} || $INFO{'maxdaysattach'};    my $maxdaysattach = $FORM{'maxdaysattach'} || $INFO{'maxdaysattach'};
   if ($maxdaysattach !~ /^[0-9]+$/) { &admin_fatal_error("only_numbers_allowed"); }     if ( $maxdaysattach !~ /^[0-9]+$/xsm ) { 
         fatal_error('only_numbers_allowed');
     }
   
     # Set up the multi-step action
     $time_to_jump = time() + $max_process_time;
   
     automaintenance('on');
   
     opendir ATT, $uploaddir
       || fatal_error( 'cannot_open', "$uploaddir", 1 );
     my @attachments = sort grep { /\w+$/xsm } readdir ATT;
     closedir ATT;
     my $info;
     if ( !@attachments ) {
         fopen( ATT, ">$vardir/attachments.txt" )
           || fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 );
         print {ATT} q{} or croak "$croak{'print'} ATT";
         fclose(ATT);
   
         $info = qq~<br /><i>$fatxt{'48'}.</i>~;
     }
     else {
         fopen( AML, "$vardir/attachments.txt" );
         foreach (@attachmentstxt) {
             my @line = split /\|/xsm, $_;
             $att{ $line[7] } = $line[0];
         }
   
         if ( !exists $INFO{'next'} ) { unlink "$vardir/rem_old_attach.tmp"; }
   
         my %rem_attachments;
         for my $aa ( ( $INFO{'next'} || 0 ) .. ( @attachments - 1 ) ) {
   
             # -M => Script start time minus file modification time, in days.
             my $age = sprintf '%.2f', -M "$uploaddir/$attachments[$aa]";
             if ( $age <= $maxdaysattach ) {
   
                 # If the attachment is not too old
                 $info .= qq~<br />$attachments[$aa] = $age $admin_txt{'122'}.~;
   
             }
             elsif ( exists $att{ $attachments[$aa] } ) {
                 $rem_attachments{ $att{ $attachments[$aa] } } .=
                   $rem_attachments{ $att{ $attachments[$aa] } }
                   ? "|$attachments[$aa]" 
                   : $attachments[$aa];
                 $info .=
  qq~<br /><i>$attachments[$aa]</i> $fatxt{'1'} = $age $admin_txt{'122'}.~;
             }
   
             if ( $time_to_jump < time() && ( $aa + 1 ) < @attachments ) {
   
             # save the $info of this run until the end of 'RemoveOldAttachments'
                 fopen( FILE, ">>$vardir/rem_old_attach.tmp" )
                   || fatal_error( 'cannot_open',
                     "$vardir/rem_old_attach.tmp", 1 );
                 print $info or croak "$croak{'print'} rem_old_attach";
                 fclose(FILE);
   
                 $yySetLocation =
  qq~$adminurl?action=removeoldattachments;maxdaysattach=$maxdaysattach;next=~
                   . ( $aa + 1 - RemoveAttachments( \%rem_attachments ) );
                 redirectexit();
             }
         }
         RemoveAttachments( \%rem_attachments );
     }
   
     automaintenance('off');
   
     $yymain .= qq~<b>$fatxt{'32'} $maxdaysattach $fatxt{'58'}.</b><br />~;
   
     fopen( FILE, "$vardir/rem_old_attach.tmp" );
   
     #    $yymain .= join( q{}, <FILE> ) . $info;
     $yymain .= do { local $INPUT_RECORD_SEPARATOR = undef; <FILE> }
       . $info;
     fclose(FILE);
     unlink "$vardir/rem_old_attach.tmp";
   
     fopen( FILE, ">$vardir/oldestattach.txt" );
     print {FILE} $maxdaysattach or croak "$croak{'print'} oldestattach";
     fclose(FILE);
   
     $yytitle     = "$fatxt{'34'} $maxdaysattach";
     $action_area = 'removeoldattachments';
     AdminTemplate();
     return;
  }
   
   # Set up the multi-step action  sub RemoveBigAttachments { 
   $time_to_jump = time() + $max_process_time;     is_admin_or_gmod(); 
   
   &automaintenance('on');     my $maxsizeattach = $FORM{'maxsizeattach'} || $INFO{'maxsizeattach'}; 
     if ( $maxsizeattach !~ /^[0-9]+$/xsm ) {
   opendir(ATT, $uploaddir) || &admin_fatal_error('cannot_open', "$uploaddir", 1);         fatal_error('only_numbers_allowed'); 
   my @attachments = sort( grep(/\w+$/, readdir(ATT)) );     } 
   closedir(ATT);  
     # Set up the multi-step action
   fopen(AML, "$vardir/attachments.txt");     $time_to_jump = time() + $max_process_time; 
   my @attachmentstxt = <AML>;  
   fclose(AML);     automaintenance('on'); 
   
   my (%att,@line);     opendir ATT, $uploaddir 
   foreach (@attachmentstxt) {       || fatal_error( 'cannot_open', "$uploaddir", 1 ); 
       @line = split(/\|/, $_);     my @attachments = sort grep { /\w+$/xsm } readdir ATT; 
       $att{$line[7]} = $line[0];     closedir ATT; 
   }     my %filelist = (); 
     foreach my $i (@attachments) {
   my $info;         $filelist{$i} = 1; 
   if (!@attachments) {     } 
       fopen(ATT, ">$vardir/attachments.txt") || &admin_fatal_error("cannot_open","$vardir/attachments.txt", 1);  
       print ATT '';     fopen( FILE, "$vardir/attachments.txt" ); 
       fclose(ATT);     @attachmentstxt = <FILE>; 
     fclose(FILE);
       $info = qq~<br /><i>$fatxt{'48'}.</i>~;  
     my ( %att, @line );
   } else {    foreach (@attachmentstxt) {
       unlink("$vardir/rem_old_attach.tmp") unless exists $INFO{'next'};         @line = split /\|/xsm, $_; 
         if ( $filelist{$line[7]} ) {
       my %rem_attachments;             $att{ $line[7] } = $line[0]; 
       for (my $a = ($INFO{'next'} || 0); $a < @attachments; $a++) {         } 
           # -M => Script start time minus file modification time, in days.     } 
           my $age = sprintf("%.2f", -M "$uploaddir/$attachments[$a]");  
           if ($age <= $maxdaysattach) {     my $info; 
               # If the attachment is not too old     if ( !@attachments ) { 
               $info .= qq~<br />$attachments[$a] = $age $admin_txt{'122'}.~;         fopen( ATT, ">$vardir/attachments.txt" ) 
           || fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 );
           } elsif (exists $att{$attachments[$a]}) {         print {ATT} q{} or croak "$croak{'print'} ATT"; 
               $rem_attachments{$att{$attachments[$a]}} .= $rem_attachments{$att{$attachments[$a]}} ? "|$attachments[$a]" : $attachments[$a];         fclose(ATT); 
               $info .= qq~<br /><i>$attachments[$a]</i> $fatxt{'1'} = $age $admin_txt{'122'}.~;  
           }         $info = qq~<br /><i>$fatxt{'48'}.</i>~; 
     }
           if ($time_to_jump < time() && ($a + 1) < @attachments) {    else {
               # save the $info of this run until the end of 'RemoveOldAttachments'         if ( !exists $INFO{'next'} ) { unlink "$vardir/rem_big_attach.tmp"; } 
               fopen(FILE, ">>$vardir/rem_old_attach.tmp") || &admin_fatal_error('cannot_open', "$vardir/rem_old_attach.tmp", 1);  
               print $info;         my (%rem_attachments); 
               fclose(FILE);         for my $aa ( ( $INFO{'next'} || 0 ) .. ( @attachments - 1 ) ) { 
             my $size = sprintf '%.2f',
               $yySetLocation = qq~$adminurl?action=removeoldattachments;maxdaysattach=$maxdaysattach;next=~ . ($a + 1 - &RemoveAttachments(\%rem_attachments));               ( ( -s "$uploaddir/$attachments[$aa]" ) / 1024 ); 
               &redirectexit;             if ( $size <= $maxsizeattach ) { 
           }  
       }                 # If the attachment is not too big 
                 $info .= qq~<br />$attachments[$aa] = $size KB~;
       &RemoveAttachments(\%rem_attachments);  
   }            }
             elsif ( exists $att{ $attachments[$aa] } ) {
   &automaintenance('off');                 $rem_attachments{ $att{ $attachments[$aa] } } .= 
                   $rem_attachments{ $att{ $attachments[$aa] } }
   $yymain .= qq~<b>$fatxt{'32'} $maxdaysattach $fatxt{'58'}.</b><br />~;                   ? "|$attachments[$aa]" 
                   : $attachments[$aa];
   fopen(FILE, "$vardir/rem_old_attach.tmp");                 $info .= 
   $yymain .= join('', <FILE>) . $info;                   qq~<br /><i>$attachments[$aa]</i> $fatxt{'1'} = $size KB~; 
   fclose(FILE);             } 
   unlink("$vardir/rem_old_attach.tmp");             if ( $time_to_jump < time() && ( $aa + 1 ) < @attachments ) { 
   
   fopen(FILE, ">$vardir/oldestattach.txt");             # save the $info of this run until the end of 'RemoveBigAttachments' 
   print FILE $maxdaysattach;                 fopen( FILE, ">>$vardir/rem_big_attach.tmp" ) 
   fclose(FILE);                   || fatal_error( 'cannot_open', 
                     "$vardir/rem_big_attach.tmp", 1 );
   $yytitle     = "$fatxt{'34'} $maxdaysattach";                 print $info or croak "$croak{'print'} rem_big_attach"; 
   $action_area = "removeoldattachments";                 fclose(FILE); 
   &AdminTemplate;  
                 $yySetLocation =
  qq~$adminurl?action=removebigattachments;maxsizeattach=$maxsizeattach;next=~
                   . ( $aa + 1 - RemoveAttachments( \%rem_attachments ) );
                 redirectexit();
             }
         }
   
         RemoveAttachments( \%rem_attachments );
     }
   
     $yymain .= qq~<b>$fatxt{'33'} $maxsizeattach KB.</b><br />~;
   
     fopen( FILE, "$vardir/rem_big_attach.tmp" );
   
     #    $yymain .= join( q{}, <FILE> ) . $info;
     $yymain .= do { local $INPUT_RECORD_SEPARATOR = undef; <FILE> }
       . $info;
     fclose(FILE);
     unlink "$vardir/rem_big_attach.tmp";
   
     fopen( FILE, ">$vardir/maxattachsize.txt" );
     print {FILE} $maxsizeattach or croak "$croak{'print'} FILE";
     fclose(FILE);
   
     automaintenance('off');
   
     $yytitle     = "$fatxt{'35'} $maxsizeattach KB";
     $action_area = 'removebigattachments';
     AdminTemplate();
     return;
} }
   
sub RemoveBigAttachments { sub Attachments2 {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
   my $maxsizeattach = $FORM{'maxsizeattach'} || $INFO{'maxsizeattach'};     fopen( AML, "$vardir/attachments.txt" ); 
   if ($maxsizeattach !~ /^[0-9]+$/) { &admin_fatal_error("only_numbers_allowed"); }     my @attachinput = <AML>; 
     fclose(AML);
     my $max = @attachinput;
   
     my $action   = $INFO{'action'};
     my $sort     = $INFO{'sort'} || 6;
     my $newstart = $INFO{'newstart'} || 0;
   
     if ( !$max ) {
         $viewattachments .=
  qq~<tr><td class="windowbg2 padd-cell center" colspan="8"><b><i>$fatxt{'48'}</i></b></td></tr>~;
     }
     else {
         $yymain .= qq~
         <script type="text/javascript">
             function checkAll() {
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {
                     document.del_attachments.elements[i].checked = true;
                 }
             }
             function uncheckAll() {
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {
                     document.del_attachments.elements[i].checked = false;
                 }
             }
         </script>
         <form name="del_attachments" action="$adminurl?action=deleteattachment" method="post" style="display: inline;">~;
   
         my @attachments;
         if ( $sort > 0 ) {    # sort ascending
             if ( $sort == 5 || $sort == 6 || $sort == 8 ) {
                 @attachments = sort {
                     ( split /\|/xsm, $a )[$sort]
                       <=> ( split /\|/xsm, $b )[$sort];
                 } @attachinput;    # sort size, date, count numerically
             }
             elsif ( $sort == 100 ) {
                 @attachments = sort {
                     lc(   ( split /\./xsm, ( split /\|/xsm, $a )[7] )[1] ) cmp
                       lc( ( split /\./xsm, ( split /\|/xsm, $b )[7] )[1] );
                 } @attachinput;    # sort extension lexically
             }
             else {
                 @attachments = sort {
                     lc(   ( split /\|/xsm, $a )[$sort] ) cmp
                       lc( ( split /\|/xsm, $b )[$sort] );
                 } @attachinput;    # sort lexically
             }
         }
         else {                     # sort descending
             if ( $sort == -5 || $sort == -6 || $sort == -8 ) {
                 @attachments = reverse sort {
                     ( split /\|/xsm, $a )[ -$sort ]
                       <=> ( split /\|/xsm, $b )[ -$sort ];
                 } @attachinput;    # sort size, date, count numerically
             }
             elsif ( $sort == -100 ) {
                 @attachments = reverse sort {
                     lc(   ( split /\./xsm, ( split /\|/xsm, $a )[7] )[1] ) cmp
                       lc( ( split /\./xsm, ( split /\|/xsm, $b )[7] )[1] );
                 } @attachinput;    # sort extension lexically
             }
             else {
                 @attachments = reverse sort {
                     lc(   ( split /\|/xsm, $a )[ -$sort ] ) cmp
                       lc( ( split /\|/xsm, $b )[ -$sort ] );
                 } @attachinput;    # sort lexically
             }
         }
   
         $postdisplaynum = 8;
         $newstart       = ( int( $newstart / 25 ) ) * 25;
         $tmpa           = 1;
         if ( $newstart >= ( ( $postdisplaynum - 1 ) * 25 ) ) {
             $startpage = $newstart - ( ( $postdisplaynum - 1 ) * 25 );
             $tmpa = int( $startpage / 25 ) + 1;
         }
         if ( $max >= $newstart + ( $postdisplaynum * 25 ) ) {
             $endpage = $newstart + ( $postdisplaynum * 25 );
         }
         else { $endpage = $max; }
         if ( $startpage > 0 ) {
             $pageindex =
  qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" class="norm">1</a>&nbsp;...&nbsp;~;
         }
         if ( $startpage == 25 ) {
             $pageindex =
  qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" class="norm">1</a>&nbsp;~;
         }
         foreach my $counter ( $startpage .. ( $endpage - 1 ) ) {
             if ( $counter % 25 == 0 ) {
                 $pageindex .=
                   $newstart == $counter
                   ? qq~<b>$tmpa</b>&nbsp;~
                   : qq~<a href="$adminurl?action=$action;newstart=$counter;sort=$sort" class="norm">$tmpa</a>&nbsp;~;
                 $tmpa++;
             }
         }
         $lastpn  = int( $max / 25 ) + 1;
         $lastptn = ( $lastpn - 1 ) * 25;
         if ( $endpage < $max - (25) ) { $pageindexadd = q~...&nbsp;~; }
         if ( $endpage != $max ) {
             $pageindexadd .=
  qq~<a href="$adminurl?action=$action;newstart=$lastptn;sort=$sort">$lastpn</a>~;
         }
         $pageindex .= $pageindexadd;
   
         $pageindex =
  qq~<div class="small" style="line-height: 2.5em; float: right; text-align: right; vertical-align: middle;">$fatxt{'64'}: $pageindex</div>~;
   
         $numbegin = ( $newstart + 1 );
         $numend   = ( $newstart + 25 );
         if   ( $numend > $max ) { $numend  = $max; }
         if   ( $max == 0 )      { $numshow = q{}; }
         else                    { $numshow = qq~($numbegin - $numend)~; }
   
         my ( %attach_gif, $ext );
         foreach my $row ( splice @attachments, $newstart, 25 ) {
             chomp $row;
             my (
                 $amthreadid, $amreplies,      $amthreadsub,
                 $amposter,   $amcurrentboard, $amkb,
                 $amdate,     $amfn,           $amcount
             ) = split /\|/xsm, $row;
   
             if ( $amfn =~ /\.(.+?)$/xsm ) {
                 $ext = $1;
             }
             if ( !exists $attach_gif{$ext} ) {
                 $attach_gif{$ext} =
                   ( $ext && -e "$htmldir/Templates/Forum/$useimages/$ext.gif" )
                   ? "$ext.gif" 
                   : 'paperclip.gif';
             }
   
             $amdate = timeformat($amdate);
             $amkb   = NumberFormat($amkb);
             if ( length($amthreadsub) > 30 ) {
                 $amthreadsub = substr( $amthreadsub, 0, 30 ) . q{...};
             }
             my $amfna = $amfn;
             if ( length($amfn) > 30 ) {
                 $amfna = substr( $amfna, 0, 30 ) . q{...};
             }
             $viewattachments .= qq~<tr>
             <td class="windowbg2 center"><input type="checkbox" name="del_$amthreadid" value="$amfn" /></td>
             <td class="windowbg2"><a href="$uploadurl/$amfn" target="_blank">$amfna</a></td>
             <td class="windowbg2 center"><img src="$imagesdir/$attach_gif{$ext}" class="bottom" alt="" /></td>
             <td class="windowbg2 right">$amkb KB</td>
             <td class="windowbg2 center">$amdate</td>
             <td class="windowbg2 right">$amcount</td>
             <td class="windowbg2"><a href="$scripturl?num=$amthreadid/$amreplies#$amreplies" target="_blank">$amthreadsub</a></td>
             <td class="windowbg2 center">$amposter</td>
         </tr>~;
         }
   
         $viewattachments .= qq~<tr>
             <td class="catbg center">
                 <input type="checkbox" name="checkall" id="checkall" value="" onclick="if(this.checked){checkAll();}else{uncheckAll();}" />
             </td>
             <td class="catbg" colspan="7">
                 <div class="small" style="float: left; text-align: left;">
                     &lt;= <label for="checkall">$amv_txt{'38'}</label> &nbsp; <input type="submit" value="$admin_txt{'32'}" class="button" />
                 </div>
         $pageindex
             </td>
         </tr>~;
   
         $yymain .= qq~
         <input type="hidden" name="newstart" value="$newstart" />~;
     }
   
     my $class_sortattach = $sort =~ /7/sm   ? 'catbg' : 'windowbg';
     my $class_sorttype   = $sort =~ /100/sm ? 'catbg' : 'windowbg';
     my $class_sortsize   = $sort =~ /5/sm   ? 'catbg' : 'windowbg';
     my $class_sortdate   = $sort =~ /6/sm   ? 'catbg' : 'windowbg';
     my $class_sorcount   = $sort =~ /8/sm   ? 'catbg' : 'windowbg';
     my $class_sortsubj   = $sort =~ /2/sm   ? 'catbg' : 'windowbg';
     my $class_sortuser   = $sort =~ /3/sm   ? 'catbg' : 'windowbg';
   
     my $rsort;
   
     $yymain .= qq~
  <div class="bordercolor rightboxdiv">
  <table class="border-space pad-cell">
     <colgroup>
         <col style="width:7%" />
         <col style="width:18%" />
         <col style="width:5%" />
         <col style="width:7%" />
         <col style="width:23%" />
         <col style="width:5%" />
         <col style="width:22%" />
         <col style="width:13%" />
     </colgroup>
     <tr>
         <td class="titlebg" colspan="8">
             $admin_img{'xx'}&nbsp;<b>$fatxt{'39'}</b>
         </td>
     </tr><tr>
         <td class="windowbg" colspan="8">
         <div class="pad-more small">$fatxt{'38'}</div>
         </td>
     </tr><tr>
         <td class="titlebg center" colspan="8"><b>$fatxt{'55'}</b></td>
     </tr><tr>
        <td class="catbg att_h_b" colspan="8">
         <div class="small" style="float: left; text-align: left;">$fatxt{'28'} $max $numshow</div>
         $pageindex
         </td>
     </tr><tr class="att_h_b">~;
         $rsort = ( $sort == 7 ? -7 : 7 );
         $yymain .= qq~
         <td class="$class_sortattach center att"><b>$fatxt{'6c'}</b></td>
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sortattach center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'40'}</b></a>
         </td>~;
         $rsort = ( $sort == 100 ? -100 : 100 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sorttype center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'40a'}</b></a>
         </td>~;
         $rsort = ( $sort == 5 ? -5 : 5 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sortsize center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'41'}</b></a>
         </td>~;
         $rsort = ( $sort == 6 ? -6 : 6 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sortdate center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'43'}</b></a>
         </td>~;
         $rsort = ( $sort == 8 ? -8 : 8 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sorcount center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'41a'}</b></a>
         </td>~;
         $rsort = ( $sort == 2 ? -2 : 2 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sortsubj center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'44'}</b></a>
         </td>~;
         $rsort = ( $sort == 3 ? -3 : 3 );
         $yymain .= qq~
         <td onclick="location.href='$adminurl?action=manageattachments2;sort=$rsort';" class="$class_sortuser center att">
             <a href="$adminurl?action=manageattachments2;sort=$rsort"><b>$fatxt{'42'}</b></a>
         </td>
     </tr>
     $viewattachments
  </table>
  </div>~;
   
   # Set up the multi-step action     if ($max) { $yymain .= '</form>'; } 
   $time_to_jump = time() + $max_process_time;  
   
   &automaintenance('on');     $yytitle     = "$fatxt{'37'}"; 
     $action_area = 'manageattachments';
   opendir(ATT, $uploaddir) || &admin_fatal_error('cannot_open', "$uploaddir", 1);     AdminTemplate(); 
   my @attachments = sort( grep(/\w+$/, readdir(ATT)) );     return; 
   closedir(ATT);  
   
   fopen(FILE, "$vardir/attachments.txt");  
   @attachmentstxt = <FILE>;  
   fclose(FILE);  
   
   my (%att,@line);  
   foreach (@attachmentstxt) {  
       @line = split(/\|/, $_);  
       $att{$line[7]} = $line[0];  
   }  
   
   my $info;  
   if (!@attachments) {  
       fopen(ATT, ">$vardir/attachments.txt") || &admin_fatal_error("cannot_open","$vardir/attachments.txt", 1);  
       print ATT '';  
       fclose(ATT);  
   
       $info = qq~<br /><i>$fatxt{'48'}.</i>~;  
   
   } else {  
       unlink("$vardir/rem_big_attach.tmp") unless exists $INFO{'next'};  
   
       my (%rem_attachments,@line);  
       for ($a = ($INFO{'next'} || 0); $a < @attachments; $a++) {  
           my $size = sprintf("%.2f", ((-s "$uploaddir/$attachments[$a]") / 1024));  
           if ($size <= $maxsizeattach) {  
               # If the attachment is not too big  
               $info .= qq~<br />$attachments[$a] = $size KB~;  
   
           } elsif (exists $att{$attachments[$a]}) {  
               $rem_attachments{$att{$attachments[$a]}} .= $rem_attachments{$att{$attachments[$a]}} ? "|$attachments[$a]" : $attachments[$a];  
               $info .= qq~<br /><i>$attachments[$a]</i> $fatxt{'1'} = $size KB~;  
           }  
   
           if ($time_to_jump < time() && ($a + 1) < @attachments) {  
               # save the $info of this run until the end of 'RemoveBigAttachments'  
               fopen(FILE, ">>$vardir/rem_big_attach.tmp") || &admin_fatal_error('cannot_open', "$vardir/rem_big_attach.tmp", 1);  
               print $info;  
               fclose(FILE);  
   
               $yySetLocation = qq~$adminurl?action=removebigattachments;maxsizeattach=$maxsizeattach;next=~ . ($a + 1 - &RemoveAttachments(\%rem_attachments));  
               &redirectexit;  
           }  
       }  
   
       &RemoveAttachments(\%rem_attachments);  
   }  
   
   $yymain .= qq~<b>$fatxt{'33'} $maxsizeattach KB.</b><br />~;  
   
   fopen(FILE, "$vardir/rem_big_attach.tmp");  
   $yymain .= join('', <FILE>) . $info;  
   fclose(FILE);  
   unlink("$vardir/rem_big_attach.tmp");  
   
   fopen(FILE, ">$vardir/maxattachsize.txt");  
   print FILE $maxsizeattach;  
   fclose(FILE);  
   
   &automaintenance('off');  
   
   $yytitle = "$fatxt{'35'} $maxsizeattach KB";  
   $action_area = "removebigattachments";  
   &AdminTemplate;  
} }
   
sub Attachments2 { sub DeleteAttachments {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
     if ( !$FORM{'formsession'} ) { automaintenance('on'); }
   
   fopen(AML, "$vardir/attachments.txt");     my %rem_att; 
   my @attachinput = <AML>;     foreach ( keys %FORM ) { 
   fclose(AML);         if ( $_ =~ /^del_(\d+)$/xsm ) { 
   my $max = @attachinput;             my $thread = $1; 
             $rem_att{$thread} = $FORM{$_};
   my $action = $INFO{'action'};             $rem_att{$thread} =~ s/, /|/gsm; 
   my $sort = $INFO{'sort'} || 6;         } 
   my $newstart = $INFO{'newstart'} || 0;         else { next; } 
     }
   if (!$max) {  
       $viewattachments .= qq~<tr><td class="windowbg2" colspan="8"><center><b><i>$fatxt{'48'}</i></b></center></td></tr>~;     RemoveAttachments( \%rem_att ); 
   
   } else {     if ( !$FORM{'formsession'} ) { automaintenance('off'); } 
       $yymain .= qq~  
       <script language="JavaScript1.2" type="text/javascript">     $yySetLocation = 
       <!--       $FORM{'formsession'} 
           function checkAll() {       ? qq~$scripturl?action=viewdownloads;thread=~ 
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {       . ( keys %rem_att )[0] 
                   document.del_attachments.elements[i].checked = true;       . qq~;newstart=$FORM{'newstart'}~ 
                 }       : qq~$adminurl?action=manageattachments2;newstart=$FORM{'newstart'}~; 
           }     redirectexit(); 
           function uncheckAll() {     return; 
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {  
                   document.del_attachments.elements[i].checked = false;  
                 }  
           }  
       //-->  
       </script>  
   
       <form name="del_attachments" action="$adminurl?action=deleteattachment" method="post" style="display: inline;">~;  
   
       my @attachments;  
       if ($sort > 0) { # sort ascending  
           if ($sort == 5 || $sort == 6 || $sort == 8) {  
               @attachments = sort { (split(/\|/, $a))[$sort] <=> (split(/\|/, $b))[$sort]; } @attachinput; # sort size, date, count numerically  
           } elsif ($sort == 100) {  
               @attachments = sort { lc((split(/\./, (split(/\|/, $a))[7]))[1]) cmp lc((split(/\./, (split(/\|/, $b))[7]))[1]); } @attachinput; # sort extension lexically  
           } else {  
               @attachments = sort { lc((split(/\|/, $a))[$sort]) cmp lc((split(/\|/, $b))[$sort]); } @attachinput; # sort lexically  
           }  
       } else { # sort descending  
           if ($sort == -5 || $sort == -6 || $sort == -8) {  
               @attachments = sort { (split(/\|/, $b))[-$sort] <=> (split(/\|/, $a))[-$sort]; } @attachinput; # sort size, date, count numerically  
           } elsif ($sort == -100) {  
               @attachments = sort { lc((split(/\./, (split(/\|/, $b))[7]))[1]) cmp lc((split(/\./, (split(/\|/, $a))[7]))[1]); } @attachinput; # sort extension lexically  
           } else {  
               @attachments = sort { lc((split(/\|/, $b))[-$sort]) cmp lc((split(/\|/, $a))[-$sort]); } @attachinput; # sort lexically  
           }  
       }  
   
       $postdisplaynum = 8;  
       $newstart = (int($newstart / 25)) * 25;  
       $tmpa = 1;  
       if ($newstart >= (($postdisplaynum - 1) * 25)) { $startpage = $newstart - (($postdisplaynum - 1) * 25); $tmpa = int( $startpage / 25 ) + 1; }  
       if ($max >= $newstart + ($postdisplaynum * 25)) { $endpage = $newstart + ($postdisplaynum * 25); } else { $endpage = $max; }  
       if ($startpage > 0) { $pageindex = qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" style="font-weight: normal;">1</a>&nbsp;...&nbsp;~; }  
       if ($startpage == 25) { $pageindex = qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" style="font-weight: normal;">1</a>&nbsp;~;}  
       for ($counter = $startpage; $counter < $endpage; $counter += 25) {  
           $pageindex .= $newstart == $counter ? qq~<b>$tmpa</b>&nbsp;~ : qq~<a href="$adminurl?action=$action;newstart=$counter;sort=$sort" style="font-weight: normal;">$tmpa</a>&nbsp;~;  
           $tmpa++;  
       }  
       $lastpn = int($max / 25) + 1;  
       $lastptn = ($lastpn - 1) * 25;  
       if ($endpage < $max - (25) ) { $pageindexadd = qq~...&nbsp;~; }  
       if ($endpage != $max) { $pageindexadd .= qq~<a href="$adminurl?action=$action;newstart=$lastptn;sort=$sort">$lastpn</a>~; }  
       $pageindex .= $pageindexadd;  
   
       $pageindex = qq~<div class="small" style="text-align: right; vertical-align: middle;">$fatxt{'64'}: $pageindex</div>~;  
   
       $numbegin = ($newstart + 1);  
       $numend = ($newstart + 25);  
       if ($numend > $max) { $numend  = $max; }  
       if ($max == 0) { $numshow = ''; }  
       else { $numshow = qq~($numbegin - $numend)~; }  
   
       my (%attach_gif,$ext);  
       foreach $row (splice(@attachments, $newstart, 25)) {  
           my ($amthreadid, $amreplies, $amthreadsub, $amposter, $amcurrentboard, $amkb, $amdate, $amfn, $amcount) = split(/\|/, $row);  
   
           $amfn =~ /\.(.+?)$/;  
           $ext = $1;  
           unless (exists $attach_gif{$ext}) {  
               $attach_gif{$ext} = ($ext && -e "$forumstylesdir/$useimages/$ext.gif") ? "$ext.gif" : "paperclip.gif";  
           }  
   
           $amdate = &timeformat($amdate);  
           if (length($amthreadsub) > 20) { $amthreadsub = substr($amthreadsub, 0, 20) . "..."; }  
   
           $viewattachments .= qq~  
       <tr>  
       <td class="windowbg2" align="center" valign="middle"><input type="checkbox" name="del_$amthreadid" value="$amfn" /></td>  
       <td class="windowbg2" align="left" valign="middle"><a href="$uploadurl/$amfn" target="_blank"> $amfn</a></td>  
       <td class="windowbg2" align="center" valign="middle"><img src="$imagesdir/$attach_gif{$ext}" border="0" align="bottom" alt="" /></td>  
       <td class="windowbg2" align="right" valign="middle">$amkb KB</td>  
       <td class="windowbg2" align="center" valign="middle">$amdate</td>  
       <td class="windowbg2" align="right" valign="middle">$amcount</td>  
       <td class="windowbg2" align="left" valign="middle"><a href="$scripturl?num=$amthreadid/$amreplies#$amreplies" target="blank">$amthreadsub</a></td>  
       <td class="windowbg2" align="center" valign="middle">$amposter</td>  
       </tr>\n~;  
       }  
   
       $viewattachments .= qq~  
       <tr>  
       <td class="catbg" align="center">  
       <input type="checkbox" name="checkall" id="checkall" value="" onclick="if(this.checked){checkAll();}else{uncheckAll();}" />  
       </td>  
       <td class="catbg" colspan="7">  
       <div class="small" style="float: left; text-align: left;">  
       &lt;= <label for="checkall">$amv_txt{'38'}</label> &nbsp; <input type="submit" value="$admin_txt{'32'}" class="button" />  
       </div>  
       $pageindex  
       </td>  
       </tr>  
       ~;  
   
       $yymain .= qq~  
       <input type="hidden" name="newstart" value="$newstart" />~;  
   }  
   
   my $class_sortattach = $sort =~ /7/   ? 'catbg' : 'windowbg';  
   my $class_sorttype   = $sort =~ /100/ ? 'catbg' : 'windowbg';  
   my $class_sortsize   = $sort =~ /5/   ? 'catbg' : 'windowbg';  
   my $class_sortdate   = $sort =~ /6/   ? 'catbg' : 'windowbg';  
   my $class_sorcount   = $sort =~ /8/   ? 'catbg' : 'windowbg';  
   my $class_sortsubj   = $sort =~ /2/   ? 'catbg' : 'windowbg';  
   my $class_sortuser   = $sort =~ /3/   ? 'catbg' : 'windowbg';  
   
   $yymain .= qq~  
<table border="0" cellspacing="1" cellpadding="8" class="bordercolor" align="center" width="90%">  
   <tr>  
       <td class="titlebg" colspan="8">  
       <img src="$imagesdir/xx.gif" alt="" border="0" />&nbsp;<b>$fatxt{'39'}</b>  
       </td>  
   </tr><tr>  
       <td class="windowbg" colspan="8">  
       <br />  
       <span class="small">$fatxt{'38'}</span>  
       <br /><br />  
       </td>  
   </tr><tr>  
       <td class="titlebg" colspan="8" align="center" width="100%"><b>$fatxt{'55'}</b></td>  
   </tr><tr>  
       <td class="titlebg" colspan="8" width="100%">  
       <div class="small" style="float: left; text-align: left;">$fatxt{'28'} $max $numshow</div>  
       $pageindex  
       </td>  
   </tr>  
   <tr>  
       <td align="center" class="windowbg"><b>$fatxt{'45'}</b></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 7 ? -7 : 7) . qq~';" align="center" class="$class_sortattach" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == 7 ? -7 : 7) . qq~"><b>$fatxt{'40'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 100 ? -100 : 100) . qq~';" align="center" class="$class_sorttype" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == 100 ? -100 : 100) . qq~"><b>$fatxt{'40a'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 5 ? -5 : 5) . qq~';" align="center" class="$class_sortsize" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == -5 ? 5 : -5) . qq~"><b>$fatxt{'41'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 6 ? -6 : 6) . qq~';" align="center" class="$class_sortdate" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == -6 ? 6 : -6) . qq~"><b>$fatxt{'43'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 8 ? -8 : 8) . qq~';" align="center" class="$class_sorcount" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == -8 ? 8 : -8) . qq~"><b>$fatxt{'41a'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 2 ? -2 : 2) . qq~';" align="center" class="$class_sortsubj" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == 2 ? -2 : 2) . qq~"><b>$fatxt{'44'}</b></a></td>  
       <td onclick="location.href='$adminurl?action=manageattachments2;sort=~ . ($sort == 3 ? -3 : 3) . qq~';" align="center" class="$class_sortuser" style="border: 0px; border-style: outset; cursor: pointer;"><a href="$adminurl?action=manageattachments2;sort=~ . ($sort == 3 ? -3 : 3) . qq~"><b>$fatxt{'42'}</b></a></td>  
   </tr>  
   $viewattachments  
</table>~;  
   
   $yymain .= '</form>' if $max;  
   
   $yytitle = "$fatxt{'37'}";  
   $action_area = "manageattachments";  
   &AdminTemplate;  
} }
   
sub DeleteAttachments { sub FullRebuildAttachents {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
   &automaintenance('on') if !$FORM{'formsession'};     if ( !defined $INFO{'boardnum'} ) { 
         automaintenance('on');
   
   my %rem_att;         unlink "$vardir/newattachments.tmp"; 
   foreach (keys(%FORM)) {         $yySetLocation = 
       next unless $_ =~ /^del_(\d+)$/;           qq~$adminurl?action=rebuildattach;topicnum=0;boardnum=0~; 
       my $thread = $1;         redirectexit(); 
       $rem_att{$thread} = $FORM{$_};     } 
       $rem_att{$thread} =~ s/, /|/g;  
   }     # Set up the multi-step action 
     $time_to_jump = time() + $max_process_time;
   
     # Get the board list from the forum.master file
     require "$boardsdir/forum.master";
     @boardlist = sort keys %board;
   
     # Find the current board:
     my $curboard = $boardlist[ $INFO{'boardnum'} ];
   
     # store all downloadcounts in variable
     my %attachments;
     if ( ( -s "$vardir/attachments.txt" ) > 5 ) {
         my ( $atfile, $atcount );
         fopen( ATM, "$vardir/attachments.txt" );
         while (<ATM>) {
             (
                 undef, undef, undef,   undef, undef,
                 undef, undef, $atfile, $atcount
             ) = split /\|/xsm, $_;
             chomp $atcount;
             $attachments{$atfile} = $atcount;
         }
         fclose(ATM);
     }
   
     # Get the topic list.
     fopen( BOARD, "$boardsdir/$curboard.txt" );
     my @topiclist = <BOARD>;
     fclose(BOARD);
   
     my ( $topicnum, @newattachments, $mreplies, $msub, $mname, $mdate, $mfn,
         $nexttopic );
     for my $i ( $INFO{'topicnum'} .. ( @topiclist - 1 ) ) {
         ( $topicnum, undef ) = split /\|/xsm, $topiclist[$i], 2;
         fopen( TOPIC, "$datadir/$topicnum.txt" );
         my @topic = <TOPIC>;
         fclose(TOPIC);
         chomp @topic;
   
         $mreplies = 0;
         foreach (@topic) {
             (
                 $msub, $mname, undef, $mdate, undef, undef, undef,
                 undef, undef,  undef, undef,  undef, $mfn
             ) = split /\|/xsm, $_;
             foreach ( split /,/xsm, $mfn ) {
                 if ( -e "$uploaddir/$_" ) {
                     my $asize = int( ( -s "$uploaddir/$_" ) / 1024 ) || 1;
                     push @newattachments,
  qq~$topicnum|$mreplies|$msub|$mname|$curboard|$asize|$mdate|$_|~
                       . ( $attachments{$_} || 0 ) . qq~\n~;
                 }
             }
             $mreplies++;
         }
   
         if ( time() > $time_to_jump && ( $i + 1 ) < @topiclist ) {
             $nexttopic = $i + 1;
             last;
         }
     }
   
     if (@newattachments) {
         fopen( NEWATM, ">>$vardir/newattachments.tmp" )
           || fatal_error( 'cannot_open', "$vardir/newattachments.tmp",
             1 );
         print {NEWATM} @newattachments or croak "$croak{'print'} NEWATM";
         fclose(NEWATM);
     }
   
     # Prepare to continue...
     if ($nexttopic) { $INFO{'topicnum'} = $nexttopic; }
     else            { $INFO{'boardnum'}++; $INFO{'topicnum'} = 0; }
   
     my $numleft = @boardlist - $INFO{'boardnum'};
     if ( $numleft == 0 ) {
         fopen( NEWATM, "$vardir/newattachments.tmp" );
         @newattachments = <NEWATM>;
         fclose(NEWATM);
   
         fopen( ATM, ">$vardir/attachments.txt" );
         print {ATM}
           sort { ( split /\|/xsm, $a )[6] <=> ( split /\|/xsm, $b )[6] }
             @newattachments
           or croak "$croak{'print'} ATM";
         fclose(ATM);
         unlink "$vardir/newattachments.tmp";
   
         automaintenance('off');
         $yySetLocation = qq~$adminurl?action=remghostattach~;
         redirectexit();
     }
   
     # Continue
     $action_area = 'manageattachments';
     $yytitle     = "$fatxt{'37'}";
   
     $yymain .= qq~
         <br />
         $rebuild_txt{'1'}<br />
         $rebuild_txt{'5'} $max_process_time $rebuild_txt{'6'}<br />
         $rebuild_txt{'9'} ~
       . ( @boardlist - $INFO{'boardnum'} ) . q{/} . @boardlist . qq~<br />
         <br />
         <div id="attachcontinued">
         $rebuild_txt{'2'} <a href="$adminurl?action=rebuildattach;topicnum=$INFO{'topicnum'};boardnum=$INFO{'boardnum'}" onclick="rebAttach();">$rebuild_txt{'3'}</a>
         </div>
     <script type="text/javascript">
         function rebAttach() {
             document.getElementById("attachcontinued").innerHTML = '$rebuild_txt{'4'}';
         }
   
         function attachtick() {
             rebAttach();
             location.href="$adminurl?action=rebuildattach;topicnum=$INFO{'topicnum'};boardnum=$INFO{'boardnum'}";
         }
   
   &RemoveAttachments(\%rem_att);         setTimeout("attachtick()",3000) 
     </script>~;
   
   &automaintenance('off') if !$FORM{'formsession'};     AdminTemplate(); 
     return;
  }
   
  sub RemoveGhostAttach {
     is_admin_or_gmod();
   
   $yySetLocation = $FORM{'formsession'} ? qq~$scripturl?action=viewdownloads;thread=~ . (keys(%rem_att))[0] . qq~;newstart=$FORM{'newstart'}~ : qq~$adminurl?action=manageattachments2;newstart=$FORM{'newstart'}~;     $yymain .= qq~<b>$fatxt{'62'}</b><br /><br />~; 
   &redirectexit;  
     fopen( ATM, "$vardir/attachments.txt" );
     my @attachmentstxt = <ATM>;
     fclose(ATM);
   
     my %att;
     foreach (@attachmentstxt) {
         $att{ ( split /\|/xsm, $_ )[7] } = 1;
     }
   
     opendir DIR, $uploaddir;
     my @filesDIR = grep { /\w+$/xsm } readdir DIR;
     closedir DIR;
   
     $yymain .= qq~$fatxt{'61'}:<br />~;
   
     foreach my $fileinDIR (@filesDIR) {
         if ( !$att{$fileinDIR} && $fileinDIR ne 'index.html' && $fileinDIR ne '.htaccess'  ) {
             unlink "$uploaddir/$fileinDIR";
             $yymain .= qq~<br />$fatxt{'61b'}: $fileinDIR~;
         }
     }
   
     $yymain .= qq~<br /><br /><b>$fatxt{'61a'}</b>~;
     $yytitle     = $fatxt{'61'};
     $action_area = 'manageattachments';
     AdminTemplate();
     return;
} }
   
sub FullRebuildAttachents {  sub RemoveAttachments 
   &is_admin_or_gmod();  {    # remove single or multiple attachments stored in a hash-reference 
     my $count = 0;
     my $ThreadHashref =
       shift; # usage: ${$ThreadHashref}{'threadnum'} = 'filename1|filename2|...'
         # all attachments of thread are included if filname is undefined (undef)
   
     if ( !%{$ThreadHashref} ) { return $count; }
   
     fopen( ATM, "+<$vardir/attachments.txt", 1 )
       || fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 );
     seek ATM, 0, 0;
     my @attachments = <ATM>;
     truncate ATM, 0;
     seek ATM, 0, 0;
     my ( $athreadnum, $afilename, %del_filename );
     foreach (@attachments) {
         ( undef, undef, undef, undef, undef, undef, undef, $afilename, undef ) =
           split /\|/xsm, $_;
         $del_filename{$afilename}++;
     }
     for my $i ( 0 .. ( @attachments - 1 ) ) {
         (
             $athreadnum, undef, undef,      undef, undef,
             undef,       undef, $afilename, undef
         ) = split /\|/xsm, $attachments[$i];
         my $del = 0;
         if ( exists ${$ThreadHashref}{$athreadnum} ) {
             if ( defined ${$ThreadHashref}{$athreadnum} ) {
                 foreach ( split /\|/xsm, ${$ThreadHashref}{$athreadnum} ) {
                     if ( $_ eq $afilename ) { $del = 1; last; }
                 }
             }
             else {
                 $del = 1;
             }
         }
         if ($del) {
   
  # deletes the file only if NO other entry for the same filename is in the attachments.txt
             if ( $del_filename{$afilename} == 1 ) {
                 unlink "$uploaddir/$afilename";
             }
             $del_filename{$afilename}--;
             $count++;
         }
         else {
             print {ATM} $attachments[$i] or croak "$croak{'print'} ATM";
         }
     }
     fclose(ATM);
   
     return $count;
  }
  sub PMAttachments2 {
     is_admin_or_gmod();
   
   unless (defined $INFO{'boardnum'}) {     fopen( PMATTACHLOG, "$vardir/pm.attachments" ); 
       &automaintenance('on');     my @pmAttachInput = <PMATTACHLOG>; 
     fclose(PMATTACHLOG);
     my $max = @pmAttachInput;
   
     my $action   = $INFO{'action'};
     my $sort     = $INFO{'sort'} || 1;
     my $newstart = $INFO{'newstart'} || 0;
   
     if ( !$max ) {
         $viewattachments .=
  qq~<tr><td class="windowbg2 padd-cell center" colspan="6"><b><i>$fatxt{'48a'}</i></b></td></tr>~;
   
     }
     else {
         $yymain .= qq~
         <script type="text/javascript">
             function checkAll() {
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {
                     document.del_attachments.elements[i].checked = true;
                 }
             }
             function uncheckAll() {
                 for (var i = 0; i < document.del_attachments.elements.length; i++) {
                     document.del_attachments.elements[i].checked = false;
                 }
             }
         </script>
   
         <form name="del_attachments" action="$adminurl?action=deletepmattachment" method="post" style="display: inline;">~;
   
         my @pmAttachments;
         if ( $sort > 0 ) {    # sort ascending
             if ( $sort == 2 || $sort == 1 ) {
                 @pmAttachments = sort {
                     ( split /\|/xsm, $a )[$sort]
                       <=> ( split /\|/xsm, $b )[$sort];
                 } @pmAttachInput;    # sort size, date numerically
             }
             elsif ( $sort == 100 ) {
                 @pmAttachments = sort {
                     lc(   ( split /\./xsm, ( split /\|/xsm, $a )[3] )[1] ) cmp
                       lc( ( split /\./xsm, ( split /\|/xsm, $b )[3] )[1] );
                 } @pmAttachInput;    # sort extension lexically
             }
             else {
                 @pmAttachments = sort {
                     lc(   ( split /\|/xsm, $a )[$sort] ) cmp
                       lc( ( split /\|/xsm, $b )[$sort] );
                 } @pmAttachInput;    # sort lexically
             }
         }
         else {                     # sort descending
             if ( $sort == -2 || $sort == -1 ) {
                 @pmAttachments = reverse sort {
                     ( split /\|/xsm, $a )[ -$sort ]
                       <=> ( split /\|/xsm, $b )[ -$sort ];
                 } @pmAttachInput;    # sort size, date numerically
             }
             elsif ( $sort == -100 ) {
                 @pmAttachments = reverse sort {
                     lc(   ( split /\./xsm, ( split /\|/xsm, $a )[3] )[1] ) cmp
                       lc( ( split /\./xsm, ( split /\|/xsm, $b )[3] )[1] );
                 } @pmAttachInput;    # sort extension lexically
             }
             else {
                 @pmAttachments = reverse sort {
                     lc(   ( split /\|/xsm, $a )[ -$sort ] ) cmp
                       lc( ( split /\|/xsm, $b )[ -$sort ] );
                 } @pmAttachInput;    # sort lexically
             }
         }
   
         $postdisplaynum = 8;
         $newstart       = ( int( $newstart / 25 ) ) * 25;
         $tmpa           = 1;
         if ( $newstart >= ( ( $postdisplaynum - 1 ) * 25 ) ) {
             $startpage = $newstart - ( ( $postdisplaynum - 1 ) * 25 );
             $tmpa = int( $startpage / 25 ) + 1;
         }
         if ( $max >= $newstart + ( $postdisplaynum * 25 ) ) {
             $endpage = $newstart + ( $postdisplaynum * 25 );
         }
         else { $endpage = $max; }
         if ( $startpage > 0 ) {
             $pageindex =
  qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" class="norm">1</a>&nbsp;...&nbsp;~;
         }
         if ( $startpage == 25 ) {
             $pageindex =
  qq~<a href="$adminurl?action=$action;newstart=0;sort=$sort" class="norm">1</a>&nbsp;~;
         }
         foreach my $counter ( $startpage .. ( $endpage - 1 ) ) {
             if ( $counter % 25 == 0 ) {
                 $pageindex .=
                   $newstart == $counter
                   ? qq~<b>$tmpa</b>&nbsp;~
                   : qq~<a href="$adminurl?action=$action;newstart=$counter;sort=$sort" class="norm">$tmpa</a>&nbsp;~;
                 $tmpa++;
             }
         }
         $lastpn  = int( $max / 25 ) + 1;
         $lastptn = ( $lastpn - 1 ) * 25;
         if ( $endpage < $max - (25) ) { $pageindexadd = q~...&nbsp;~; }
         if ( $endpage != $max ) {
             $pageindexadd .=
  qq~<a href="$adminurl?action=$action;newstart=$lastptn;sort=$sort">$lastpn</a>~;
         }
         $pageindex .= $pageindexadd;
   
         $pageindex =
  qq~<div class="small" style="line-height: 2.5em; float: right; text-align: right; vertical-align: middle;">$fatxt{'64'}: $pageindex</div>~;
   
         $numbegin = ( $newstart + 1 );
         $numend   = ( $newstart + 25 );
         if   ( $numend > $max ) { $numend  = $max; }
         if   ( $max == 0 )      { $numshow = q{}; }
         else                    { $numshow = qq~($numbegin - $numend)~; }
   
         my ( %attach_gif, $ext );
         foreach my $row ( splice @pmAttachments, $newstart, 25 ) {
             my ( undef, $pmAttachDate, $pmAttachKB, $pmAttachName, $pmAttachUser, undef ) = split /\|/xsm, $row;
             chomp $pmAttachUser;
             if ( $pmAttachName =~ /\.(.+?)$/xsm ) {
                 $ext = $1;
             }
             if ( !exists $attach_gif{$ext} ) {
                 $attach_gif{$ext} =
                   ( $ext && -e "$htmldir/Templates/Forum/$useimages/$ext.gif" )
                   ? "$ext.gif" 
                   : 'paperclip.gif';
             }
   
             $pmthreadid   = $pmAttachDate;
             $pmAttachDate = timeformat($pmAttachDate);
             $pmAttachKB   = NumberFormat($pmAttachKB);
   
             my $pmfna = $pmAttachName;
             if ( length($pmAttachName) > 30 ) {
                 $pmfna = substr( $pmAttachName, 0, 30 ) . q{...};
             }
             $viewattachments .= qq~<tr>
             <td class="windowbg2 center"><input type="checkbox" name="del_$pmthreadid" value="$pmAttachName" /></td>
             <td class="windowbg2"><a href="$pmuploadurl/$pmAttachName" target="_blank">$pmfna</a></td>
             <td class="windowbg2 center"><img src="$imagesdir/$attach_gif{$ext}" class="bottom" alt="" /></td>
             <td class="windowbg2 right">$pmAttachKB KB</td>
             <td class="windowbg2 center">$pmAttachDate</td>
             <td class="windowbg2 center">$pmAttachUser</td>
         </tr>~;
         }
   
         $viewattachments .= qq~<tr>
             <td class="catbg center">
                 <input type="checkbox" name="checkall" id="checkall" value="" onclick="if(this.checked){checkAll();}else{uncheckAll();}" />
             </td>
             <td class="catbg" colspan="5">
                 <div class="small" style="float: left; text-align: left;">
                     &lt;= <label for="checkall">$amv_txt{'38'}</label> &nbsp; <input type="submit" value="$admin_txt{'32'}" class="button" />
                 </div>
         $pageindex
             </td>
         </tr>~;
   
         $yymain .= qq~
         <input type="hidden" name="newstart" value="$newstart" />~;
     }
   
     my $class_sortattach = $sort =~ /3/sm   ? 'catbg' : 'windowbg';
     my $class_sorttype   = $sort =~ /100/sm ? 'catbg' : 'windowbg';
     my $class_sortsize   = $sort =~ /2/sm   ? 'catbg' : 'windowbg';
     my $class_sortdate   = $sort =~ /1/sm   ? 'catbg' : 'windowbg';
     my $class_sortuser   = $sort =~ /4/sm   ? 'catbg' : 'windowbg';
   
     $yymain .= qq~
  <div class="bordercolor rightboxdiv">
  <table class="border-space pad-cell">
     <colgroup>
         <col style="width:8%" />
         <col style="width:30%" />
         <col style="width:10%" />
         <col style="width:12%" />
         <col style="width:30%" />
         <col style="width:15%" />
     </colgroup>
     <tr>
         <td class="titlebg" colspan="6">
             $admin_img{'xx'}&nbsp;<b>$fatxt{'39a'}</b>
         </td>
     </tr><tr>
         <td class="windowbg" colspan="6">
         <div class="pad-more small">$fatxt{'38a'}</div>
         </td>
     </tr><tr>
         <td class="titlebg center" colspan="6"><b>$fatxt{'55a'}</b></td>
     </tr><tr>
          <td class="catbg att_h_b" colspan="6">
         <div class="small" style="float: left; text-align: left;">$fatxt{'28'} $max $numshow</div>
         $pageindex
         </td>
     </tr><tr class="att_h_b">
         <td class="windowbg center"><b>$fatxt{'45'}</b></td>
         <td onclick="location.href='$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 3 ? -3 : 3 )
       . qq~';" class="$class_sortattach center att"><a href="$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 3 ? -3 : 3 )
       . qq~"><b>$fatxt{'40'}</b></a></td>
         <td onclick="location.href='$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 100 ? -100 : 100 )
       . qq~';" class="$class_sorttype center att"><a href="$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 100 ? -100 : 100 )
       . qq~"><b>$fatxt{'40a'}</b></a></td>
         <td onclick="location.href='$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 2 ? -2 : 2 )
       . qq~';" class="$class_sortsize center att"><a href="$adminurl?action=managepmattachments2;sort=~
       . ( $sort == -2 ? 2 : -2 )
       . qq~"><b>$fatxt{'41'}</b></a></td>
         <td onclick="location.href='$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 1 ? -1 : 1 )
       . qq~';" class="$class_sortdate center att"><a href="$adminurl?action=managepmattachments2;sort=~
       . ( $sort == -1 ? 1 : -1 )
       . qq~"><b>$fatxt{'43'}</b></a></td>
         <td onclick="location.href='$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 4 ? -4 : 4 )
       . qq~';" class="$class_sortuser center att"><a href="$adminurl?action=managepmattachments2;sort=~
       . ( $sort == 4 ? -4 : 4 )
       . qq~"><b>$fatxt{'42a'}</b></a></td>
     </tr>
    $viewattachments
  </table>
  </div>~;
   
       unlink "$vardir/newattachments.tmp";     if ($max) { $yymain .= '</form>'; } 
       $yySetLocation = qq~$adminurl?action=rebuildattach;topicnum=0;boardnum=0~;  
       &redirectexit();  
   }  
   
   # Set up the multi-step action  
   $time_to_jump = time() + $max_process_time;  
   
   # Get the board list from the forum.master file  
   require "$boardsdir/forum.master";  
   @boardlist = sort( keys(%board) );  
   
   # Find the current board:  
   my $curboard = $boardlist[$INFO{'boardnum'}];  
   
   # store all downloadcounts in variable  
   my %attachments;  
   if (-s "$vardir/attachments.txt" > 5) {  
       my ($atfile,$atcount);  
       fopen(ATM, "$vardir/attachments.txt");  
       while (<ATM>) {  
           (undef, undef, undef, undef, undef, undef, undef, $atfile, $atcount) =split(/\|/, $_);  
           chomp $atcount;  
           $attachments{$atfile} = $atcount;  
       }  
       fclose(ATM);  
   }  
   
   # Get the topic list.  
   fopen(BOARD, "$boardsdir/$curboard.txt");  
   my @topiclist = <BOARD>;  
   fclose(BOARD);  
   
   my ($topicnum,@newattachments,$mreplies,$msub, $mname, $mdate, $mfn, $nexttopic);  
   for (my $i = $INFO{'topicnum'}; $i < @topiclist; $i++) {  
       ($topicnum, undef) = split(/\|/, $topiclist[$i], 2);  
       fopen(TOPIC, "$datadir/$topicnum.txt");  
       my @topic = <TOPIC>;  
       fclose(TOPIC);  
       chomp(@topic);  
   
       $mreplies = 0;  
       foreach (@topic) {  
           ($msub, $mname, undef, $mdate, undef, undef, undef, undef, undef, undef, undef, undef, $mfn) = split(/\|/, $_);  
           foreach (split(/,/, $mfn)) {  
               if (-e "$uploaddir/$_") {  
                   my $asize = int((-s "$uploaddir/$_") / 1024) || 1;  
                   push (@newattachments, qq~$topicnum|$mreplies|$msub|$mname|$curboard|$asize|$mdate|$_|~ . ($attachments{$_} || 0) . qq~\n~);  
               }  
           }  
           $mreplies++;  
       }  
   
       if (time() > $time_to_jump && ($i + 1) < @topiclist) {  
           $nexttopic = $i + 1;  
           last;  
       }  
   }  
   
   if (@newattachments) {  
       fopen(NEWATM, ">>$vardir/newattachments.tmp") || &admin_fatal_error('cannot_open', "$vardir/newattachments.tmp", 1);  
       print NEWATM @newattachments;  
       fclose(NEWATM);  
   }  
   
   # Prepare to continue...  
   if ($nexttopic) { $INFO{'topicnum'} = $nexttopic; }  
   else { $INFO{'boardnum'}++; $INFO{'topicnum'} = 0; }  
   
   my $numleft = @boardlist - $INFO{'boardnum'};  
   if ($numleft == 0) {  
       fopen(NEWATM, "$vardir/newattachments.tmp");  
       my @newattachments = <NEWATM>;  
       fclose(NEWATM);  
   
       fopen (ATM, ">$vardir/attachments.txt");  
       print ATM sort( { (split /\|/,$a)[6] <=> (split /\|/,$b)[6] } @newattachments);  
       fclose (ATM);  
       unlink "$vardir/newattachments.tmp";  
   
       &automaintenance("off");  
       $yySetLocation = qq~$adminurl?action=remghostattach~;  
       &redirectexit;  
   }  
   
   # Continue  
   $action_area = 'manageattachments';  
   $yytitle = "$fatxt{'37'}";  
   
   $yymain .= qq~  
       <br />  
       $rebuild_txt{'1'}<br />  
       $rebuild_txt{'5'} $max_process_time $rebuild_txt{'6'}<br />  
       $rebuild_txt{'9'} ~ . (@boardlist - $INFO{'boardnum'}) . "/" . @boardlist . qq~<br />  
       <br />  
       <div id="attachcontinued">  
       $rebuild_txt{'2'} <a href="$adminurl?action=rebuildattach;topicnum=$INFO{'topicnum'};boardnum=$INFO{'boardnum'}" onclick="rebAttach();">$rebuild_txt{'3'}</a>  
       </div>  
   <script type="text/javascript" language="JavaScript">  
   <!--  
       function rebAttach() {  
           document.getElementById("attachcontinued").innerHTML = '$rebuild_txt{'4'}';  
       }  
   
       function attachtick() {  
           rebAttach();  
           location.href="$adminurl?action=rebuildattach;topicnum=$INFO{'topicnum'};boardnum=$INFO{'boardnum'}";  
       }  
   
       setTimeout("attachtick()",3000)  
   // -->  
   </script>~;  
   
   &AdminTemplate();     $yytitle     = "$fatxt{'37a'}"; 
     $action_area = 'managepmattachments';
     AdminTemplate();
     return;
} }
   
sub RemoveGhostAttach { sub DeletePMAttachments {
   &is_admin_or_gmod;     is_admin_or_gmod(); 
   
     if ( !$FORM{'formsession'} ) { automaintenance('on'); }
   
     my %rem_att;
     foreach ( keys %FORM ) {
         if ( $_ =~ /^del_(\d+)$/xsm ) {
             my $thread = $1;
             $rem_att{$thread} = $FORM{$_};
             $rem_att{$thread} =~ s/, /|/gsm;
         }
         else { next; }
     }
   
     RemovePMAttachments( \%rem_att );
   
     if ( !$FORM{'formsession'} ) { automaintenance('off'); }
   
     $yySetLocation = qq~$adminurl?action=managepmattachments2;newstart=$FORM{'newstart'}~;
     redirectexit();
     return;
  }
   
  sub RemoveOldPMAttachments {
     is_admin_or_gmod();
   
     my $pmMaxDaysAttach = $FORM{'pmmaxdaysattach'} || $INFO{'pmmaxdaysattach'};
     if ( $pmMaxDaysAttach !~ /^[0-9]+$/xsm ) {
         fatal_error('only_numbers_allowed');
     }
   
     # Set up the multi-step action
     $time_to_jump = time() + $max_process_time;
   
     automaintenance('on');
   
     opendir PMATTACHDIR, $pmuploaddir
       || fatal_error( 'cannot_open', "$pmuploaddir", 1 );
     my @pmAttachments = sort grep { /\w+$/xsm } readdir PMATTACHDIR;
     closedir PMATTACHDIR;
   
     fopen( PMATTACHLOG, "$vardir/pm.attachments" );
     my @pmAttachmentstxt = <PMATTACHLOG>;
     fclose(PMATTACHLOG);
   
     my ( %att, @line );
     foreach (@pmAttachmentstxt) {
         @line = split /\|/xsm, $_;
         $att{ $line[3] } = $line[0];
     }
   
     my $info;
     if ( !@pmAttachments ) {
         fopen( PMATTACHLOG, ">$vardir/pm.attachments" )
           || fatal_error( 'cannot_open', "$vardir/pm.attachments", 1 );
         print {PMATTACHLOG} q{} or croak "$croak{'print'} ATT";
         fclose(PMATTACHLOG);
   
         $info = qq~<br /><i>$fatxt{'48a'}.</i>~;
     }
     else {
         if ( !exists $INFO{'next'} ) { unlink "$vardir/rem_old_pm_attach.tmp"; }
   
         my %rem_attachments;
         for my $aa ( ( $INFO{'next'} || 0 ) .. ( @pmAttachments - 1 ) ) {
   
             # -M => Script start time minus file modification time, in days.
             my $age = sprintf '%.2f', -M "$pmuploaddir/$pmAttachments[$aa]";
             if ( $age <= $pmMaxDaysAttach ) {
   
                 # If the attachment is not too old
                 $info .= qq~<br />$pmAttachments[$aa] = $age $admin_txt{'122'}.~;
   
             }
             elsif ( exists $att{ $pmAttachments[$aa] } ) {
                 $rem_attachments{ $att{ $pmAttachments[$aa] } } .=
                   $rem_attachments{ $att{ $pmAttachments[$aa] } }
                   ? "|$pmAttachments[$aa]" 
                   : $pmAttachments[$aa];
                 $info .=
  qq~<br /><i>$pmAttachments[$aa]</i> $fatxt{'1'} = $age $admin_txt{'122'}.~;
             }
   
             if ( $time_to_jump < time() && ( $aa + 1 ) < @pmAttachments ) {
   
             # save the $info of this run until the end of 'RemoveOldPMAttachments'
                 fopen( FILE, ">>$vardir/rem_old_pm_attach.tmp" )
                   || fatal_error( 'cannot_open',
                     "$vardir/rem_old_pm_attach.tmp", 1 );
                 print $info or croak "$croak{'print'} rem_big_attach";
                 fclose(FILE);
   
                 $yySetLocation =
  qq~$adminurl?action=removeoldpmattachments;pmmaxdaysattach=$pmMaxDaysAttach;next=~
                   . ( $aa + 1 - RemovePMAttachments( \%rem_attachments ) );
                 redirectexit();
             }
         }
         RemovePMAttachments( \%rem_attachments );
     }
   
     automaintenance('off');
   
     $yymain .= qq~<b>$fatxt{'32a'} $pmMaxDaysAttach $fatxt{'58'}.</b><br />~;
   
     fopen( FILE, "$vardir/rem_old_pm_attach.tmp" );
   
     #    $yymain .= join( q{}, <FILE> ) . $info;
     $yymain .= do { local $INPUT_RECORD_SEPARATOR = undef; <FILE> }
       . $info;
     fclose(FILE);
     unlink "$vardir/rem_old_pm_attach.tmp";
   
     fopen( FILE, ">$vardir/oldestpmattach.txt" );
     print {FILE} $pmMaxDaysAttach or croak "$croak{'print'} FILE";
     fclose(FILE);
   
     $yytitle     = "$fatxt{'34a'} $pmMaxDaysAttach";
     $action_area = 'removeoldpmattachments';
     AdminTemplate();
     return;
  }
   
  sub RemoveBigPMAttachments {
     is_admin_or_gmod();
   
   $yymain .= qq~<b>$fatxt{'62'}</b><br /><br />~;     my $pmmaxsizeattach = $FORM{'pmmaxsizeattach'} || $INFO{'pmmaxsizeattach'}; 
     if ( $pmmaxsizeattach !~ /^[0-9]+$/xsm ) {
         fatal_error('only_numbers_allowed');
     }
   
     # Set up the multi-step action
     $time_to_jump = time() + $max_process_time;
   
     automaintenance('on');
   
     opendir ATT, $pmuploaddir
       || fatal_error( 'cannot_open', "$pmuploaddir", 1 );
     my @attachments = sort grep { /\w+$/xsm } readdir ATT;
     closedir ATT;
   
     fopen( FILE, "$vardir/pm.attachments" );
     @pmAttachmentstxt = <FILE>;
     fclose(FILE);
   
     my ( %att, @line );
     foreach (@pmAttachmentstxt) {
         @line = split /\|/xsm, $_;
         $att{ $line[3] } = $line[0];
     }
   
     my $info;
     if ( !@attachments ) {
         fopen( ATT, ">$vardir/pm.attachments" )
           || fatal_error( 'cannot_open', "$vardir/pm.attachments", 1 );
         print {ATT} q{} or croak "$croak{'print'} ATT";
         fclose(ATT);
   
         $info = qq~<br /><i>$fatxt{'48a'}.</i>~;
     }
     else {
         if ( !exists $INFO{'next'} ) { unlink "$vardir/rem_big_pm_attach.tmp"; }
   
         my (%rem_attachments);
         for my $aa ( ( $INFO{'next'} || 0 ) .. ( @attachments - 1 ) ) {
             my $size = sprintf '%.2f',
               ( ( -s "$pmuploaddir/$attachments[$aa]" ) / 1024 );
             if ( $size <= $pmmaxsizeattach ) {
   
                 # If the attachment is not too big
                 $info .= qq~<br />$attachments[$aa] = $size KB~;
   
             }
             elsif ( exists $att{ $attachments[$aa] } ) {
                 $rem_attachments{ $att{ $attachments[$aa] } } .=
                   $rem_attachments{ $att{ $attachments[$aa] } }
                   ? "|$attachments[$aa]" 
                   : $attachments[$aa];
                 $info .=
                   qq~<br /><i>$attachments[$aa]</i> $fatxt{'1'} = $size KB~;
             }
             if ( $time_to_jump < time() && ( $aa + 1 ) < @attachments ) {
   
             # save the $info of this run until the end of 'RemoveBigPMAttachments'
                 fopen( FILE, ">>$vardir/rem_big_pm_attach.tmp" )
                   || fatal_error( 'cannot_open',
                     "$vardir/rem_big_pm_attach.tmp", 1 );
                 print $info or croak "$croak{'print'} rem_big_pm_attach";
                 fclose(FILE);
   
                 $yySetLocation =
  qq~$adminurl?action=removebigpmattachments;pmmaxsizeattach=$pmmaxsizeattach;next=~
                   . ( $aa + 1 - RemovePMAttachments( \%rem_attachments ) );
                 redirectexit();
             }
         }
   
         RemovePMAttachments( \%rem_attachments );
     }
   
     $yymain .= qq~<b>$fatxt{'33a'} $pmmaxsizeattach KB.</b><br />~;
   
     fopen( FILE, "$vardir/rem_big_pm_attach.tmp" );
   
     #    $yymain .= join( q{}, <FILE> ) . $info;
     $yymain .= do { local $INPUT_RECORD_SEPARATOR = undef; <FILE> }
       . $info;
     fclose(FILE);
     unlink "$vardir/rem_big_pm_attach.tmp";
   
     fopen( FILE, ">$vardir/maxpmattachsize.txt" );
     print {FILE} $pmmaxsizeattach or croak "$croak{'print'} FILE";
     fclose(FILE);
   
     automaintenance('off');
   
     $yytitle     = "$fatxt{'33a'} $pmmaxsizeattach KB";
     $action_area = 'removebigpmattachments';
     AdminTemplate();
     return;
  }
   
   fopen(ATM, "$vardir/attachments.txt");  sub RemovePMAttachments { 
   my @attachmentstxt = <ATM>;     # remove single or multiple attachments stored in a hash-reference 
   fclose(ATM);     my $count = 0; 
     my $ThreadHashref =
   my %att;       shift; # usage: ${$ThreadHashref}{'threadnum'} = 'filename1|filename2|...' 
   foreach (@attachmentstxt) {         # all attachments of thread are included if filname is undefined (undef) 
       $att{(split(/\|/, $_))[7]} = 1;  
   }    if ( !%{$ThreadHashref} ) { return $count; }
   
   opendir(DIR, $uploaddir);     fopen( ATM, "+<$vardir/pm.attachments", 1 ) 
   my @filesDIR = grep(/\w+$/, readdir(DIR));       || fatal_error( 'cannot_open', "$vardir/pm.attachments", 1 ); 
   close(DIR);     seek ATM, 0, 0; 
     my @pmAttachments = <ATM>;
   $yymain .= qq~$fatxt{'61'}:<br />~;     truncate ATM, 0; 
     seek ATM, 0, 0;
   foreach my $fileinDIR (@filesDIR) {     my ( $athreadnum, $afilename, %del_filename ); 
       if (!$att{$fileinDIR}) {    foreach (@pmAttachments) {
           unlink "$uploaddir/$fileinDIR";         ( undef, undef, undef, $afilename, undef, undef ) = 
           $yymain .= qq~<br />$fatxt{'61b'}: $fileinDIR~;           split /\|/xsm, $_; 
       }         $del_filename{$afilename}++; 
   }    }
     for my $i ( 0 .. $#pmAttachments ) {
   $yymain .= qq~<br /><br /><b>$fatxt{'61a'}</b>~;         ( 
   $yytitle = $fatxt{'61'};             $athreadnum, undef, undef, $afilename, undef, undef 
   $action_area = 'manageattachments';         ) = split /\|/xsm, $pmAttachments[$i]; 
   &AdminTemplate;         my $del = 0; 
}         if ( exists ${$ThreadHashref}{$athreadnum} ) { 
             if ( defined ${$ThreadHashref}{$athreadnum} ) {
sub RemoveAttachments { # remove single or multiple attachments stored in a hash-reference                 foreach ( split /\|/xsm, ${$ThreadHashref}{$athreadnum} ) { 
   my $count = 0;                     if ( $_ eq $afilename ) { $del = 1; last; } 
   my $ThreadHashref = shift; # usage: ${$ThreadHashref}{'threadnum'} = 'filename1|filename2|...'                 } 
                              # all attachments of thread are included if filname is undefined (undef)             } 
             else {
   return $count if !%$ThreadHashref;                 $del = 1; 
             }
   fopen(ATM, "+<$vardir/attachments.txt", 1) || &admin_fatal_error("cannot_open","$vardir/attachments.txt", 1);         } 
   seek ATM, 0, 0;         if ($del) { 
   my @attachments = <ATM>;  
   truncate ATM, 0;  # deletes the file only if NO other entry for the same filename is in the attachments.txt 
   seek ATM, 0, 0;             if ( $del_filename{$afilename} == 1 ) { 
   my ($athreadnum, $afilename, %del_filename);                 unlink "$pmuploaddir/$afilename"; 
   foreach (@attachments) {             } 
       (undef, undef, undef, undef, undef, undef, undef, $afilename, undef) = split(/\|/, $_);             $del_filename{$afilename}--; 
       $del_filename{$afilename}++;             $count++; 
   }        }
   for ($i = 0; $i < @attachments; $i++) {        else {
       ($athreadnum, undef, undef, undef, undef, undef, undef, $afilename, undef) = split(/\|/, $attachments[$i]);             print {ATM} $pmAttachments[$i] or croak "$croak{'print'} ATM"; 
       my $del = 0;         } 
       if (exists ${$ThreadHashref}{$athreadnum}) {     } 
           if (defined ${$ThreadHashref}{$athreadnum}) {     fclose(ATM); 
               foreach (split(/\|/, ${$ThreadHashref}{$athreadnum})) {  
                   if ($_ eq $afilename) { $del = 1; last; }  
               }  
           } else {  
               $del = 1;  
           }  
       }  
       if ($del) {  
           # deletes the file only if NO other entry for the same filename is in the attachments.txt  
           unlink("$uploaddir/$afilename") if $del_filename{$afilename} == 1;  
           $del_filename{$afilename}--;  
           $count++;  
       } else {  
           print ATM $attachments[$i];  
       }  
   }  
   fclose(ATM);  
   
   $count;    return $count;
} }
   
1;  sub FullRebuildPMAttachments { 
     is_admin_or_gmod();
   
     automaintenance('on');
   
     fopen( ATM, "$vardir/pm.attachments" );
     @pm_attach = <ATM>;
     fclose(ATM);
     foreach my $pmattach ( @pm_attach ) {
         chomp $pmattach;
         ( $atid, $atdate, $atsize, $atfile, $atuser, $atusername ) = split /\|/xsm, $pmattach;
         if ( -e "$pmuploaddir/$atfile" ) {
             push @newattachments, qq~$atid|$atdate|$atsize|$atfile|$atuser|$atusername\n~;
         }
     }
   
     if (@newattachments) {
         fopen( NEWATM, ">>$vardir/newpmattachments.tmp" )
           || fatal_error( 'cannot_open', "$vardir/newpmattachments.tmp",
             1 );
         print {NEWATM} @newattachments or croak "$croak{'print'} NEWATM";
         fclose(NEWATM);
     }
   
     fopen( NEWATM, "$vardir/newpmattachments.tmp" );
     @newattachments = <NEWATM>;
     fclose(NEWATM);
   
     fopen( ATM, ">$vardir/pm.attachments" );
     print {ATM}  @newattachments  or croak "$croak{'print'} ATM";
     fclose(ATM);
     unlink "$vardir/newpmattachments.tmp";
   
     automaintenance('off');
     $yySetLocation = qq~$adminurl?action=remghostpmattach~;
     redirectexit();
   
     return;
  }
   
  sub RemoveGhostPMAttach {
     is_admin_or_gmod();
   
     $yymain .= qq~<b>$fatxt{'62a'}</b><br /><br />~;
   
     fopen( ATM, "$vardir/pm.attachments" );
     my @attachmentstxt = <ATM>;
     fclose(ATM);
   
     my %att;
     foreach (@attachmentstxt) {
         $att{ ( split /\|/xsm, $_ )[3] } = 1;
     }
   
     opendir DIR, $pmuploaddir;
     my @filesDIR = grep { /\w+$/xsm } readdir DIR;
     closedir DIR;
   
     $yymain .= qq~$fatxt{'61c'}:<br />~;
   
     foreach my $fileinDIR (@filesDIR) {
         if ( !$att{$fileinDIR} && $fileinDIR ne 'index.html' && $fileinDIR ne '.htaccess'  ) {
             unlink "$pmuploaddir/$fileinDIR";
             $yymain .= qq~<br />$fatxt{'61b'}: $fileinDIR~;
         }
     }
   
     $yymain .= qq~<br /><br /><b>$fatxt{'61a'}</b>~;
     $yytitle     = $fatxt{'61c'};
     $action_area = 'manageattachments';
     AdminTemplate();
     return;
  }
  1;