1############################################################################### 2# Checkspace.pm # 3# $Date: 12.02.14 $ # 4############################################################################### 5# YaBB: Yet another Bulletin Board # 6# Open-Source Community Software for Webmasters # 7# Version: YaBB 2.6.11 # 8# Packaged: December 2, 2014 # 9# Distributed by: http://www.yabbforum.com # 10# =========================================================================== # 11# Copyright (c) 2000-2014 YaBB (www.yabbforum.com) - All Rights Reserved. # 12# Software by: The YaBB Development Team # 13# with assistance from the YaBB community. # 14############################################################################### 15use CGI::Carp qw(fatalsToBrowser); 16use English '-no_match_vars'; 17our $VERSION = '2.6.11'; 18 19$checkspacepmver = 'YaBB 2.6.11 $Revision: 1611 $'; 20if ( $action eq 'detailedversion' ) { return 1; } 21 22sub checkspace { 23 is_admin_or_gmod(); 24 25 # Free Disk Space Checking 26 if ( $OSNAME =~ /Win/sm ) { 27 open my $fh, q{-|}, 'DIR /-C' or croak "Can't open pipe: $!"; 28 my @x = <$fh>; 29 close $fh or croak "Can't close pipe: $!"; 30 my $lastline = pop @x; 31 32 # should look like: 17 Directory(s), 21305790464 Bytes free 33 return -1 34 if $lastline !~ m/byte/ism; 35 36 # error trapping if output fails. The word byte should be in the line 37 if ( $lastline =~ /^\s+(\d+)\s+(.+?)\s+(\d+)\s+(.+?)\n$/xsm ) { 38 $FreeBytes = $3 - 100_000; 39 } # 100000 bytes reserve 40 if ( $FreeBytes >= 1_073_741_824 ) { 41 $yyfreespace = 42 sprintf( '%.2f', $FreeBytes / ( 1024 * 1024 * 1024 ) ) . ' GB'; 43 } 44 elsif ( $FreeBytes >= 1_048_576 ) { 45 $yyfreespace = 46 sprintf( '%.2f', $FreeBytes / ( 1024 * 1024 ) ) . ' MB'; 47 } 48 else { 49 $yyfreespace = sprintf( '%.2f', $FreeBytes / 1024 ) . ' KB'; 50 } 51 @disk_space = $yyfreespace; 52 } 53 else { 54 open my $dsh, q{-|}, 'df -k .' or croak "Can't open pipe: $!"; 55 @disk_space = <$dsh>; 56 close $dsh or croak "Can't close pipe: $!"; 57 58 map { $_ =~ s/ +/ /gsm } @disk_space; 59 60 open my $ffh, q{-|}, 'find . -noleaf -type f -printf "%s-"' 61 or croak "Can't open pipe: $!"; 62 my @find = <$ffh>; 63 close $ffh or croak "Can't close pipe: $!"; 64 } 65 $hostusername = $hostusername 66 || ( split / +/sm, qx{ls -l YaBB.$yyext} )[2]; 67 my @quota = qx{quota -u $hostusername -v}; 68 $quota[0] =~ s/^ +//sm; 69 $quota[0] =~ s/ / /gsm; 70 $quota[1] =~ s/^ +//sm; 71 $quota[1] =~ s/ / /gsm; 72 my $quota_select = qq~$quota[0]<br />$quota[1]~; 73 74 if ( $quota[2] ) { 75 if ( !$enable_quota ) { $ds = ( split / +/sm, $disk_space[1], 2 )[0]; } 76 $my_q_select = 77 isselected( $i == $enable_quota 78 || ( $ds && $quota[$i] =~ /^$ds/sm ) ); 79 $quota_select .= q~<br /><select name="enable_quota_value" id="enable_quota_value">~; 80 for my $i ( 2 .. ( @quota - 1 ) ) { 81 $quota[$i] =~ s/^ +//sm; 82 $quota[$i] =~ s/ +/ /gsm; 83 $quota_select .= 84 qq~<option value="$i" ~ . $my_q_select . qq~>$quota[$i]</option>~; 85 } 86 $quota_select .= '</select>'; 87 } 88 89 # } 90 91 $ch_spc = ischecked($enable_freespace_check); 92 $ch_enable_q = ischecked($enable_quota); 93 94 @settings = ( 95 { 96 name => $settings_txt{'checkspace'}, 97 id => 'checkspace', 98 items => [ 99 { header => $settings_txt{'freedisk'}, }, 100 { 101 description => 102 qq~<label for="enable_quota">$admin_txt{'quota'}</label>~, 103 input_html => 104q~<input type="checkbox" name="enable_quota" id="enable_quota" value="1" ~ 105 . ( 106 !$quota[2] ? 'disabled="disabled" ' 107 : $ch_enable_q 108 ) 109 . q~/>~, 110 name => 'enable_quota', 111 validate => 'boolean', 112 depends_on => ( 113 !$quota[2] ? [] 114 : [ 115 '!enable_freespace_check', 116 '(findfile_time==0||', 117 'findfile_time==||', 118 'findfile_maxsize==0||', 119 'findfile_maxsize==)' 120 ] 121 ), 122 }, 123 { 124 description => 125qq~<label for="enable_quota_value">$admin_txt{'quota_value'}</label>~, 126 input_html => ( 127 $quota[2] ? $quota_select 128 : q~<input type="text" disabled="disabled" name="enable_quota_value" id="enable_quota_value" value="" style="display:none" />~ 129 ), 130 name => 'enable_quota_value', 131 validate => 'number,null', 132 depends_on => ['enable_quota'], 133 }, 134 { 135 description => 136qq~<label for="hostusername">$admin_txt{'quotahostuser'}</label>~, 137 input_html => 138qq~<input type="text" name="hostusername" id="hostusername" size="20" value="$hostusername" />~, 139 name => 'hostusername', 140 validate => 'text,null', 141 depends_on => ['enable_quota'], 142 }, 143 { 144 description => 145qq~<label for="findfile_time">$admin_txt{'findtime'}</label>~, 146 input_html => 147q~<input type="text" name="findfile_time" id="findfile_time" size="4" value="~ 148 . ( 149 @find ? qq~$findfile_time"~ : '0" disabled="disabled"' 150 ) 151 . qq~ /> $admin_txt{'537'}~, 152 name => 'findfile_time', 153 validate => 'number,null', 154 depends_on => ( 155 @find ? [ '!enable_quota', '!enable_freespace_check' ] 156 : [] 157 ), 158 }, 159 { 160 description => 161qq~<label for="findfile_root">$admin_txt{'findroot'}</label>~, 162 input_html => 163qq~<input type="text" name="findfile_root" id="findfile_root" size="40" value="$findfile_root" ~ 164 . ( @find ? q{} : 'disabled="disabled" ' ) . q~/>~, 165 name => 'findfile_root', 166 validate => 'text,null', 167 depends_on => ( 168 @find ? [ '!enable_quota', '!enable_freespace_check' ] 169 : [] 170 ), 171 }, 172 { 173 description => 174qq~<label for="findfile_maxsize">$admin_txt{'findmax'}</label>~, 175 input_html => 176qq~<input type="text" name="findfile_maxsize" id="findfile_maxsize" size="10" value="$findfile_maxsize" ~ 177 . ( @find ? q{} : 'disabled="disabled" ' ) 178 . q~/> MB~, 179 name => 'findfile_maxsize', 180 validate => 'number,null', 181 depends_on => ( 182 @find ? [ '!enable_quota', '!enable_freespace_check' ] 183 : [] 184 ), 185 }, 186 { 187 description => 188qq~<label for="enable_freespace_check">$admin_txt{'diskspacecheck'}</label>~, 189 input_html => 190qq~<input type="checkbox" name="enable_freespace_check" id="enable_freespace_check" value="1" $ch_spc /><pre>@disk_space</pre>~, 191 name => 'enable_freespace_check', 192 validate => 'boolean', 193 depends_on => [ 194 '!enable_quota', '(findfile_time==0||', 195 'findfile_time==||', 'findfile_maxsize==0||', 196 'findfile_maxsize==)' 197 ], 198 }, 199 ], 200 }, 201 ); 202 chsettings(); 203 $action_area = 'checkspace'; 204 AdminTemplate(); 205 exit; 206} 207 208sub chsettings { 209 is_admin_or_gmod(); 210 211 $yytitle = $admin_txt{'checkspclabel'}; 212 $page = 'checkspace'; 213 214 my @requireorder; # an array for the correct order of the requirements 215 my %requirements; # a hash that says "Y is required by X" 216 217 $yymain .= qq~ 218 <div class="bordercolor rightboxdiv"> 219 <table class="border-space pad-cell" style="margin-bottom:.5em"> 220 <tr> 221 <td class="titlebg"><b>$yytitle</b></td> 222 </tr><tr> 223 <td class="windowbg2"><div class="pad-more">$admin_txt{'347'}</div></td> 224 </tr> 225 </table> 226 </div> 227 <form action="$adminurl?action=checkspace_save" method="post" onsubmit="savealert()" accept-charset="$yymycharset"> 228~; 229 foreach my $tab (@settings) { 230 $yymain .= qq~ 231 <div class="bordercolor rightboxdiv"> 232 <table class="section border-space pad-cell" style="margin-bottom:.5em" id="tab_$tab->{'id'}"> 233 <colgroup> 234 <col span="2" style="width:50%" /> 235 </colgroup> 236 <tr> 237 <td class="titlebg" colspan="2"> 238 $admin_img{'prefimg'} <b>$tab->{'name'}</b> 239 </td> 240 </tr>~; 241 242 foreach my $item ( @{ $tab->{'items'} } ) { 243 if ( $item->{'header'} ) { 244 $yymain .= qq~<tr> 245 <td class="catbg" colspan="2"> 246 <span class="small">$item->{'header'}</span> 247 </td> 248 </tr>~; 249 } 250 elsif ( $item->{'two_rows'} && $item->{'input_html'} ) { 251 $yymain .= qq~<tr> 252 <td class="windowbg2" colspan="2"> 253 $item->{'description'} 254 </td> 255 </tr><tr> 256 <td class="windowbg2" colspan="2"> 257 $item->{'input_html'} 258 </td> 259 </tr>~; 260 } 261 elsif ( $item->{'input_html'} ) { 262 $yymain .= qq~<tr> 263 <td class="windowbg2 vtop"> 264 $item->{'description'} 265 </td> 266 <td class="windowbg2 vtop"> 267 $item->{'input_html'} 268 </td> 269 </tr>~; 270 } 271 272 # Handle settings that require other settings 273 if ( $item->{'depends_on'} && $item->{'name'} ) { 274 foreach my $require ( @{ $item->{'depends_on'} } ) { 275 276# This is somewhat messy, but it works well. 277# We strip off the possible options: inverse, equal, and not equal 278# Then we attach those to this current option in the detailed string for requirements 279# While this data does not really belong with the value, it transfers nicely. 280# We then remove it and reuse it later. 281 my ( $inverse, $realname, $remainder ) = 282 $require =~ m{(\(?\!?)(\w+)(.*)}xsm; 283 if ( !$requirements{$realname} ) { 284 push @requireorder, $realname; 285 } 286 push 287 @{ $requirements{$realname} }, 288 $inverse . $item->{'name'} . $remainder; 289 } 290 } 291 } 292 293 $yymain .= q~ 294 </table> 295 </div>~; 296 } 297 298 my %requirejs; 299 300 my $dependicies = q{}; 301 my $onloadevents; 302 foreach my $ritem (@requireorder) { 303 $dependicies .= qq~ 304 function handleDependent_$ritem() { 305 var isChecked = document.getElementsByName("$ritem")[0].checked; 306 var itemValue = document.getElementsByName("$ritem")[0].value;\n~; 307 308 foreach my $require ( @{ $requirements{$ritem} } ) { 309 310 # && or ||, ( and ) 311 my $AndOr = $require =~ s/\)//xsm ? ')' : q{}; 312 $AndOr .= $require =~ s/\|\|//xsm ? ' ||' : ' &&'; 313 my $C = $require =~ s/\(//xsm ? '(' : q{}; 314 315 # Is false 316 if ( $require =~ s/^\!//xsm ) { 317 $requirejs{$require} .= 318qq~$C\!document.getElementsByName("$ritem")[0].checked$AndOr ~; 319 } 320 321 # Is equal to 322 elsif ( $require =~ s/\=\=(.*)$//xsm ) { 323 $requirejs{$require} .= 324qq~$C\document.getElementsByName("$ritem")[0].value == '$1'$AndOr ~; 325 } 326 327 # Is not equal to 328 elsif ( $require =~ s/\!\=(.*)$//xsm ) { 329 $requirejs{$require} .= 330qq~$C\document.getElementsByName("$ritem")[0].value != '$1'$AndOr ~; 331 } 332 333 # Is true 334 else { 335 $requirejs{$require} .= 336 qq~$C\document.getElementsByName("$ritem")[0].checked$AndOr ~; 337 } 338 $dependicies .= qq~ checkDependent("$require");\n~; 339 } 340 $dependicies .= qq~ } 341 document.getElementsByName("$ritem")[0].onclick = handleDependent_$ritem; 342 document.getElementsByName("$ritem")[0].onkeyup = handleDependent_$ritem; 343~; 344 $onloadevents .= qq~handleDependent_$ritem(); ~; 345 } 346 347 # Hidden "feature": jump directly to a tab by default via the URL bar. 348 $INFO{'tab'} =~ s/\W//gxsm; 349 $default_tab = $INFO{'tab'} || $settings[0]->{'id'}; 350 $yymain .= qq~ 351<div class="bordercolor rightboxdiv"> 352 <table class="border-space pad-cell"> 353 <tr> 354 <td class="titlebg" colspan="2"> 355 $admin_img{'prefimg'} <b>$admin_txt{'10'}</b> 356 </td> 357 </tr><tr> 358 <td class="catbg center pad-cell" colspan="2"> 359 <input class="button" type="submit" value="$admin_txt{'10'}" /> 360 </td> 361 </tr> 362 </table> 363 </div> 364 </form> 365 <script type="text/javascript"> 366 function checkDependent(eid) { 367 var elm = document.getElementsByName(eid)[0];\n~; 368 369 # Loop through each item that depends on something else 370 foreach my $name ( keys %requirejs ) { 371 my $logic = $requirejs{$name}; 372 $logic =~ s/ (&&|\|\|) $//sm; 373 $yymain .= qq~ 374 if (eid == "$name" && ($logic)) { 375 elm.disabled = false; 376 } else if (eid == "$name") { 377 elm.disabled = true; 378 }\n~; 379 } 380 381 $yymain .= qq~ 382 } 383$dependicies 384 window.onload = function(){ $onloadevents}; 385 function undisableAll(node) { 386 var elements = document.getElementsByTagName("input"); 387 for(var i = 0; i < elements.length; i++) { 388 elements[i].disabled = false; 389 } 390 elements = document.getElementsByTagName("textarea"); 391 for( i = 0; i < elements.length; i++) { 392 elements[i].disabled = false; 393 } 394 elements = document.getElementsByTagName("select"); 395 for( i = 0; i < elements.length; i++) { 396 elements[i].disabled = false; 397 } 398 } 399 </script>~; 400 401 return; 402} 403 404sub ischecked { 405 my ($inp) = @_; 406 407 # Return a ref so we can be used like ${ischecked($var)} inside a string 408 if ( $inp == 1 ) { return 'checked="checked"'; } 409 return; 410} 411 412sub isselected { 413 my ($inp) = @_; 414 415 # Return a ref so we can be used like ${ischecked($var)} inside a string 416 if ( $inp == 1 ) { return 'selected="selected"'; } 417 return; 418} 419 420sub checkspace_save { 421 is_admin_or_gmod(); 422 423 $enable_quota = $FORM{'enable_quota'} || '0'; 424 $enable_quota_value = $FORM{'enable_quota_value'} || '0'; 425 $hostusername = $FORM{'hostusername'} || q{}; 426 $findfile_time = $FORM{'findfile_time'} || 0; 427 $findfile_root = $FORM{'findfile_root'} || q{}; 428 $findfile_maxsize = $FORM{'findfile_maxsize'} || 0; 429 $findfile_space = $FORM{'findfile_space'} || '1<>0'; 430 $enable_freespace_check = $FORM{'enable_freespace_check'} || 0; 431 432 if ( $enable_quota && $enable_quota_value > 1 && $hostusername ) { 433 $enable_quota = $enable_quota_value; 434 $findfile_maxsize = 0; 435 $enable_freespace_check = 0; 436 } 437 elsif (-d "$findfile_root" 438 && $findfile_maxsize > 0 439 && !$enable_freespace_check ) 440 { 441 $findfile_space = '1<>0'; 442 $enable_quota = 0; 443 } 444 elsif ($enable_freespace_check) { 445 $findfile_maxsize = 0; 446 $enable_quota = 0; 447 } 448 elsif ( !-d "$findfile_root" || !$findfile_maxsize ) { 449 $findfile_time = 0; 450 $findfile_maxsize = 0; 451 } 452 453 require Admin::NewSettings; 454 SaveSettingsTo('Settings.pm'); 455 456 if ( $action eq 'checkspace_save' ) { 457 $yySetLocation = qq~$adminurl?action=newsettings;page=advanced~; 458 redirectexit(); 459 } 460 return; 461} 462 4631; 464