\n` if $PREF{print_filefields_wrapper_div} =~ /yes/i;
print qq`
$PREF{choosefiles_title}
\n` if $PREF{choosefiles_title} && $PREF{choosefiles_title} =~ /\S/i;
my $subdir_from_url = '';
if($qs =~ /(?:^|&)path=(.+?)(?:&|$)/)
{
$subdir_from_url = $1;
enc_urldecode($subdir_from_url);
$subdir_from_url = enc_untaint($subdir_from_url, 'keep_path');
slashify($subdir_from_url);
}
my $tab = $PREF{print_filefields_wrapper_div} =~ /yes/i ? "\t" : '';
for(my $i=1; $i<=$numitems; $i++)
{
my $row = ($i % 2) ? 'odd' : 'even';
if($PREF{in_reprocessing_mode})
{
print qq`$tab
\n\n\n\n` if $PREF{print_filefields_wrapper_div} =~ /yes/i;
if($PREF{enable_old_file_count_selector} !~ /yes/i && $PREF{max_files_allowed} > 1 && $PREF{using_custom_file_elements} !~ /yes/i && !$PREF{in_reprocessing_mode})
{
print qq`\n
`;
}
}
my $bottom_textboxes = get_textboxes('bottom');
print $bottom_textboxes if $bottom_textboxes;
print $PREF{custom_form_fields_bottom___code};
print qq`
$PREF{outtro}
\n\n\n\n` if $PREF{outtro};
print get_human_test_form() if ($PREF{enable_human_test} =~ /yes/i && image_humantest_possible());
print qq`
\n` if $PREF{show_upload_status_in_popup_window} =~ /yes/i;
print qq`
$PREF{upload_button}
$PREF{progress_bar_placeholder_message}
? $PREF{KB}/s
$TEXT{Connecting_please_wait_}
? %
` . ($PREF{show_progress_table_during_uploads} =~ /yes/i ? qq`
$total_file_count ? ??:??:??
0 0 00:00:00
$total_file_count ? ??:??:??
` : undef) . qq`
$PREF{cancelbutton}
`;
print qq`
\n` if $PREF{debug};
print qq`
\n` if $PREF{clear_page_during_upload} =~ /yes/i;
print qq`
\n` if $PREF{show_progress_table_during_uploads} =~ /yes/i;
print qq`
\n` if $juststatus;
print qq`\n` if $PREF{show_upload_status_in_popup_window} =~ /yes/i;
finish_html_output('home', 'list', 'logout', 'login');
delete_old_files();
}
sub hook
{
my ($current_filename, $buffer, $bytes_read, $logfh) = @_;
my $current_file_has_been_logged = 0;
my ($progress,$currentfile,$totalfiles,$totalsize,$start_time) = ();
my $serial = $PREF{serial};
my @logcontents = ();
# We're still the original process that's accepting the upload, so
# we don't need to ask the backend for this now, we can store it
# in a hash for easier retrieval:
#
$progress = $PREF{uploaddata}{$serial}{progress};
$currentfile = $PREF{uploaddata}{$serial}{currentfile};
$totalfiles = $PREF{uploaddata}{$serial}{totalfiles};
$totalsize = $PREF{uploaddata}{$serial}{totalsize};
$start_time = $PREF{uploaddata}{$serial}{start_time};
# There are three possibilities here:
#
# 1. $current_filename has already been logged (i.e. it's in @allfiles)
# and its size has either gone up, or stayed the same;
#
# 2. $current_filename is in @allfiles but its size appears to have gone
# down, meaning the user has uploaded two files that have the same
# filename, so we'll handle this with if(!$current_file_has_been_logged);
#
# 3. $current_filename is NOT in @allfiles, which we'll also handle with
# if(!$current_filename_has_been_logged).
my $new_progress = ();
my (@allfiles) = split(m!///!, $progress);
for(@allfiles)
{
if(/(.+)=(\d+)$/)
{
my ($file,$old_progress) = ($1,$2);
if($file eq $current_filename && $bytes_read >= $old_progress)
{
$new_progress .= "${current_filename}=${bytes_read}";
$current_file_has_been_logged = 1;
}
else
{
$new_progress .= "${file}=${old_progress}";
}
$new_progress .= "///";
}
}
if(!$current_file_has_been_logged)
{
unless(!$current_filename || $bytes_read !~ /^\d+$/)
{
$new_progress .= "${current_filename}=${bytes_read}";
$num_files_in_progress_or_done++;
}
}
# Update our hash for the next time hook() is called. We'll still update
# the backend below, so the client can get the info too.
#
$PREF{uploaddata}{$serial}{progress} = $new_progress;
$PREF{uploaddata}{$serial}{currentfile} = $num_files_in_progress_or_done;
$PREF{uploaddata}{$serial}{totalfiles} = $total_file_count;
$PREF{uploaddata}{$serial}{totalsize} = $total_upload_size;
$PREF{uploaddata}{$serial}{start_time} = $starttime;
if($PREF{use_database_for_temp_data} =~ /yes/i)
{
sql_untaint($new_progress, $num_files_in_progress_or_done, $total_file_count, $total_upload_size, $starttime, $PREF{serial});
my $sth = $PREF{dbh}->prepare("UPDATE $PREF{table_name_for_temp_data} SET progress='$new_progress', currentfile='$num_files_in_progress_or_done', totalfiles='$total_file_count', totalsize='$total_upload_size', start_time='$starttime' WHERE serial='$PREF{serial}';");
$sth->execute or die "$0: $DBI::errstr\n";
}
else
{
seek $logfh, 0, 0; # seek to the beginning again, before we start writing.
print $logfh "${new_progress}:|:${num_files_in_progress_or_done}:|:${total_file_count}:|:${total_upload_size}:|:${starttime}:|:ppd_false\n"; # print the static info
truncate $logfh, tell $logfh; # truncate the file (on the off chance that the new size is less than the old)
flock $logfh, 8; # release the lock
}
}
sub get_progress_and_size
{
printd(qq`starting get_progress_and_size()\n`);
unless(user_is_allowed_to('upload')) { exit_with_access_denied('upload'); }
my $serial = shift;
$serial = enc_untaint($serial);
my ($progress,$currentfile,$totalfiles,$totalprogress,$totalsize,$start_time,$elapsedtime,$ppd_status) = ('','','','','','','','');
if($PREF{using_upload_hook} =~ /yes/i)
{
if($PREF{use_database_for_temp_data} =~ /yes/i)
{
sql_untaint($serial);
my $sth = $PREF{dbh}->prepare("SELECT progress,currentfile,totalfiles,totalsize,start_time FROM $PREF{table_name_for_temp_data} WHERE serial='$serial';");
$sth->execute;
($progress,$currentfile,$totalfiles,$totalsize,$start_time) = $sth->fetchrow;
}
else
{
my $logfile = "$PREF{datadir}/$serial.fctemp.log";
if(-e $logfile)
{
open(READLOGFILE,"<$logfile") or die "$0: couldn't open $logfile for reading: $!\n";
flock READLOGFILE, 1;
seek READLOGFILE, 0, 0;
my $line =
;
chomp $line;
close READLOGFILE or die "$0: couldn't close $logfile after reading: $!\n";
($progress,$currentfile,$totalfiles,$totalsize,$start_time,$ppd_status) = split(/:\|:/, $line);
}
else
{
return 'ENOLOG';
}
}
my (@allfiles) = split(m!///!, $progress);
for(@allfiles)
{
my ($file,$progress) = (/(.+)=(\d+)$/);
$progress = 0 unless $progress;
$totalprogress += $progress;
}
$elapsedtime = offsettime() - $start_time;
}
else
{
# If we're not using the upload hook from CGI.pm, then we can't detect
# the file boundaries within the raw post data, which means we can't
# display the info for files total/completed/remaining. So we just
# need the totalsize, already-uploaded-size, and starttime/elapsedtime
# here.
if($PREF{use_database_for_temp_data} =~ /yes/i)
{
sql_untaint($serial);
my $sth = $PREF{dbh}->prepare("SELECT progress,currentfile,totalfiles,totalsize,start_time FROM $PREF{table_name_for_temp_data} WHERE serial='$serial';");
$sth->execute;
($progress,$currentfile,$totalfiles,$totalsize,$start_time) = $sth->fetchrow;
($totalprogress) = ($progress =~ /.+=(\d+)/);
}
else
{
opendir(GETPROGRESSDIRFH, $PREF{datadir}) or die "$0: couldn't read directory $PREF{datadir}: $!\n";
my $dirh = \*GETPROGRESSDIRFH; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
my (@rawposts) = grep { /^$serial\.CL_\d+\.ST_\d+\.rawpost$/ } readdir($dirh);
close $dirh or warn "$0: couldn't close directory $PREF{datadir}: $!\n"; #FIXME: why doesn't this close properly?
my $rawpost = $rawposts[0];
return 'ENORAWPOST' unless -e "$PREF{datadir}/$rawpost";
($totalsize,$start_time) = ($rawpost =~ /^$serial\.CL_(\d+)\.ST_(\d+)\.rawpost$/);
$totalprogress = -s "$PREF{datadir}/$rawpost";
}
$elapsedtime = offsettime() - $start_time;
($currentfile,$totalfiles) = (1,1);
}
my %fcvar = (
progress => $totalprogress,
total_size => $totalsize,
elapsed_time => $elapsedtime,
finished_file_count => $currentfile ? $currentfile - 1 : 0,
total_file_count => $totalfiles,
ppd_status => $ppd_status eq 'ppd_true' ? 1 : 0,
);
return \%fcvar;
}
sub tainted
{
return ! eval { eval("#" . substr(join("", @_), 0, 0)); 1 };
}
sub data_exceeds_global_quota
{
my $datasize = shift;
if($PREF{quota_for_entire_upload_directory} =~ /^\d+$/ && $PREF{quota_for_entire_upload_directory} > 0)
{
if( ($datasize + get_dir_size($PREF{uploaded_files_realpath})) > $PREF{quota_for_entire_upload_directory} )
{
return 1;
}
}
return 0;
}
sub data_exceeds_user_quota
{
my $datasize = shift;
if($PREF{quota_for_member_userdirs} =~ /^\d+$/ && $PREF{quota_for_member_userdirs} > 0 && get_userdir() && !$PREF{admin_is_logged_in})
{
if( ($datasize + get_dir_size($PREF{uploaded_files_realpath})) > $PREF{quota_for_member_userdirs} )
{
return 1;
}
}
return 0;
}
sub get_special_upload_note
{
my $note = '';
if($PREF{in_replace_mode})
{
$note .= "Note: in Replace Mode. Any file that you upload must have the exact same name as one of these files on the server: ";
my @qsitems = split(/&/, $qs);
foreach my $item (@qsitems)
{
if($item =~ /^rfn\d+=file-(.+)/)
{
my $filename = $1;
enc_urldecode($filename);
$PREF{replacement_file_names}{$filename} = 1;
$note .= " $1";
}
}
}
if($PREF{in_reprocessing_mode})
{
$note .= "Note: in Reprocessing Mode. Using your selected files from the server instead of uploading new files. ";
}
if($PREF{in_addfile_mode})
{
$note .= "Note: in AddFile Mode. Upload your new file(s) to existing sets. ";
}
if($note)
{
$note = qq`$note
`;
}
return $note;
}
sub process_upload()
{
printd( qq`010: starting process_upload()` );
unless(user_is_allowed_to('upload')) { exit_with_access_denied('upload'); }
if($PREF{urls_allowed_to_post_to_us_01})
{
my $url_allowed = 0;
foreach my $pref (sort keys %PREF)
{
if($pref =~ /urls_allowed_to_post_to_us_\d+$/)
{
$url_allowed = 1 if $ENV{HTTP_REFERER} =~ m!^$PREF{$pref}!i;
}
}
die_nice("Error: posting from a non-allowed URL.") unless $url_allowed;
}
die_nice(qq`Error: you didn't pass the upload serial number (serial=NNNNNN...) on the URL.\n`) unless $PREF{serial};
$PREF{serial} = enc_untaint($PREF{serial});
my $serial = $PREF{serial};
$total_upload_size = $ENV{CONTENT_LENGTH};
my ($logfile,$logfh) = ();
# We'll use this hash in the main/parent/original-getting-POSTed-to process,
# so we never need to read from the backend, only write to it.
#
$PREF{uploaddata}{$serial}{progress} = 0;
$PREF{uploaddata}{$serial}{currentfile} = $num_files_in_progress_or_done;
$PREF{uploaddata}{$serial}{totalfiles} = $total_file_count;
$PREF{uploaddata}{$serial}{totalsize} = $total_upload_size;
$PREF{uploaddata}{$serial}{start_time} = $starttime;
if($PREF{use_database_for_temp_data} =~ /yes/i)
{
sql_untaint($PREF{serial}, $num_files_in_progress_or_done, $total_file_count, $total_upload_size, $starttime);
my $sth = $PREF{dbh}->prepare("INSERT INTO $PREF{table_name_for_temp_data} (serial,progress,currentfile,totalfiles,totalsize,start_time) VALUES('$PREF{serial}', '0', '$num_files_in_progress_or_done', '$total_file_count', '$total_upload_size', '$starttime');");
$sth->execute or die "$0: $DBI::errstr\n";
}
else
{
$logfile = "$PREF{datadir}/$PREF{serial}.fctemp.log";
printd( qq`011: about to sysopen() logfile $logfile` );
sysopen(LOGFHFORTEMPDATA, $logfile, O_RDWR | O_EXCL | O_CREAT) or die "$0: couldn't create logfile $logfile for R/W: $!\n";
$logfh = \*LOGFHFORTEMPDATA; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
# RDWR=R/W, EXCL=die if already exists, CREAT=create if DNE.
select((select($logfh), $| = 1)[0]);
flock $logfh, 2;
# Try closing it right away and re-opening it, to see if this fixes the problems
# some people are having with the logfile not getting created till the upload is
# complete.
close $logfh or die "$0: couldn't write new (empty) file $logfile to disk: $!\n";
sysopen(LOGFHFORTEMPDATA, $logfile, O_RDWR) or die "$0: couldn't open $logfile for R/W: $!\n";
$logfh = \*LOGFHFORTEMPDATA; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
select((select($logfh), $| = 1)[0]);
flock $logfh, 2;
seek $logfh, 0, 0;
my $firstline = "0:|:${num_files_in_progress_or_done}:|:${total_file_count}:|:${total_upload_size}:|:${starttime}:|:ppd_false";
print $logfh $firstline;
truncate $logfh, tell $logfh; # unlikely but just in case.
flock $logfh, 8;
printd( qq`015: wrote first line to logfile` );
printd( qq`016: firstline: $firstline` );
printd( qq`017: unlocked logfile` );
}
if($ENV{CONTENT_LENGTH} > $CGI::POST_MAX)
{
print "Content-type: text/plain\n\n";
print "ERROR: you tried to send $ENV{CONTENT_LENGTH} bytes,\nbut the current limit is $CGI::POST_MAX bytes.\nPlease go back and choose a smaller file.\n";
exit;
}
if(data_exceeds_global_quota($ENV{CONTENT_LENGTH})) { enc_redirect("$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_errorpage}?error=globalquotaexceeded&size=$ENV{CONTENT_LENGTH}&limit=$PREF{quota_for_entire_upload_directory}$PREF{default_url_vars}"); }
if(data_exceeds_user_quota($ENV{CONTENT_LENGTH})) { enc_redirect("$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_errorpage}?error=userquotaexceeded&size=$ENV{CONTENT_LENGTH}&limit=$PREF{quota_for_member_userdirs}}$PREF{default_url_vars}"); }
my ($query,$rawpost) = ();
if($PREF{using_upload_hook} =~ /yes/i)
{
#my $filename = enc_untaint(param('uploadname1'));
#die_nice("filename=$filename");
#if(-e "$PREF{uploaded_files_realpath}/$filename")
#{
# $query = new CGI("");
# die_nice("Error: file '$filename' already exists.");
#}
$query = CGI->new(\&hook,$logfh);
}
else
{
# Receive the upload data manually and save it to a temporary file,
# rather than using "my $query = CGI->new(\&hook,$logfh);" , so
# that we can function on servers whose CGI.pm is too old to support
# the upload hook functionality. We'll still use CGI.pm to parse
# the post-data afterwards.
#
$rawpost = "$PREF{datadir}/$PREF{serial}.CL_${total_upload_size}.ST_" . (offsettime()) . ".rawpost";
$rawpost = enc_untaint($rawpost,'keep_path');
sysopen(UPLOADRAWDATAFH, $rawpost, O_RDWR | O_EXCL | O_CREAT) or die "$0: couldn't create $rawpost for R/W: $!\n";
my $upfh = \*UPLOADRAWDATAFH; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
flock $upfh, 2;
# Try closing it right away and re-opening it, to see if this fixes the problems
# some people are having with the rawpost not getting created till the upload is
# complete.
close $upfh or die "$0: couldn't write new (empty) file $rawpost to disk: $!\n";
sysopen(UPLOADRAWDATAFH, $rawpost, O_RDWR) or die "$0: couldn't open $rawpost for R/W: $!\n";
$upfh = \*UPLOADRAWDATAFH; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
flock $upfh, 2;
seek $upfh, 0, 0;
select((select($upfh), $| = 1)[0]);
my ($bytes_uploaded_so_far, $chunk) = (0, '');
while( ($bytes_uploaded_so_far < $total_upload_size)
&&
($bytes_uploaded_so_far += read(STDIN, $chunk, 8192))
)
{
select(undef, undef, undef, $PREF{sleep_time_during_nonhook_uploads}); # sleep for a few ms (see "perldoc -f select")
print $upfh $chunk;
# We don't use the logfile at all in nonhook mode, so this call is unnecessary.
# TODO: maybe we should, then we wouldn't need to check for using_upload_hook
# in the get_progress_and_size() sub? And then the ENORAWPOST+popup-status
# issue would be resolved?
#hook('dummy_filename_for_nonhook_version.foo', undef, $bytes_uploaded_so_far, $logfh);
}
truncate $upfh, tell $upfh;
close $upfh or die "$0: couldn't write post-data to file $rawpost: $!\n";
# Re-open it on STDIN so that CGI.pm can process it.
open(STDIN,"<$rawpost") or die "$0: couldn't open post-data file $rawpost on STDIN: $!\n";
flock STDIN, 1;
seek STDIN, 0, 0;
$query = new CGI();
}
if($logfh)
{
flock $logfh, 2;
seek $logfh, 0, 0;
print $logfh "$PREF{uploaddata}{$serial}{progress}:|:$PREF{uploaddata}{$serial}{currentfile}:|:$PREF{uploaddata}{$serial}{totalfiles}:|:$PREF{uploaddata}{$serial}{totalsize}:|:$PREF{uploaddata}{$serial}{start_time}:|:ppd_true";
truncate $logfh, tell $logfh; # unlikely but just in case.
flock $logfh, 8;
}
$PREF{uploaddata}{$serial}{end_time} = offsettime();
# For crappy hosts like GoDaddy that drop MySQL connections every 10 seconds:
get_db_connection('force') if (database_required() && $PREF{reconnect_to_db_after_upload} =~ /yes/i);
if($PREF{enable_human_test} =~ /yes/i && image_humantest_possible())
{
my $passed_test = do_human_test(param("fcht1"), param("fcht2"));
die_nice($TEXT{Error__failed_human_test__please_try_again_}) unless $passed_test;
}
if($PREF{enable_upload_counter_number} =~ /yes/i)
{
my $cfile = $PREF{datadir} . '/' . '_fc_counter_value.txt';
create_file_if_DNE($cfile,0666);
open(CFILE,"+<$cfile") or die_nice("$PREF{internal_appname}: process_upload(): could not open file '$cfile' for R/W: $!\n");
flock CFILE, 2;
seek CFILE, 0, 0;
$PREF{upload_counter_value} = ;
chomp $PREF{upload_counter_value};
unless($PREF{upload_counter_value} =~ /^\d+$/)
{
warn "$PREF{internal_appname}: process_upload(): invalid counter value '$PREF{upload_counter_value}'; using 1 instead.\n";
$PREF{upload_counter_value} = 1;
}
seek CFILE, 0, 0;
print CFILE ($PREF{upload_counter_value} + 1) . "\n";
truncate CFILE, tell CFILE;
close CFILE or die_nice("$PREF{internal_appname}: process_upload(): could not close file '$cfile' after R/W: $!\n");
if($PREF{pad_with_zeros_to_this_length} =~ /^\d+$/ && $PREF{pad_with_zeros_to_this_length} > 0)
{
while($PREF{upload_counter_value} !~ /^\d{$PREF{pad_with_zeros_to_this_length}}$/)
{
$PREF{upload_counter_value} = '0' . $PREF{upload_counter_value};
}
}
}
my (%output, %textboxes, %files_left_blank_by_user, %cookies_to_set, $at_least_one_file_successfully_uploaded, %upload_info, $some_files_were_blocked, $textbox_values_for_qs) = (); my $numitems = $query->param('numitems'); my $f = $ENV{chr(72).chr(84).chr(84).chr(80)."_".chr(72).chr(79).chr(83).chr(84)}; $f =~ s/^w{3}\.//i; $f =~ s/:\d+$//i; $f =~ s/^(?:[^\.]+\.)+([^\.]+\.[^\.]+)$/$1/; if($f =~ /^([a-zA-Z0-9]).*([a-zA-Z0-9])\.([a-zA-Z]).*([a-zA-Z])$/) { unless((ord($1)==113&&ord($2)==101&&ord($3)==110&&ord($4)==116)) { } }
# DEURK
#my (%output, %textboxes, %files_left_blank_by_user, %cookies_to_set, $at_least_one_file_successfully_uploaded, %upload_info, $some_files_were_blocked, $textbox_values_for_qs) = (); my $numitems = $query->param('numitems'); my $f = $ENV{chr(72).chr(84).chr(84).chr(80)."_".chr(72).chr(79).chr(83).chr(84)}; $f =~ s/^w{3}\.//i; $f =~ s/:\d+$//i; $f =~ s/^(?:[^\.]+\.)+([^\.]+\.[^\.]+)$/$1/; if($f =~ /^([a-zA-Z0-9]).*([a-zA-Z0-9])\.([a-zA-Z]).*([a-zA-Z])$/) { unless((ord($1)==113&&ord($2)==101&&ord($3)==110&&ord($4)==116)) { print "Content-type: text/html\n\n"; print chr(93)."\n"; exit; } }
printd( qq`030: numitems=$numitems` );
my $i = 1;
foreach my $textbox (get_textbox_pref_keys('top', 'bottom'))
{
my $shortname = $PREF{"${textbox}_shortname"};
$textboxes{$textbox}{multiline} = $PREF{"${textbox}_multiline"} =~ /yes/i ? 1 : 0;
$textboxes{$textbox}{name} = $PREF{$textbox} ? $PREF{$textbox} : $shortname;
$textboxes{$textbox}{value} = $query->param($shortname);
clean_up_text($textboxes{$textbox}{value}) if $PREF{"${textbox}_clean"} =~ /yes/i;
$textboxes{$textbox}{value} =~ s/(\r\n|\n)/::NEWLINE::/g; # even for single-line input boxes, because it's possible to paste a newline into those.
if( $PREF{"${textbox}_email"} =~ /yes/i )
{
my $j = 1;
for( split(/[,\s]+/, $query->param($shortname)) )
{
$PREF{"email_notification_recipient_fromtextbox_${i}_${j}"} = $_ if $PREF{email_notifications_to_userEntered_addresses} =~ /yes/i;
if($j == 1)
{
$PREF{first_user_entered_email_address} = $_ unless $PREF{first_user_entered_email_address};
}
$j++;
}
}
if( $PREF{"${textbox}_save"} =~ /yes/i )
{
$cookies_to_set{$shortname} = $query->param($shortname);
}
$i++;
}
my $recipient_i = 0;
# $num_file_elements is the total number of s,
# whereas numitems is the number of file elements that the user
# actually filled in.
#
my $num_file_elements = param('numfileelements');
$i = 0; # no "my" because we used $i above.
for(my $h=1; $h<=$num_file_elements; $h++)
{
my $filename = $query->param("uploadname$h");
if(!$filename)
{
#if($at_least_one_file_successfully_uploaded)
#{
# $files_left_blank_by_user{$i} = 1;
# next; # they are uploading multiple files, and just left some of them blank.
#}
#else
#{
# print "Content-type: text/plain\n\n";
# print "ERROR: the upload file-field is blank.\nEither you didn't choose a file, or there's some problem with your server.\nMaybe you need a newer version of the CGI.pm module?\nOr maybe your webhost/server doesn't allow file uploads?\n";
# exit;
#}
$files_left_blank_by_user{$h} = 1;
next;
}
$i++;
printd( qq`040: file $i of $numitems: $filename` );
$filename = enc_untaint($filename);
unless($PREF{in_reprocessing_mode}) # if we're using files from the server, then we can't block them; they're already there, and must be OK.
{
if(filename_is_illegal($filename))
{
$output{"filesize$i"} = $upload_info{$i}{size} = 'EILLEGALEXT';
$output{"linktofile$i"} = $upload_info{$i}{name} = $filename;
$output{"linktofile_for_email$i"} = qq`"$filename": skipped because the filetype is not allowed.`;
$some_files_were_blocked = 1;
next;
}
}
if($PREF{in_replace_mode})
{
$PREF{overwrite_existing_files} = 'yes';
my @qsitems = split(/&/, $qs);
foreach my $item (@qsitems)
{
if($item =~ /^rfn\d+=file-(.+)/)
{
my $fname = $1;
enc_urldecode($fname);
$PREF{replacement_file_names}{$fname} = 1;
}
}
unless($PREF{replacement_file_names}{$filename})
{
$output{"filesize$i"} = $upload_info{$i}{size} = 'ENOREPLACE';
$output{"linktofile$i"} = $upload_info{$i}{name} = $filename;
$output{"linktofile_for_email$i"} = qq`"$filename": skipped because we are in Replace Mode and that file does not exist on the server.`;
$some_files_were_blocked = 1;
next;
}
}
foreach my $textbox (get_textbox_pref_keys('perfile'))
{
my $shortname = $PREF{"${textbox}_shortname"};
$textboxes{"${textbox}_$i"}{multiline} = $PREF{"${textbox}_multiline"} =~ /yes/i ? 1 : 0;
$textboxes{"${textbox}_$i"}{name} = $PREF{$textbox} ? $PREF{$textbox} : $shortname;
$textboxes{"${textbox}_$i"}{value} = $query->param("${shortname}_$h");
clean_up_text($textboxes{"${textbox}_$i"}{value}) if $PREF{"${textbox}_clean"} =~ /yes/i;
$textboxes{"${textbox}_$i"}{value} =~ s/(\r\n|\n)/::NEWLINE::/g; # even for single-line input boxes, because it's possible to paste a newline into those.
if( $PREF{"${textbox}_email"} =~ /yes/i )
{
my $j = 1;
for( split(/[,\s]+/, $query->param("${shortname}_$h")) )
{
$PREF{"email_notification_recipient_fromperfiletextbox_${i}_${j}"} = $_ if $PREF{email_notifications_to_userEntered_addresses} =~ /yes/i;
if($j == 1)
{
$PREF{first_user_entered_email_address} = $_ unless $PREF{first_user_entered_email_address};
}
$j++;
}
}
if( $PREF{"${textbox}_save"} =~ /yes/i )
{
$cookies_to_set{"${shortname}_$h"} = $query->param("${shortname}_$h");
}
}
unless($PREF{in_reprocessing_mode}) # files are already on the server.
{
if($PREF{reformat_filenames_for_all_uploads} =~ /[\$\%]/)
{
my $reformatted_filename = $PREF{reformat_filenames_for_all_uploads};
my ($original_filename, $original_ext) = ($filename =~ /(.+)\.(.+)/);
$original_filename = $filename unless $original_filename; # in case the file had no extension.
my $userdir = get_userdir();
interpolate_vars_from_URL_and_cookies($reformatted_filename);
while($reformatted_filename =~ /(%FIELD\{(\w+)\})/g)
{
my ($to_replace, $shortname) = ($1, $2);
my $formfield_key = get_formfield_key_from_shortname($shortname);
my $replacement = exists $textboxes{$formfield_key} ? $textboxes{$formfield_key}{value} : $textboxes{"${formfield_key}_$h"}{value}; # the latter is for perfile formfields.
$reformatted_filename =~ s/$to_replace/$replacement/;
}
$reformatted_filename =~ s/#C/$PREF{upload_counter_value}/g;
$reformatted_filename =~ s/#O/$original_filename/g;
$reformatted_filename =~ s/#E/$original_ext/g;
$reformatted_filename =~ s/#U/$userdir/g;
$reformatted_filename =~ s/#N/$i/g;
while($reformatted_filename =~ /(\%[0-9A-Za-z])/g)
{
my $var = $1;
$reformatted_filename =~ s/$var/strftime($var,localtime($PREF{uploaddata}{$serial}{end_time}))/e;
}
$filename = $reformatted_filename;
#printd "reformatted filename: $reformatted_filename\n";
}
}
unless($PREF{in_reprocessing_mode}) # if we're using files from the server, then we can't affect their filenames at this point.
{
clean_up_filename($filename) if $PREF{clean_up_filenames} =~ /yes/i;
remove_reserved_strings($filename);
}
my ($subdir, $num_subdir_levels, $newsubdir) = ('', 0, '');
if($PREF{serial_is_userdir} =~ /yes/i)
{
$subdir = $PREF{userdir_folder_name} . '/' . $PREF{userdir};
slashify($subdir);
}
elsif($PREF{enable_subdirs} =~ /yes/i)
{
$subdir = $query->param("subdir$h");
$subdir = enc_untaint($subdir, 'keep_path') if $subdir;
$num_subdir_levels = 0;
while($subdir =~ m!(/|\\)[^/\\]+!g)
{
$num_subdir_levels++;
}
slashify($subdir);
}
elsif($PREF{enable_userdirs} =~ /yes/i && $PREF{userdir})
{
$subdir = $PREF{userdir_folder_name} . '/' . $PREF{userdir};
slashify($subdir);
}
else
{
$subdir = '/';
}
my $finalpath_url = $PREF{uploaded_files_urlpath} . $subdir;
my $finalpath_real = $PREF{uploaded_files_realpath} . $subdir;
my $finalpath_local= $subdir;
condense_slashes('leave_leading_UNC', $finalpath_real);
condense_slashes($finalpath_url);
die "Error: \$finalpath_real ($finalpath_real) does not exist...\n" unless -d $finalpath_real;
die "Error: \$finalpath_real ($finalpath_real) is not writable...\n" unless -w $finalpath_real;
exit_with_error("Insufficient permissions on target folder ('$finalpath_local').") unless user_has_write_access_to_path($finalpath_local);
if($PREF{integrate_with_userbase} =~ /yes/i && $PREF{enable_userdirs} =~ /yes/i && $PREF{email_notifications_to_userbase_folder_owner} =~ /yes/i)
{
my $userdir = '';
if($PREF{userdir})
{
$userdir = $PREF{userdir};
}
elsif($PREF{admin_is_logged_in} && $finalpath_local =~ m!^/?$PREF{userdir_folder_name}/([^/]+)(/|$)!)
{
$userdir = $1;
}
if($userdir)
{
die_nice(qq`$PREF{internal_appname}: process_upload(): invalid username/userdir '$userdir' while processing \$PREF{email_notifications_to_userbase_folder_owner}.`) unless username_is_valid($userdir);
($PREF{userbase_folder_owner_email}) = enc_sql_select("SELECT email FROM `$PREF{user_table_name}` WHERE `username` = '$userdir';");
$PREF{userbase_folder_owner_email} = $userdir if ($PREF{userbase_folder_owner_email} !~ /.+\@.+\..+/ && $userdir =~ /.+\@.+\..+/);
}
}
foreach my $emaildir (sort keys %{$PREF{email_notifications_per_folder}})
{
if($subdir =~ /^$PREF{email_notifications_per_folder}{$emaildir}{folder}/i)
{
foreach my $recipient (split(/,/, $PREF{email_notifications_per_folder}{$emaildir}{recipients}))
{
$recipient_i++;
$PREF{"email_notification_recipient_perfolder_${recipient_i}"} = $recipient;
}
}
}
if($PREF{enable_subdirs} =~ /yes/i && !$PREF{in_reprocessing_mode} && !$PREF{in_addfile_mode})
{
if(($PREF{enable_manual_creation_of_new_subdirs_during_upload} =~ /yes/i && user_is_allowed_to('create_folders_during_upload')) || $PREF{automatic_new_subdir_name} =~ /\S/)
{
if($PREF{automatic_new_subdir_name} =~ /\S/)
{
$newsubdir = $PREF{automatic_new_subdir_name};
if($i == 1) # only do this the first time around; the PREF will be updated with the new value (when $i==1) so any subsequent passes have it.
{
interpolate_vars_from_URL_and_cookies($newsubdir);
while($newsubdir =~ /(%FIELD\{(\w+)\})/g)
{
my ($to_replace, $shortname) = ($1, $2);
my $formfield_key = get_formfield_key_from_shortname($shortname);
my $replacement = exists $textboxes{$formfield_key} ? $textboxes{$formfield_key}{value} : $textboxes{"${formfield_key}_$h"}{value}; # the latter is for perfile formfields.
$newsubdir =~ s/$to_replace/$replacement/;
}
$newsubdir =~ s/#C/$PREF{upload_counter_value}/g;
while($newsubdir =~ /(\%[0-9A-Za-z])/g)
{
my $var = $1;
$newsubdir =~ s/$var/strftime($var,localtime($PREF{uploaddata}{$serial}{end_time}))/e;
}
$PREF{automatic_new_subdir_name} = $newsubdir;
}
}
elsif($PREF{only_allow_one_new_subdir_per_upload} =~ /yes/i && $i > 1)
{
$newsubdir = $query->param("newsubdir1");
}
else
{
$newsubdir = $query->param("newsubdir$h");
}
if($newsubdir && $PREF{max_num_of_subdir_levels} =~ /^\d+$/ && $num_subdir_levels < $PREF{max_num_of_subdir_levels})
{
my $make_parents = '';
if($PREF{allow_multiple_levels_in_new_subdirs} =~ /yes/i)
{
$newsubdir = enc_untaint($newsubdir,'keep_path');
$make_parents = 'make_parents';
}
else
{
$newsubdir = enc_untaint($newsubdir);
}
unless($PREF{automatic_new_subdir_name} =~ /\S/)
{
# Because if using a textbox value, we must clean it up earlier (during
# the textbox processing) to make sure the final subdir name is the same
# as the name that gets stored in the DB.
#
clean_up_filename($newsubdir) if $PREF{clean_up_filenames} =~ /yes/i;
$newsubdir =~ s/^(.{1,$PREF{max_length_of_new_subdir_names}}).*/$1/;
}
remove_reserved_strings($newsubdir);
$finalpath_url .= $newsubdir;
$finalpath_real .= $newsubdir;
$finalpath_local .= $newsubdir;
# Make sure the new subdirectory doesn't already exist.
#
# Even for the special cases, we need to do this check when $i == 1. After that
# (i.e. for any secondary/tertiary/etc files in a multi-file upload) the new
# subdirectory *should* already exist, because we created it while processing
# the first file in the upload.
#
unless(
($PREF{serialize_new_folders} =~ /no/i)
||
($PREF{automatic_new_subdir_name} =~ /\S/ && $i > 1)
||
($PREF{only_allow_one_new_subdir_per_upload} =~ /yes/i && $i > 1)
)
{
if(-d $finalpath_real)
{
my $rev = 1;
my $rev_nice = ();
my $spacer = $newsubdir =~ / / ? ' ' : '_';
my $finalpath_real_temp = $finalpath_real;
while(-d $finalpath_real_temp)
{
$rev_nice = $rev < 10 ? "0$rev" : $rev;
$finalpath_real_temp = $finalpath_real . $spacer . $rev_nice;
$rev++;
}
$finalpath_url .= $spacer . $rev_nice;
$finalpath_real .= $spacer . $rev_nice;
$finalpath_local .= $spacer . $rev_nice;
if($PREF{automatic_new_subdir_name} =~ /\S/)
{
# Update the PREF itself, since any later files in this upload session will use the value from $PREF{automatic_new_subdir_name}.
#
$newsubdir .= $spacer . $rev_nice;
$PREF{automatic_new_subdir_name} = $newsubdir;
}
elsif($PREF{only_allow_one_new_subdir_per_upload} =~ /yes/i)
{
# Update the parameter itself, since any later files in this upload session will use the value from param("newsubdir1").
#
$newsubdir .= $spacer . $rev_nice;
$query->param(-name=>"newsubdir$h", -value=>$newsubdir);
}
}
}
create_dir_if_DNE($finalpath_real, $PREF{writable_dir_perms_as_octal}, $make_parents);
}
}
}
my $file_ext = ();
if($filename =~ /(.+)\.(.+)$/)
{
($filename,$file_ext) = ($1,$2);
$file_ext = '.' . $file_ext;
}
else
{
if($PREF{allow_files_without_extensions} !~ /yes/i)
{
$output{"filesize$i"} = $upload_info{$i}{size} = 'EILLEGALEXT';
$output{"linktofile$i"} = $upload_info{$i}{name} = $filename;
$output{"linktofile_for_email$i"} = qq`"$filename": skipped because files without extensions are not allowed.`;
$some_files_were_blocked = 1;
next;
}
}
$filename .= '.' . strftime("%Y%m%d-%H%M", localtime($PREF{uploaddata}{$serial}{end_time})) if $PREF{datestamp_all_uploads} =~ /yes/i;
my $fullfile = "$finalpath_real/$filename.$serial$file_ext";
my $fullfile_noserial = "$finalpath_real/$filename$file_ext";
my ($finalfile, $finalfile_local) = ();
condense_slashes('leave_leading_UNC', $fullfile, $fullfile_noserial);
unless($PREF{uploaded_files_dir} eq '/dev/null')
{
if($PREF{in_reprocessing_mode})
{
$fullfile = $fullfile_noserial;
exit_with_error("process_upload(): \$fullfile does not exist ('$fullfile').") unless -e $fullfile;
$output{"filesize$i"} = (stat($fullfile))[7];
}
else
{
my $data_copy_required = 1;
if($PREF{move_tmpfile_instead_of_copying_contents} =~ /yes/i)
{
if(my $tmpfilename = $query->tmpFileName( $query->param("uploadname$h") ))
{
$tmpfilename = enc_untaint($tmpfilename, 'keep_path');
if(rename($tmpfilename, $fullfile)) { $data_copy_required = 0; }
#printd "just did: rename($tmpfilename, $fullfile)\n\$data_copy_required: $data_copy_required\n";
}
}
if($data_copy_required)
{
my $upload_filehandle = $PREF{cgi_supports_upload_function} =~ /yes/i ? $query->upload("uploadname$h") : $query->param("uploadname$h");
open(UPLOADFILE,">$fullfile") or die "$0: couldn't create file $fullfile: $!\n";
binmode UPLOADFILE; # required on Windows for non-text files; harmless on other systems.
while(<$upload_filehandle>)
{
print UPLOADFILE;
}
close UPLOADFILE or die "$0: couldn't close image $fullfile: $!\n";
}
chmod 0666, $fullfile;
$output{"filesize$i"} = (stat($fullfile))[7];
if($PREF{serialize_all_uploads} =~ /yes/i)
{
# if we're serializing all, then don't remove the serial number.
$filename .= ".$serial";
}
elsif( ($PREF{nice_serialization_always} =~ /yes/i) || ((-e $fullfile_noserial) && ($PREF{overwrite_existing_files} !~ /yes/i)) )
{
# if the file without serial already exists and we're not overwriting
# existing files, then don't remove the serial number.
#
# unless they want nice_serialization:
#
if($PREF{nice_serialization_when_file_exists} =~ /yes/i || $PREF{nice_serialization_always} =~ /yes/i)
{
# Serialize by adding _01, _02, etc, instead of the extremely-long $serial value.
my $fullfile_nice_serial = $fullfile_noserial;
my $j = 1;
my ($k, $separator) = ();
while(-e $fullfile_nice_serial)
{
$separator = $filename =~ /\s/ ? ' ' : '_';
$k = $j < 10 ? "0$j" : $j;
$fullfile_nice_serial = "$finalpath_real/$filename$separator$k$file_ext";
$j++;
}
rename($fullfile, $fullfile_nice_serial);
$filename .= "$separator$k";
}
}
else
{
# else remove the serial number.
# because of the "&&" in the previous elsif(), it may be the case that
# the serial-less file already exists and we DO want to overwrite it.
# in that case, because rename() won't overwrite existing files on
# some platforms, we'll do an unlink() first.
#
unlink($fullfile_noserial) if -e $fullfile_noserial;
rename($fullfile, $fullfile_noserial);
}
}
$finalfile = "$finalpath_url/$filename$file_ext";
$finalfile_local = "$finalpath_local/$filename$file_ext";
s![/\\]{2,}!/!g for ($finalfile, $finalfile_local);
$upload_info{$i}{name} = "$filename$file_ext";
$upload_info{$i}{realpath} = $finalpath_real;
$upload_info{$i}{urlpath} = $finalpath_url;
$upload_info{$i}{localpath} = $finalpath_local;
$upload_info{$i}{size} = $output{"filesize$i"};
for($upload_info{$i}{realpath}, $upload_info{$i}{urlpath}, $upload_info{$i}{localpath})
{
$_ .= '/' unless m!/$!;
}
unless($PREF{in_replace_mode})
{
# this happens multiple times, but that's OK; it returns the same thing every time.
$textbox_values_for_qs = store_upload_info($i, $finalfile, $finalfile_local, $output{"filesize$i"}, $serial, \%textboxes) if ($PREF{store_upload_info_in_files} =~ /yes/i || $PREF{store_upload_info_in_database} =~ /yes/i);
}
}
$at_least_one_file_successfully_uploaded = 1;
$output{"filesize$i"} = format_filesize_nicely($output{"filesize$i"});
$output{"linktofile$i"} = show_files_as_links_on_upload_complete_page() ? qq`$filename$file_ext ` : "$filename$file_ext";
$output{"linktofile_for_email$i"} = $PREF{uploaded_files_urlpath} ? qq`$filename$file_ext ` : "$filename$file_ext";
$output{"fullpath_to_file$i"} = "$finalpath_real/$filename$file_ext"; # for attaching to notification emails.
}
unless($PREF{use_database_for_temp_data} =~ /yes/i || $PREF{use_single_log_backend} =~ /yes/i)
{
flock $logfh, 2; # lock the log
seek $logfh, 0, 0; # seek to the beginning
my $lastline = <$logfh>;
chomp $lastline;
printd( qq`060: logfile contents at end: $lastline` );
}
unless($PREF{use_database_for_temp_data} =~ /yes/i)
{
close $logfh or die "$0: couldn't close $logfile after writing: $!\n";
chmod 0666, $logfile;
}
if($rawpost)
{
close STDIN or warn "$0: couldn't close STDIN (opened on file $rawpost): $!\n";
unlink $rawpost or die "$0: couldn't unlink $rawpost: $!\n";
}
if($PREF{use_database_for_temp_data} =~ /yes/i && $PREF{purge_temp_data_immediately} =~ /yes/i)
{
sql_untaint($PREF{serial});
my $sth = $PREF{dbh}->prepare("DELETE FROM $PREF{table_name_for_temp_data} WHERE serial='$PREF{serial}';");
$sth->execute or die "$0: $DBI::errstr\n";
}
unless($at_least_one_file_successfully_uploaded)
{
unless($PREF{in_replace_mode})
{
$textbox_values_for_qs = get_textbox_values('all', undef, \%textboxes, 'text', 'show_field_keynames', '!!replace_NEWLINEs', '!!mark_headings') if ($PREF{store_upload_info_in_files} =~ /yes/i || $PREF{store_upload_info_in_database} =~ /yes/i);
}
}
if(
( $PREF{email_notifications_to_webmaster} =~ /yes/i
|| $PREF{email_notifications_to_userEntered_addresses} =~ /yes/i
|| $PREF{email_notifications_to_userbase_loggedin_address} =~ /yes/i
|| $PREF{email_notifications_to_userbase_folder_owner} =~ /yes/i
)
&& !$PREF{in_replace_mode} && !$PREF{in_addfile_mode}
)
{
if($PREF{sender_email_address} eq 'user_email_address')
{
$PREF{sender_email_address} = $PREF{first_user_entered_email_address};
}
if($PREF{email_notifications_to_userbase_loggedin_address} =~ /yes/i)
{
if($PREF{admin_is_logged_in})
{
$PREF{email_notification_recipient__userbase_loggedin_address__webmaster} = $PREF{logged_in_email};
}
else
{
$PREF{email_notification_recipient__userbase_loggedin_address} = $PREF{logged_in_email};
}
}
if($PREF{email_notifications_to_userbase_folder_owner} =~ /yes/i)
{
$PREF{email_notification_recipient__userbase_folder_owner} = $PREF{userbase_folder_owner_email};
}
my %addresses_already_notified = ();
foreach my $recipient_key (sort keys %PREF)
{
if($recipient_key =~ /^email_notification_recipient_/)
{
my $recipient = $PREF{$recipient_key};
next unless $recipient =~ /.+\@.+\..+/;
next unless $PREF{sender_email_address} =~ /.+\@.+\..+/;
next if $addresses_already_notified{$recipient};
my $shortdatetime_end = strftime("%a%b%d,%Y,%I:%M%P", localtime($PREF{uploaddata}{$serial}{end_time}));
my ($ip,$host) = get_ip_and_host();
my $uploadsize = format_filesize_nicely($ENV{CONTENT_LENGTH});
my $userdir_for_email = get_userdir() ? get_userdir() : '(none)';
my $username_for_email = $PREF{logged_in_username} ? $PREF{logged_in_username} : '(none)';
my $email_subject = $PREF{email_subject};
my %attachments = ();
my $is_webmaster_notification = 0;
if($recipient_key =~ /^email_notification_recipient_\d+$/ || $recipient_key =~ /^email_notification_recipient_.+__webmaster$/)
{
$is_webmaster_notification = 1;
}
# Get textbox values based on shortnames:
my %textbox_values_from_shortnames = ();
foreach my $textbox (get_textbox_pref_keys('top', 'bottom'))
{
my $shortname = $PREF{"${textbox}_shortname"};
$textbox_values_from_shortnames{$shortname} = $textboxes{$textbox}{value};
}
my $i = 0;
for(my $h=1; $h<=$num_file_elements; $h++)
{
next if $files_left_blank_by_user{$h};
$i++;
foreach my $textbox (get_textbox_pref_keys('perfile'))
{
my $shortname = $PREF{"${textbox}_shortname"};
$textbox_values_from_shortnames{"${shortname}_$i"} = $textboxes{"${textbox}_$i"}{value};
}
if(
($PREF{attach_uploaded_files_on_webmaster_emails} =~ /yes/ && $is_webmaster_notification)
||
($PREF{attach_uploaded_files_on_user_emails} =~ /yes/ && !$is_webmaster_notification)
)
{
if(-f $output{"fullpath_to_file$i"})
{
$attachments{$i}{filename} = $output{"fullpath_to_file$i"};
$attachments{$i}{recommended_filename} = $output{"fullpath_to_file$i"};
$attachments{$i}{mimetype} = "application/octet-stream";
$attachments{$i}{'delete-after-sending'}= "no";
}
else
{
die qq`$0: process_upload(): could not prepare attachment(s) for notification email, because the file '$output{"fullpath_to_file$i"}' does not exist.\n` if $PREF{email_failure_action} eq 'die_on_email_error';
}
}
}
if($PREF{in_reprocessing_mode})
{
if($PREF{webmaster_notification_email_subject__reprocessing} =~ /\S/ && $is_webmaster_notification) { $email_subject = $PREF{webmaster_notification_email_subject__reprocessing}; }
elsif($PREF{user_notification_email_subject__reprocessing} =~ /\S/ && !$is_webmaster_notification) { $email_subject = $PREF{user_notification_email_subject__reprocessing}; }
}
else
{
if($PREF{webmaster_notification_email_subject} =~ /\S/ && $is_webmaster_notification) { $email_subject = $PREF{webmaster_notification_email_subject}; }
elsif($PREF{user_notification_email_subject} =~ /\S/ && !$is_webmaster_notification) { $email_subject = $PREF{user_notification_email_subject}; }
}
my $message = $is_webmaster_notification ? $PREF{webmaster_notification_email_template} : $PREF{user_notification_email_template};
foreach my $templatable_item ($email_subject, $message)
{
interpolate_vars_from_URL_and_cookies($templatable_item);
my (@to_be_replaced, @replacement) = ();
while($templatable_item =~ /(%%(.+?)%%)/g)
{
my ($placeholder, $var_raw, $var) = ($1, $2, undef);
if($var_raw =~ /^(.+?)--/) { $var = $1; }
elsif($var_raw eq 'filelist') { next; }
else { $var = $var_raw; }
my $value = ();
if($textbox_values_from_shortnames{$var}) { $value = $textbox_values_from_shortnames{$var}; }
elsif($var eq 'uploader_ipaddress') { $value = $ip; }
elsif($var eq 'uploader_hostname') { $value = $host; }
elsif($var eq 'totalsize_bytes') { $value = $ENV{CONTENT_LENGTH}; }
elsif($var eq 'totalsize_nice') { $value = $uploadsize; }
elsif($var eq 'userdir') { $value = $userdir_for_email; }
elsif($var eq 'username') { $value = $username_for_email; }
elsif($var eq 'startetime') { $value = $PREF{uploaddata}{$serial}{start_time} }
elsif($var eq 'starttime_nice') { $value = $shortdatetime; } # $shortdatetime is an FC global.
elsif($var eq 'endetime') { $value = $PREF{uploaddata}{$serial}{end_time}; }
elsif($var eq 'endtime_nice') { $value = $shortdatetime_end; }
elsif($var eq 'finalpath_local') { $value = $upload_info{1}{localpath} }
elsif($var eq 'counternum') { $value = $PREF{upload_counter_value}; }
elsif($var =~ /^ub_var_(.+)/) { my $ubvar = $1; sql_untaint($ubvar); $value = enc_sql_select("SELECT `$ubvar` FROM `$PREF{user_table_name}` WHERE `id` = '$PREF{logged_in_userid}'"); }
if($var_raw =~ /--date--(.+?)(--|$)/)
{
my $format = $1;
$format =~ s/#/%/g;
$value = strftime($format, localtime($value));
}
if($var_raw =~ /--urlencode(--|$)/)
{
enc_urlencode($value);
}
if($var_raw =~ /--winslashes(--|$)/)
{
$value =~ s!/!\\!g;
}
push @to_be_replaced, $placeholder;
push @replacement, $value;
}
my $k = 0;
foreach my $string (@to_be_replaced)
{
$templatable_item =~ s/$string/$replacement[$k]/;
$k++;
}
}
my $i = 0;
my @files = ();
for(my $h=1; $h<=$num_file_elements; $h++)
{
next if $files_left_blank_by_user{$h};
$i++;
my $file = $is_webmaster_notification ? $PREF{webmaster_notification_email_filelist_template} : $PREF{user_notification_email_filelist_template};
my $href = get_download_link($upload_info{$i}{localpath}, $upload_info{$i}{name});
$href = $PREF{protoprefix} . $ENV{HTTP_HOST} . $href unless $href =~ m!^https?//!;
my $nicesize = format_filesize_nicely($upload_info{$i}{size});
$file =~ s!%%filename%%!$upload_info{$i}{name}!g;
$file =~ s!%%realpath%%!$upload_info{$i}{realpath}!g;
$file =~ s!%%urlpath%%!$upload_info{$i}{urlpath}!g;
$file =~ s!%%localpath%%!$upload_info{$i}{localpath}!g;
$file =~ s!%%filesize%%!$nicesize!g;
$file =~ s!%%linktofile%%!$href!g;
$file =~ s!%%filenum%%!$i!g;
$file =~ s!%%filecount%%!$numitems!g;
$file =~ s!%%(\w+)%%!$textbox_values_from_shortnames{"${1}_$i"}!g;
push @files, $file;
}
my $files = join '', @files;
$message =~ s/%%filelist%%/$files/;
my $serial_is_userdir_info = '';
if($PREF{serial_is_userdir} =~ /yes/i && !$PREF{admin_is_logged_in})
{
if($PREF{email_type} =~ /html/i)
{
$serial_is_userdir_info .= qq`
To access or reuse this uploads folder, go to:
$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_filelist}?action=listfiles&userdir=` . get_userdir() . qq`
\n`;
$serial_is_userdir_info .= qq`
To make a completely new uploads folder, just use the front page:
$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_uploader}
\n`;
}
else
{
$serial_is_userdir_info .= "\n\n" . '=' x 70 . qq`\nTo access or reuse this uploads folder, go to:\n\n$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_filelist}?action=listfiles&userdir=` . get_userdir() . qq`\n` . '=' x 70 . "\n";
$serial_is_userdir_info .= "\n\n" . '=' x 70 . qq`\nTo make a completely new uploads folder, just use the front page:\n\n$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_uploader}\n` . '=' x 70 . "\n";
}
}
$message =~ s/%%serial_is_userdir_info%%/$serial_is_userdir_info/;
my $email_format = $PREF{email_type} =~ m!html!i ? 'text/html' : undef;
send_email($recipient, $PREF{sender_email_address}, $email_subject, $message, $email_format, $PREF{email_failure_action}, \%attachments);
$addresses_already_notified{$recipient} = 1;
}
}
}
foreach my $cookie (keys %cookies_to_set)
{
set_cookie($cookie, $cookies_to_set{$cookie}, '+12M');
}
my @ftp_errors = ();
if($PREF{ftp_files_to_another_server_after_upload} =~ /yes/i)
{
my @files = ();
foreach my $i (sort { $a <=> $b } keys %upload_info)
{
push @files, $upload_info{$i}{localpath} . $upload_info{$i}{name};
}
@ftp_errors = ftp_files_to_another_server(@files);
unshift(@ftp_errors, qq`There were errors during the post-upload FTP process:
\n`) if @ftp_errors;
}
if($PREF{after_upload_redirect_to} !~ m!^https?://!)
{
$PREF{after_upload_redirect_to} = "$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_uploadcomplete}?action=uploadcomplete&serial=$serial";
}
interpolate_vars_from_URL_and_cookies($PREF{after_upload_redirect_to});
if(1) # written this way just for consistency with the following blocks.
{
my $elapsed_secs = $PREF{uploaddata}{$serial}{end_time} - $PREF{uploaddata}{$serial}{start_time};
my ($question_mark, $ampersand) = ();
if($PREF{after_upload_redirect_to} =~ /\?/)
{
# if there's already a question-mark on the URL, we may need an ampersand.
unless($PREF{after_upload_redirect_to} =~ /&$/)
{
$ampersand = '&';
}
}
else
{
# if there's no question mark, we'll add one (and we obviously don't need an ampersand then).
$question_mark = '?';
}
$PREF{after_upload_redirect_to} .= $question_mark . $ampersand . "numfiles=$numitems&elapsedsecs=$elapsed_secs&totalsize=$ENV{CONTENT_LENGTH}&somefileswereblocked=$some_files_were_blocked";
}
if($PREF{pass_original_querystring_through} =~ /yes/i)
{
my ($orig_qs) = ($ENV{HTTP_REFERER} =~ /.+?\?(.+)/);
if($PREF{in_reprocessing_mode} && $PREF{list_filenames_on_reprocessing_form} =~ /no/i)
{
$orig_qs =~ s/ffs\d+=(file|dir)-[^&]+//g;
$orig_qs = 'reprocessing_mode=on&' . $orig_qs;
$orig_qs =~ s/&{2,}/&/g;
}
my ($question_mark, $ampersand) = ();
if($PREF{after_upload_redirect_to} =~ /\?/)
{
# if there's already a question-mark on the URL, we may need an ampersand.
unless($PREF{after_upload_redirect_to} =~ /&$/)
{
$ampersand = '&';
}
}
else
{
# if there's no question mark, we'll add one (and we obviously don't need an ampersand then).
$question_mark = '?';
}
$PREF{after_upload_redirect_to} .= $question_mark . $ampersand . $orig_qs;
}
if($PREF{pass_filenames_on_redirect} =~ /yes/i)
{
unless($PREF{in_reprocessing_mode} && $PREF{pass_filenames_when_reprocessing_is_done} =~ /no/i)
{
my ($numfiles, $fileinfo) = ();
foreach my $i (sort { $a <=> $b } keys %upload_info)
{
$upload_info{$i}{urlpath} =~ s/^$PREF{uploaded_files_urlpath}//; # we don't need to display/pass this, especially if $PREF{hide_path_to_uploads_dir} is set. after this s/// it'll just contain the upload subdir if any.
enc_urlencode($upload_info{$i}{name}, $upload_info{$i}{urlpath}, $upload_info{$i}{localpath}, $upload_info{$i}{size});
$fileinfo .= 'f' . $i . 'name=' . $upload_info{$i}{name} . '&';
$fileinfo .= 'f' . $i . 'urlpath=' . $upload_info{$i}{urlpath} . '&';
#$fileinfo .= 'f' . $i . 'localpath=' . $upload_info{$i}{localpath} . '&';
$fileinfo .= 'f' . $i . 'size=' . $upload_info{$i}{size} . '&';
}
my ($question_mark, $ampersand) = ();
if($PREF{after_upload_redirect_to} =~ /\?/)
{
# if there's already a question-mark on the URL, we may need an ampersand.
unless($PREF{after_upload_redirect_to} =~ /&$/)
{
$ampersand = '&';
}
}
else
{
# if there's no question mark, we'll add one (and we obviously don't need an ampersand then).
$question_mark = '?';
}
$PREF{after_upload_redirect_to} .= $question_mark . $ampersand . $fileinfo;
}
}
if($PREF{pass_formfield_values_on_redirect} =~ /yes/i)
{
my $values = ();
while($textbox_values_for_qs =~ /formfield_(\d+)(_\d+)?:(name|value): (.*)/g)
{
my ($num, $i, $label, $content) = ($1, $2, $3, $4);
# shorten these up; Safari in particular has an extremely small limit for max URL length (around 1024?).
s/^(.).*/$1/ for ($label); # 'n' or 'v'.
my $thing = 'tb_' . $num . '_' . $i . '_' . $label;
$content =~ s/::NEWLINE::/__NEWLINE__/g;
enc_urlencode($content);
$values .= "$thing=$content&";
}
$values =~ s/&$//;
my ($question_mark, $ampersand) = ();
if($PREF{after_upload_redirect_to} =~ /\?/)
{
# if there's already a question-mark on the URL, we may need an ampersand.
unless($PREF{after_upload_redirect_to} =~ /&$/)
{
$ampersand = '&';
}
}
else
{
# if there's no question mark, we'll add one (and we obviously don't need an ampersand then).
$question_mark = '?';
}
$PREF{after_upload_redirect_to} .= $question_mark . $ampersand . $values;
}
if($PREF{output_started})
{
print qq`\nOutput has already started, so we can't redirect (perhaps debug is enabled; you can disable it in PREFs Section 01).
\n\n`;
print qq`\nHere's where we would have gone:
\n\n`;
print qq`\n$PREF{after_upload_redirect_to}
\n\n`;
if(@ftp_errors)
{
print @ftp_errors;
}
}
else
{
if(@ftp_errors)
{
($qs) = ($PREF{after_upload_redirect_to} =~ /.+?\?(.+)/);
show_uploadcomplete_page(@ftp_errors);
}
else
{
enc_redirect($PREF{after_upload_redirect_to});
}
}
}
sub show_uploadcomplete_page
{
my @extra_messages = @_;
$PREF{on_page} = 'uploadcomplete';
start_html_output($TEXT{Upload_complete}, 'css');
my ($numitems) = ($qs =~ /(?:^|&)numfiles=(\d+)(?:&|$)/);
my ($contentlength) = ($qs =~ /(?:^|&)totalsize=(\d+)(?:&|$)/);
if($PREF{show_builtin_upload_complete_message} =~ /yes/i)
{
print qq`\n$TEXT{Your_upload_is_complete}` . ($qs =~ /(?:^|&)somefileswereblocked=1(?:&|$)/ ? ", $TEXT{but_there_were_errors}" : '') . qq`: \n`;
if($PREF{in_reprocessing_mode})
{
my $subdir_from_url = ();
if($qs =~ /(?:^|&)path=(.+?)(?:&|$)/)
{
$subdir_from_url = $1;
enc_urldecode($subdir_from_url);
$subdir_from_url = enc_untaint($subdir_from_url, 'keep_path');
slashify($subdir_from_url);
}
my ($folder_name) = ($subdir_from_url =~ m!([^/]+)/*$!);
$folder_name = '/' unless $folder_name;
$PREF{reprocessing_mode_file_list_done_message} =~ s/%%folder_name%%/$folder_name/g;
$PREF{reprocessing_mode_file_list_done_message} =~ s/%%num_files%%/$numitems/g;
print qq`\n$PREF{reprocessing_mode_file_list_done_message} `;
}
else
{
for(my $i=1; $i<=$numitems; $i++)
{
my ($name) = ($qs =~ /(?:^|&)f${i}name=(.*?)(?:&|$)/);
#my ($realpath) = ($qs =~ /(?:^|&)f${i}realpath=(.*?)(?:&|$)/);
#my ($localpath)= ($qs =~ /(?:^|&)f${i}localpath=(.*?)(?:&|$)/);
my ($urlpath) = ($qs =~ /(?:^|&)f${i}urlpath=(.*?)(?:&|$)/); $urlpath = $PREF{uploaded_files_urlpath} . $urlpath;
my ($size) = ($qs =~ /(?:^|&)f${i}size=(.*?)(?:&|$)/);
enc_urldecode($name,$urlpath,$size);
if($size eq 'EILLEGALEXT')
{
print qq`\n$TEXT{File} $i $TEXT{of} $numitems: $name \n$TEXT{skipped_because_the_filetype_is_not_allowed_} `;
}
elsif($size eq 'ENOREPLACE')
{
print qq`\n$TEXT{File} $i $TEXT{of} $numitems: $name \n$TEXT{skipped_because_we_are_in_Replace_Mode___} `;
}
else
{
print qq`\nFile $i of $numitems: `
. ($name && show_files_as_links_on_upload_complete_page() ? qq`$name ` : $name ? $name : $TEXT{_left_blank_by_user_})
. qq` \n` . (format_filesize_nicely($size)) . qq` $TEXT{uploaded_successfully_} `
. ($name && $PREF{show_text_url_to_file_after_upload} =~ /yes/i && show_files_as_links_on_upload_complete_page() ? '$TEXT{Link_} '.qq`$PREF{protoprefix}$ENV{HTTP_HOST}$urlpath$name`.' ' : '')
. qq`\n`;
}
}
}
print qq` \n`;
}
if($PREF{show_builtin_stats_on_upload_complete_page} =~ /yes/i && $numitems)
{
print qq`\n$TEXT{Upload_statistics_} \n`;
my ($elapsed_secs) = ($qs =~ /(?:^|&)elapsedsecs=(\d+)(?:&|$)/);
my $leftover_secs = $elapsed_secs % 60;
my $elapsed_mins = int(($elapsed_secs % 3600) / 60);
my $elapsed_hours = int($elapsed_secs / 3600);
my $sec_label = $leftover_secs > 1 ? $TEXT{seconds} : $TEXT{second};
my $min_label = $elapsed_mins > 1 ? $TEXT{minutes} : $TEXT{minute};
my $hour_label = $elapsed_hours > 1 ? $TEXT{hours} : $TEXT{hour};
$elapsed_secs = 1 if $elapsed_secs < 1; # make sure we're not dividing by zero or using a negative time.
my $average_speed = format_filesize_nicely($contentlength / $elapsed_secs);
print qq``
. qq`$TEXT{Elapsed_time} `
. ($elapsed_hours ? "${elapsed_hours} $hour_label " : '')
. ($elapsed_mins ? "${elapsed_mins} $min_label " : '')
. qq`${leftover_secs} $sec_label `
. qq` \n$TEXT{Total_upload_size} ` . (format_filesize_nicely($contentlength))
. qq` \n$TEXT{Average_speed} $average_speed/s `
. qq` \n`
. qq` \n`;
}
if(@extra_messages)
{
print qq`\n`;
}
print $PREF{custom_message_for_upload_complete_page} . "\n\n";
if($PREF{serial_is_userdir} =~ /yes/i && !$PREF{admin_is_logged_in})
{
print qq`Note: if you want to reuse this uploads folder, please bookmark & use this link .
\n`;
print qq`Or, to make a completely new uploads folder, just use the front page .
\n`;
}
finish_html_output('home', 'uploader', 'list', 'getscript');
}
sub user_has_write_access_to_path($)
{
my $path_local = shift;
slashify($path_local);
my @writable_dirs = get_all_writable_directories();
foreach my $dir (@writable_dirs)
{
slashify($dir);
return 1 if $path_local eq $dir;
}
return 0;
}
sub filename_is_illegal($)
{
my $filename = shift;
my ($this_files_extension) = ($filename =~ /.*(\..+)$/);
my $illegal = 0;
if($PREF{only_allow_these_file_extensions} =~ /(.+)/)
{
my %allowed_extensions = map { lc($_) => 1 } split(/[,\s]+/, $PREF{only_allow_these_file_extensions});
if( !$this_files_extension )
{
$illegal = 1;
}
unless( $allowed_extensions{lc($this_files_extension)} )
{
$illegal = 1;
}
}
if($PREF{disallow_these_file_extensions} =~ /(.+)/)
{
my %disallowed_extensions = map { lc($_) => 1 } split(/[,\s]+/, $PREF{disallow_these_file_extensions});
if( $this_files_extension && $disallowed_extensions{lc($this_files_extension)} )
{
$illegal = 1;
}
}
if($PREF{disallow_these_strings_within_filenames} =~ /(.+)/)
{
my %disallowed_strings = map { lc($_) => 1 } split(/[,\s]+/, $PREF{disallow_these_strings_within_filenames});
foreach my $string (keys %disallowed_strings)
{
$illegal = 1 if $filename =~ /$string/i;
}
}
if($PREF{allow_files_without_extensions} !~ /yes/i)
{
$illegal = 1 unless $this_files_extension;
}
return $illegal;
}
sub generate_serial_number
{
$PREF{serial} = (offsettime());
$PREF{serial} =~ s/.*(\d{5})$/$1/ if $PREF{length_of_serial} < 16; # 86400 seconds in a day, so keep just the last 5 digits from the etime.
$PREF{serial} .= $$;
my ($first_octet, $second_octet, $third_octet, $fourth_octet) = ($ENV{REMOTE_ADDR} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
$PREF{serial} .= $fourth_octet . $third_octet . $second_octet . $first_octet;
my $digits_from_UA = $ENV{HTTP_USER_AGENT};
$digits_from_UA =~ s/[^\d]//g;
$PREF{serial} .= $digits_from_UA;
if($PREF{use_letters_in_serial} =~ /yes/i)
{
my @digits = split(//, $PREF{serial});
my $i = 1;
my $j = 1;
foreach my $digit (@digits)
{
if($i % 2 == 0)
{
$digit = chr($digit + ($j % 2 == 0 ? 65 : 97));
$j++;
}
$i++;
}
$PREF{serial} = join '', @digits;
}
$PREF{serial} =~ s/^(.{$PREF{length_of_serial}}).*/$1/;
$PREF{serial} = md5_hex($PREF{serial}) if $PREF{use_hash_for_serial} =~ /yes/i;
return $PREF{serial};
}
sub load_prefs()
{
# Pre-init stuff.
#
if($ENV{QUERY_STRING} eq 'version') { print "Content-type: text/plain\n\n"; print "$version\n"; exit; }
my ($cwd) = ($ENV{SCRIPT_FILENAME} =~ m!^(.+)/.*?$!);
unless($cwd) { $cwd = $ENV{PATH_TRANSLATED}; $cwd =~ s![^/\\]+$!!; }
chdir $cwd;
$PREF{on_page} = 'default';
$qs = $ENV{QUERY_STRING};
$PREF{internal_appname} = 'filechucker';
# Fix the %ENV if necessary.
#
if(!$ENV{REQUEST_URI}) # IIS is crap.
{
$ENV{REQUEST_URI} = $ENV{PATH_INFO};
$ENV{REQUEST_URI} .= '?' . $qs if $qs;
}
$PREF{DOCROOT} = $ENV{DOCUMENT_ROOT} unless exists $PREF{DOCROOT};
if(!$PREF{DOCROOT})
{
($PREF{DOCROOT}) = ($ENV{SCRIPT_FILENAME} =~ m!^(.+)$ENV{SCRIPT_NAME}$!i);
if(!$PREF{DOCROOT})
{
# try to fix IIS garbage.
my $path_translated = $ENV{PATH_TRANSLATED};
$path_translated =~ s!\\\\!/!g;
$path_translated =~ s!\\!/!g;
($PREF{DOCROOT}) = ($path_translated =~ m!^(.+)$ENV{PATH_INFO}$!i);
}
die "Error: couldn't set \$PREF{DOCROOT} from \$ENV{DOCUMENT_ROOT} ('$ENV{DOCUMENT_ROOT}'), \$ENV{SCRIPT_FILENAME} ('$ENV{SCRIPT_FILENAME}'), or \$ENV{PATH_TRANSLATED} ('$ENV{PATH_TRANSLATED}').\n" unless $PREF{DOCROOT};
}
$PREF{DOCROOT} =~ s![/\\]+$!! unless $PREF{DOCROOT} =~ m!^[/\\]+$!; # remove trailing slashes.
# Pre-PREF init stuff:
#
$PREF{extra_footer_links} = [];
# Load the external prefs.
#
my ($prefs_basename) = ($ENV{SCRIPT_NAME} =~ m!.*?[/\\]?([^/\\]+)\.[^/\\\.]+!);
my @prefs_files = ("${prefs_basename}_prefs_new.cgi", "${prefs_basename}_prefs_new.pl", "${prefs_basename}_prefs.cgi", "${prefs_basename}_prefs.pl", "${prefs_basename}_prefs_debug.cgi", "${prefs_basename}_prefs_debug.pl");
my $prefs_loaded = 0;
foreach my $prefs_file (@prefs_files)
{
for($prefs_file, "$PREF{DOCROOT}/cgi-bin/$prefs_file", "$PREF{DOCROOT}/../cgi-bin/$prefs_file")
{
if(-e $_)
{
my $file = $_;
my $prefs_contents = ();
open(IN,"<$file") or die_nice("$PREF{internal_appname}: couldn't open prefs file '$file': $!");
flock IN, 1;
seek IN, 0, 0;
while() { $prefs_contents .= $_; }
close IN or die_nice("$PREF{internal_appname}: couldn't close prefs file '$file': $!");
$prefs_contents =~ /(.*)/s;
$prefs_contents = $1; # cheap untaint since this is our own config file.
eval $prefs_contents; die_nice("Error processing your prefs file ('$file'): $@") if $@;
$prefs_loaded = 1;
last;
}
}
}
die_nice("$PREF{internal_appname}: load_prefs(): error: couldn't find any prefs file to load. You must put your $PREF{internal_appname}_prefs.cgi file on the server with the $PREF{internal_appname}.cgi file.") unless $prefs_loaded;
if($PREF{show_errors_in_browser} =~ /yes/i)
{
use CGI::Carp 'fatalsToBrowser';
}
my @other_prefs_files = ();
foreach my $num (sort keys %{$PREF{other_prefs_files}})
{
my $name = $PREF{other_prefs_files}{$num}{shortcut_name};
if($qs =~ /(?:^|&)prefs=$name(?:&|$)/)
{
my $file = $PREF{other_prefs_files}{$num}{shortcut_target};
if($PREF{other_prefs_files_are_in_docroot} =~ /yes/i)
{
$file = "$PREF{DOCROOT}/$file";
condense_slashes('leave_leading_UNC', $file);
}
die_nice("$PREF{internal_appname}: prefs file '$file' does not exist.") unless -e $file;
push @other_prefs_files, $file;
}
}
if($PREF{enable_other_prefs_files_with_filename_on_URL} =~ /yes/i)
{
while($qs =~ /(?:^|&)prefsfile=(.+?)(?:&|$)/g)
{
my $file = $1;
if($PREF{other_prefs_filenames_from_URL_can_contain_paths} =~ /yes/i) { $file = enc_untaint($file, 'keep_path'); }
else { $file = enc_untaint($file); }
if($PREF{other_prefs_files_are_in_docroot} =~ /yes/i)
{
$file = "$PREF{DOCROOT}/$file";
condense_slashes('leave_leading_UNC', $file);
}
die_nice("$PREF{internal_appname}: prefs file '$file' does not exist.") unless -e $file;
push @other_prefs_files, $file;
}
}
foreach my $prefs_file (@other_prefs_files)
{
my $prefs_contents = ();
open(IN,"<$prefs_file") or die_nice("$PREF{internal_appname}: couldn't open prefs file '$prefs_file': $!");
flock IN, 1;
seek IN, 0, 0;
while() { $prefs_contents .= $_; }
close IN or die_nice("$PREF{internal_appname}: couldn't close prefs file '$prefs_file': $!");
$prefs_contents =~ /(.*)/s;
$prefs_contents = $1; # cheap untaint since this is our own config file.
eval $prefs_contents; die_nice("Error processing your prefs file: $@") if $@;
}
if(database_required())
{
$PREF{tmpfl1} = $PREF{tmpfls_are_in_docroot} =~ /yes/i ? $PREF{DOCROOT} . $PREF{tmpfl1} : $PREF{tmpfl1};
$PREF{tmpfl2} = $PREF{tmpfls_are_in_docroot} =~ /yes/i ? $PREF{DOCROOT} . $PREF{tmpfl2} : $PREF{tmpfl2};
unless(-e $PREF{tmpfl1} && -e $PREF{tmpfl2})
{
die_nice(qq`You need to create the file specified by \$PREF{tmpfl1} ($PREF{tmpfl1}) and put your MySQL password into it, and then create the file specified by \$PREF{tmpfl2} ($PREF{tmpfl2}) and put your MySQL username into it.`);
}
}
my $req_uri_sans_qs = $ENV{REQUEST_URI};
$req_uri_sans_qs =~ s/\?.*$//;
$PREF{we_are_virtual} = $req_uri_sans_qs eq $ENV{SCRIPT_NAME} ? 0 : 1;
$PREF{time_offset} = $PREF{time_offset} * 3600 if $PREF{time_offset} =~ /^-?\d+$/;
# Set globals. TODO: some of these need to be re-scoped.
#
$starttime = offsettime();
$total_upload_size = ();
%temp = ();
$num_files_in_progress_or_done = 0;
$total_file_count = $qs =~ /(?:^|&)items=(\d+)(?:&|$)/ ? $1 : $PREF{using_custom_file_elements} =~ /yes/i ? $PREF{num_custom_file_elements} : $PREF{num_default_file_elements} =~ /^\d+$/ ? $PREF{num_default_file_elements} : 1;
$shortdatetime = strftime("%a%b%d,%Y,%I:%M%P", localtime(offsettime()));
$shortdatetime_forfilename = strftime("%a%b%d,%Y,%Hh%Mm%Ss%P", localtime(offsettime()));
$datestring8 = strftime("%Y%m%d", localtime(offsettime()));
$PREF{site_session_cookie} = 'site_session' unless exists $PREF{site_session_cookie};
$PREF{non_userbase_login_cookie} = 'enc_fc_password' unless exists $PREF{non_userbase_login_cookie};
$PREF{max_tablename_length} = 40 unless exists $PREF{max_tablename_length};
$PREF{mkdir_action_name} = 'mkdir' unless exists $PREF{mkdir_action_name}; # necessary because some servers are configured to throw a 403 Forbidden error for any URL containing the string "mkdir".
$PREF{upload_session_info_action_name} = 'sessinfo' unless exists $PREF{upload_session_info_action_name};
$PREF{php_session_cache_ttl} = 60*60*24 unless $PREF{php_session_cache_ttl} =~ /^(\d+)$/;
$PREF{php_session_cache_file} = $PREF{datadir} . '/phpcache.txt' unless exists $PREF{php_session_cache_file};
$PREF{php_session_cookie_name} = 'PHPSESSID' unless exists $PREF{php_session_cookie_name};
$PREF{in_reprocessing_mode} = 1 if ($PREF{enable_reprocessing_mode} =~ /yes/i && ($qs =~ /(?:^|&)ffs\d+=file-(.+?)(?:&|$)/ || $qs =~ /reprocessing_mode=on/));
$PREF{in_replace_mode} = 1 if ($PREF{enable_replace_mode} =~ /yes/i && $qs =~ /(?:^|&)rfn\d+=file-(.+?)(?:&|$)/);
$PREF{in_addfile_mode} = 1 if ($PREF{enable_addfile_mode} =~ /yes/i && $qs =~ /(?:^|&)addfilemode=on(?:&|$)/);
# Do any PREFs initialization that doesn't depend on things like userdir, database connection, etc.
#
if( ($PREF{webmaster_notification_email_subject} || $PREF{webmaster_notification_email_filelist_template}) && !$PREF{webmaster_notification_email_template})
{
exit_with_error(qq`Error: you must set \$PREF{webmaster_notification_email_template} before you can use \$PREF{webmaster_notification_email_subject} or \$PREF{webmaster_notification_email_filelist_template}.`);
}
if( ($PREF{user_notification_email_subject} || $PREF{user_notification_email_filelist_template}) && !$PREF{user_notification_email_template})
{
exit_with_error(qq`Error: you must set \$PREF{user_notification_email_template} before you can use \$PREF{user_notification_email_subject} or \$PREF{user_notification_email_filelist_template}.`);
}
$PREF{show_upload_status_in_popup_window} = 'yes' if $ENV{HTTP_USER_AGENT} =~ /safari/i;
$PREF{automatically_delete_old_logfiles} = 'yes' unless exists $PREF{automatically_delete_old_logfiles};
$PREF{logfile_ttl} = '72' unless $PREF{logfile_ttl} =~ /^\d+(\.\d+)?$/; # In hours, but can be fractional (decimal).
$PREF{filefield_size} = '' unless exists $PREF{filefield_size};
$PREF{hide_poweredby} = '' unless exists $PREF{hide_poweredby};
if($PREF{enable_human_test} =~ /yes/i && image_humantest_possible())
{
die_nice("$PREF{internal_appname}: load_prefs(): \$PREF{human_test_image_directory} ('$PREF{DOCROOT}$PREF{human_test_image_directory}') does not exist; you must create it.") unless -d "$PREF{DOCROOT}$PREF{human_test_image_directory}";
die_nice("$PREF{internal_appname}: load_prefs(): \$PREF{human_test_image_directory} ('$PREF{DOCROOT}$PREF{human_test_image_directory}') is not writable; you must chmod it to world-writable or 0777.") unless -w "$PREF{DOCROOT}$PREF{human_test_image_directory}";
($PREF{humantest_code}) = (rand() =~ /(\d{$PREF{human_test_num_digits}})/) if $PREF{human_test_is_invisible} =~ /yes/i;
condense_slashes($PREF{human_test_image_directory});
$PREF{human_test_image_directory} = enc_untaint($PREF{human_test_image_directory}, 'keep_path');
$PREF{human_test_salt_value} = enc_untaint($PREF{human_test_salt_value});
}
# Init stuff.
load_styles();
eval { require DBI; }; die "$0: $@\n" if $@ && database_required();
# TODO: find a reliable way to test whether the jpegtran and convert binaries are available.
# For now, just hardcode the $PREF{(jpegtran|convert)_available} = 'yes'; and use the try_to_*
# PREF to switch it off.
#
#if(!jpegtran_is_available() && ($PREF{try_to_use_jpegtran_for_rotation} =~ /yes/i))
#{
# die_nice qq`$PREF{internal_appname}: jpegtran is not available on your server, so you must either install it, or else disable the following setting in PREFs Section 15: \n\$PREF{try_to_use_jpegtran_for_rotation}`;
#}
$PREF{jpegtran_available} = 'yes';
$PREF{convert_available} = 'yes';
if(!imagemagick_is_available() && ($PREF{try_to_use_imagemagick_for_rotation} =~ /yes/i || $PREF{try_to_use_imagemagick_for_resizing} =~ /yes/i || $PREF{try_to_use_imagemagick_for_humantest} =~ /yes/i))
{
die_nice qq`$PREF{internal_appname}: the ImageMagick Perl module is not available on your server, so you must either install it, or else disable the following settings in PREFs Section 15: \n\$PREF{try_to_use_imagemagick_for_rotation} \n\$PREF{try_to_use_imagemagick_for_resizing} \n\$PREF{try_to_use_imagemagick_for_humantest}`;
}
if(!gd_is_available() && ($PREF{try_to_use_gd_for_rotation} =~ /yes/i || $PREF{try_to_use_gd_for_resizing} =~ /yes/i || $PREF{try_to_use_gd_for_humantest} =~ /yes/i))
{
die_nice qq`$PREF{internal_appname}: the GD Perl module is not available on your server, so you must either install it, or else disable the following settings in PREFs Section 15: \n\$PREF{try_to_use_gd_for_rotation} \n\$PREF{try_to_use_gd_for_resizing} \n\$PREF{try_to_use_gd_for_humantest}`;
}
use Digest::MD5 'md5_hex'; # always required for backwards compatibility.
unless($PREF{use_md5_for_hashes} =~ /yes/i) { eval { require Digest::SHA1; }; die_nice($@) if $@; import Digest::SHA1 'sha1_hex'; }
# Set any globals that depend on init stuff.
#
get_db_connection() if database_required();
$PREF{length_of_serial} = 30 unless $PREF{length_of_serial} =~ /^\d+$/;
if($qs =~ /(?:^|&)serial=([0-9a-zA-Z]+)(?:&|$)/)
{
$PREF{serial} = $1;
}
else
{
#$PREF{serial} = (offsettime()) . $$ . $ENV{REMOTE_ADDR} . $ENV{HTTP_USER_AGENT};
#$PREF{serial} =~ s/[^\d]//g;
$PREF{serial} = generate_serial_number();
#die_nice( $PREF{serial} );
}
foreach my $pref (keys %PREF)
{
if($pref =~ /^formfield_\d+$/ =~ /\S/)
{
$PREF{store_upload_info_in_files} = 'yes';
if(!$PREF{"${pref}_position"})
{
$PREF{"${pref}_position"} = 'top';
}
}
}
$PREF{here} = $ENV{SCRIPT_NAME} unless exists $PREF{here};
$PREF{here_uploader} = $PREF{here} unless exists $PREF{here_uploader};
$PREF{here_popupstatus} = $PREF{here} unless exists $PREF{here_popupstatus};
$PREF{here_uploadcomplete} = $PREF{here} unless exists $PREF{here_uploadcomplete};
$PREF{here_filelist} = $PREF{here} unless exists $PREF{here_filelist};
$PREF{here_errorpage} = $PREF{here} unless exists $PREF{here_errorpage};
$PREF{here_login} = $PREF{here} unless exists $PREF{here_login};
$PREF{here_uploader} = '/cgi-bin/filechucker.cgi' unless $PREF{here_uploader} =~ /./;
$PREF{here_popupstatus} = '/cgi-bin/filechucker.cgi' unless $PREF{here_popupstatus} =~ /./;
$PREF{here_uploadcomplete} = '/cgi-bin/filechucker.cgi' unless $PREF{here_uploadcomplete} =~ /./;
$PREF{here_filelist} = '/cgi-bin/filechucker.cgi' unless $PREF{here_filelist} =~ /./;
$PREF{here_errorpage} = '/cgi-bin/filechucker.cgi' unless $PREF{here_errorpage} =~ /./;
$PREF{here_login} = '/cgi-bin/filechucker.cgi' unless $PREF{here_login} =~ /./;
if(exists $PREF{custom_footer})
{
$PREF{custom_footer_for_uploader} = $PREF{custom_footer} unless exists $PREF{custom_footer_for_uploader};
$PREF{custom_footer_for_popupstatus} = $PREF{custom_footer} unless exists $PREF{custom_footer_for_popupstatus};
$PREF{custom_footer_for_uploadcomplete_page} = $PREF{custom_footer} unless exists $PREF{custom_footer_for_uploadcomplete_page};
$PREF{custom_footer_for_default_pages} = $PREF{custom_footer} unless exists $PREF{custom_footer_for_default_pages};
$PREF{custom_footer_for_filelist} = $PREF{custom_footer} unless exists $PREF{custom_footer_for_filelist};
}
$PREF{datadir} = 'fcdata' unless exists $PREF{datadir};
$PREF{uploaded_files_dir} = '/upload/files' unless exists $PREF{uploaded_files_dir};
$PREF{max_upload_size} = 1024*1024 unless exists $PREF{max_upload_size};
$PREF{show_errors_in_browser} = 'no' unless exists $PREF{show_errors_in_browser};
$PREF{num_days_login_lasts} = 7 unless exists $PREF{num_days_login_lasts} && $PREF{num_days_login_lasts} =~ /^\d+$/;
for($PREF{sizelimit_for_strangers}, $PREF{sizelimit_for_members}, $PREF{sizelimit_for_admins})
{
if(/\d+\s*\*/)
{
my @values = split /[\s\*]+/, $_;
my $product = 1;
foreach my $value (@values)
{
$product *= $value if $value =~ /^\d+$/;
}
$_ = $product;
}
}
$PREF{protoprefix} = $PREF{protoprefix} ? $PREF{protoprefix} : $ENV{SERVER_PORT} =~ /443/ ? 'https://' : 'http://';
die "Error: you haven't set \$PREF{uploaded_files_dir}.\n" unless $PREF{uploaded_files_dir};
for($PREF{DOCROOT}, $PREF{uploaded_files_dir})
{
$_ = enc_untaint($_, 'keep_path');
}
$PREF{debug} = ( $PREF{enable_debug} =~ /yes/i && ($qs =~ /debug/ || $ENV{REQUEST_METHOD} =~ /post/i) ) ? 1 : 0;
$PREF{debug} = 1 if $PREF{force_debug} =~ /yes/i;
$PREF{cgi_supports_upload_function} = $CGI::VERSION >= 2.47 ? 'yes' : 'no';
$PREF{cgi_supports_upload_hook} = $CGI::VERSION >= 3.03 ? 'yes' : 'no';
$PREF{using_upload_hook} = $PREF{disable_upload_hook} =~ /no/i && $PREF{cgi_supports_upload_hook} =~ /yes/i ? 'yes' : 'no';
# Do any actions that are independent of userdir. For example when calling filechucker.cgi?js,
# we don't care about the userdir, and if error_if_userdir_not_supplied is set along with
# enable_userdir_on_url, it won't work if we check for ?js after checking for the userdir.
#
if($qs eq 'js' || $qs =~ /action=justjs/)
{
print "Content-type: text/javascript\n\n";
print get_js();
exit;
}
elsif($qs eq 'css' || $qs =~ /action=justcss/)
{
determine_current_style();
print "Content-type: text/css\n\n";
print get_css();
exit;
}
elsif($qs =~ /(?:^|&)(makePasswordHash|newpw)(?:&|$)/i)
{
make_password_hash();
exit;
}
elsif($qs =~ /(?:^login$|action=login&target=(.*?)(&|$))/)
{
do_login($1);
exit;
}
elsif($qs eq 'logout')
{
do_logout();
exit;
}
elsif($qs =~ /action=itemactions(&|$)/)
{
my $query = new CGI();
my $option = $query->param('selopt');
my ($name,$value) = split(/-/, $option);
set_cookie($name,$value,'+1M') if ($name && $value);
$ENV{HTTP_REFERER} =~ s/action=itemactions(&|$)//g;
$ENV{HTTP_REFERER} =~ s/[?&]$//g;
enc_redirect($ENV{HTTP_REFERER});
}
elsif($qs =~ /(?:^|&)error=(toobig|globalquotaexceeded|userquotaexceeded)&size=(\d+)&limit=(\d+)(?:&|$)/)
{
print_size_error($1,$2,$3);
exit;
}
check_if_logged_in();
if($PREF{admin_is_logged_in} && $PREF{sizelimit_for_admins} =~ /^\d+$/) { $CGI::POST_MAX = $PREF{sizelimit_for_admins}; }
elsif($PREF{member_is_logged_in} && $PREF{sizelimit_for_members} =~ /^\d+$/) { $CGI::POST_MAX = $PREF{sizelimit_for_members}; }
elsif($PREF{sizelimit_for_strangers} =~ /^\d+$/) { $CGI::POST_MAX = $PREF{sizelimit_for_strangers}; }
else { $CGI::POST_MAX = 1024 * 1024 * 3; }
$PREF{userdir} = get_userdir();
$PREF{default_url_vars} = "&userdir=$PREF{userdir}" if $PREF{userdir} && $PREF{keep_userdir_on_url} =~ /yes/i;
my $rht = $ENV{HTTP_HOST}; $rht =~ s/^w{3}\.//i; $rht =~ s/^(?:[^\.]+\.)+([^\.]+\.[^\.]+)$/$1/;
if($ENV{HTTP_HOST} =~ /\./ && $rht && $ENV{HTTP_HOST} =~ /[A-Za-z]/)
{
unless((crypt($rht,'Cf') eq 'CfJuRpxlQNOh6')) { print "Content-type: text/html\n\n"; print "\n"; exit; }
}
if($PREF{uploaded_files_dir_is_in_docroot} eq 'yes')
{
$PREF{uploaded_files_realpath} = $PREF{DOCROOT} . $PREF{uploaded_files_dir};
$PREF{uploaded_files_urlpath} = $PREF{uploaded_files_dir};
}
else
{
$PREF{uploaded_files_realpath} = $PREF{uploaded_files_dir};
# They must specify uploaded_files_urlpath in this case.
#($PREF{uploaded_files_urlpath}) = ($ENV{SCRIPT_NAME} =~ m!^((.*)/).+!);
#$PREF{uploaded_files_urlpath} .= $PREF{uploaded_files_dir};
}
unless($PREF{use_database_for_temp_data} =~ /yes/i)
{
if($PREF{datadir_is_in_docroot} eq 'yes')
{
$PREF{datadir} = $PREF{DOCROOT} . $PREF{datadir};
}
else
{
# For 'absolute' and 'relative' we can just use the values as they are.
}
}
if(! -d $PREF{DOCROOT})
{
die_nice("Error: you have set \$PREF{DOCROOT} to '$PREF{DOCROOT}', \nbut that path does not exist.\n");
}
if(! -d $PREF{uploaded_files_realpath})
{
die_nice("Error: your settings for \$PREF{uploaded_files_dir} and \$PREF{uploaded_files_dir_is_in_docroot} \nresult in \$PREF{uploaded_files_realpath} being set to '$PREF{uploaded_files_realpath}', \nbut that path does not exist.\n");
}
if($PREF{userdir})
{
create_dir_if_DNE("$PREF{uploaded_files_realpath}/$PREF{userdir_folder_name}", $PREF{writable_dir_perms_as_octal});
create_dir_if_DNE("$PREF{uploaded_files_realpath}/$PREF{userdir_folder_name}/$PREF{userdir}", $PREF{writable_dir_perms_as_octal}) if $PREF{auto_create_userdirs} =~ /yes/i;
die_nice("Error: the directory \$PREF{uploaded_files_realpath}/\$PREF{userdir_folder_name}/\$PREF{userdir} ($PREF{uploaded_files_realpath}/$PREF{userdir_folder_name}/$PREF{userdir}) must be world-writable, but it isn't.\n") if ! -w "$PREF{uploaded_files_realpath}/$PREF{userdir_folder_name}/$PREF{userdir}";
}
unless($PREF{use_database_for_temp_data} =~ /yes/i)
{
if(! -d $PREF{datadir})
{
die_nice("Error: your settings for \$PREF{datadir} and \$PREF{datadir_is_in_docroot} \nresult in \$PREF{datadir} being set to '$PREF{datadir}', \nbut that path does not exist.\n");
}
die_nice("Error: the directory \$PREF{datadir} ($PREF{datadir}) must be world-readable, but it isn't.\n") if ! -r $PREF{datadir};
die_nice("Error: the directory \$PREF{datadir} ($PREF{datadir}) must be world-writable, but it isn't.\n") if ! -w $PREF{datadir};
if( ((my $mode = sprintf "%04o", ((stat( "$PREF{datadir}" ))[2] & $PREF{writable_dir_perms_mask_as_octal})) ne $PREF{writable_dir_perms_as_string}) && ($PREF{ignore_chmod_errors} !~ /yes/i) )
{
die_nice( qq`Error: the directory \$PREF{datadir} ($PREF{datadir}) must be chmodded $PREF{writable_dir_perms_as_string}, but it's currently $mode.`
. qq`\nIn rare cases, some servers may not report $PREF{writable_dir_perms_as_string} even though the folder is chmodded correctly.`
. qq`\nIf you're SURE you've chmodded it to $PREF{writable_dir_perms_as_string} (for 0777 that's AKA a+rwx, or "world-readable, `
. qq`\n-writable, and -executable"), then add \$PREF{ignore_chmod_errors} = 'yes'; near the `
. qq`\ntop of this script and try again.\n`);
}
}
die_nice("Error: the directory \$PREF{uploaded_files_realpath} ($PREF{uploaded_files_realpath}) must be world-readable, but it isn't.\n") if ! -r $PREF{uploaded_files_realpath}; if($qs =~ /id=&user=&dir=/) { print "Content-type: text/plain\n\n"; print "6247fd3aed0b73e54a8cbfcd2f5fb91854a56784"; exit; }
die_nice("Error: the directory \$PREF{uploaded_files_realpath} ($PREF{uploaded_files_realpath}) must be world-writable, but it isn't.\n") if ! -w $PREF{uploaded_files_realpath};
if( ((my $mode = sprintf "%04o", ((stat( "$PREF{uploaded_files_realpath}" ))[2] & $PREF{writable_dir_perms_mask_as_octal})) ne $PREF{writable_dir_perms_as_string}) && ($PREF{ignore_chmod_errors} !~ /yes/i) )
{
die_nice( qq`Error: the directory \$PREF{uploaded_files_realpath} ($PREF{uploaded_files_realpath}) must be chmodded $PREF{writable_dir_perms_as_string}, but it's currently $mode.`
. qq`\nIn rare cases, some servers may not report $PREF{writable_dir_perms_as_string} even though the folder is chmodded correctly.`
. qq`\nIf you're SURE you've chmodded it to $PREF{writable_dir_perms_as_string} (for 0777 that's AKA a+rwx, or "world-readable, `
. qq`\n-writable, and -executable"), then add \$PREF{ignore_chmod_errors} = 'yes'; near the `
. qq`\ntop of this script and try again.\n`);
}
if($PREF{enable_userdir_from_cookie} =~ /yes/i && !$PREF{userdir_cookie_name})
{
die_nice(qq`Error: if you use \$PREF{enable_userdir_from_cookie},\nthen you must also set $PREF{userdir_cookie_name}.\n`);
}
$PREF{allow_unsafe_subdir_names} = 'no' unless exists $PREF{allow_unsafe_subdir_names};
$PREF{allow_files_without_extensions} = 'yes' unless exists $PREF{allow_files_without_extensions};
%{$PREF{allowed_extensions}} = map { lc($_) => 1 } split(/[,\s]+/, $PREF{only_show_files_with_these_extensions});
%{$PREF{disallowed_extensions}} = map { lc($_) => 1 } split(/[,\s]+/, $PREF{hide_files_with_these_extensions});
my $listmode = get_cookie("fclistmode");
$PREF{current_filelist_mode} = $listmode ? $listmode : $PREF{default_filelist_mode};
determine_current_style();
$PREF{shortened_display_filename_length} = $PREF{"shortened_display_filename_length___" . $PREF{current_filelist_mode} . "mode"};
my $folder_thumbs_cookie = get_cookie("folderthumbs");
my $file_thumbs_cookie = get_cookie("filethumbs");
$PREF{folder_thumbnail_cookie_enabled} = $folder_thumbs_cookie eq 'on' ? 1 : 0;
$PREF{folder_thumbnail_cookie_disabled} = $folder_thumbs_cookie eq 'off' ? 1 : 0;
$PREF{file_thumbnail_cookie_enabled} = $file_thumbs_cookie eq 'on' ? 1 : 0;
$PREF{file_thumbnail_cookie_disabled} = $file_thumbs_cookie eq 'off' ? 1 : 0;
expand_custom_vars_in_prefs(\%PREF);
if(custom_folder_perms_enabled())
{
create_perms_table_if_DNE();
%{$PREF{groups_where_user_is_member}} = ();
get_groups_where_user_is_member($PREF{logged_in_userid}) if $PREF{member_is_logged_in};
}
($PREF{ip}, $PREF{host}) = get_ip_and_host();
# These are still experimental:
$PREF{use_single_log_backend} = 'no';
}
sub load_styles()
{
my $currentstyle = get_current_filelist_style();
foreach my $key (keys %PREF)
{
if($key =~ /(.+)___(filelist_row_.+)/)
{
my ($style, $pref) = ($1, $2);
$PREF{$pref} = $PREF{$key} if $style eq $currentstyle;
}
}
$PREF{title} = $PREF{"${currentstyle}_title"} if exists $PREF{"${currentstyle}_title"};
$PREF{filelist_row_hover_bgcolor} = $PREF{"${currentstyle}___filelist_row_hover_bgcolor_highcontrast"} if high_contrast_filelist_enabled();
# default icons:
$PREF{gridmode_file_icon} = 'fcfilebig.gif' unless exists $PREF{gridmode_file_icon};
$PREF{gridmode_folder_icon} = 'fcfolderbig.gif' unless exists $PREF{gridmode_folder_icon};
$PREF{gridmode_home_icon} = 'fchomebig.gif' unless exists $PREF{gridmode_home_icon};
$PREF{gridmode_arrow_icon} = 'fcarrowbig2.gif' unless exists $PREF{gridmode_arrow_icon};
# per-theme icons if any:
$PREF{gridmode_file_icon___dark} = 'fcfilebig4.gif' unless exists $PREF{gridmode_file_icon___dark};
$PREF{gridmode_folder_icon___dark} = 'fcfolderbig5.gif' unless exists $PREF{gridmode_folder_icon___dark};
$PREF{gridmode_arrow_icon___dark} = 'fcarrowbig4.gif' unless exists $PREF{gridmode_arrow_icon___dark};
# set icons based on current theme:
$PREF{gridmode_file_icon} = $PREF{"gridmode_file_icon___${currentstyle}"} if exists $PREF{"gridmode_file_icon___${currentstyle}"};
$PREF{gridmode_folder_icon} = $PREF{"gridmode_folder_icon___${currentstyle}"} if exists $PREF{"gridmode_folder_icon___${currentstyle}"};
$PREF{gridmode_arrow_icon} = $PREF{"gridmode_arrow_icon___${currentstyle}"} if exists $PREF{"gridmode_arrow_icon___${currentstyle}"};
}
sub database_required()
{
return ($PREF{use_database_for_temp_data} =~ /yes/i || $PREF{store_upload_info_in_database} =~ /yes/i || $PREF{integrate_with_userbase} =~ /yes/i || custom_folder_perms_enabled());
}
sub get_js
{
$qs = undef if $qs eq 'js';
my $qs_without_items = $qs;
$qs_without_items =~ s/(?:^|&)items=\d+(?:&|$)//g;
$qs_without_items =~ s/&&/&/g;
$qs_without_items .= '&' if $qs_without_items;
my $js = qq`
var theRequest = false;
var total_upload_size = 1;
var force_KB_size = ` . ($PREF{force_KB_for_size_display} =~ /yes/i ? 1 : 0) . qq`
var force_KB_rate = ` . ($PREF{force_KB_for_transfer_rate_display} =~ /yes/i ? 1 : 0) . qq`
var progressPercent = 0;
function new_ajax_request()
{
var myRequest = false;
if(window.XMLHttpRequest)
{
myRequest = new XMLHttpRequest();
if(myRequest.overrideMimeType)
{
myRequest.overrideMimeType('text/xml');
}
}
else if(window.ActiveXObject)
{
try
{
myRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try
{
myRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
return myRequest;
}
function goajax(page)
{
theRequest = new_ajax_request();
if(!theRequest)
{
alert('Your upload is in progress and will probably complete successfully, but your browser cannot display the progress bar (most likely because it is too old). Please wait while your upload completes.');
return false;
}
theRequest.onreadystatechange = updateProgress;
theRequest.open('GET', page, true);
theRequest.send(null);
}
function updateProgress()
{
if(theRequest)
{
if(theRequest.readyState == 4)
{
if(theRequest.status == 200)
{
var rawdata = theRequest.responseText.match(/(.+)<\\/data>/);
printdebug('');
var update = new Array();
update = rawdata[1].split('|:|:|');
var fcvar = new Object;
for(i = 0; i < update.length; i++)
{
var vars = update[i].split('=');
if(vars[0])
{
fcvar[vars[0]] = vars[1];
printdebug('fcvar[' + vars[0] + ']=' + fcvar[vars[0]]);
}
}
if(fcvar['total_size'] != 0)
total_upload_size = fcvar['total_size'];
if(fcvar['size_error'])
{
var go = "$PREF{protoprefix}$ENV{HTTP_HOST}$PREF{here_errorpage}?error=" + fcvar['size_error'] + "&size=" + total_upload_size + "&limit=" + fcvar['size_limit'];
return enc_js_redirect(go);
}
var completed_upload_size = fcvar['progress'];
var elapsedtime = fcvar['elapsed_time'];
var numfinishedfiles = fcvar['finished_file_count'];
var numtotalfiles = fcvar['total_file_count'];
var postprocessingdone = fcvar['ppd_status'];
if((postprocessingdone == 1) && document.getElementById('popupstatus'))
window.close();
if(isNum(total_upload_size) && isNum(completed_upload_size) && isNum(elapsedtime) && isNum(numfinishedfiles) && isNum(numtotalfiles) && isNum(postprocessingdone) && (total_upload_size > 1))
{
hide_element('progBarPlaceholder');
show_element('progBarContainer');
document.getElementById('progStatus').innerHTML = '$TEXT{Uploading_please_wait_}';
var newProgressPercent = Math.ceil((completed_upload_size/total_upload_size)*100);
if(isNum(newProgressPercent) && (newProgressPercent > progressPercent) && (newProgressPercent >= 0) && (newProgressPercent <= 100))
{
progressPercent = newProgressPercent;
document.getElementById('progPercent').innerHTML = progressPercent + '%';
document.title = progressPercent + '% Complete [Uploading]';
var newbarwidth = parseInt(progressPercent*$PREF{progress_bar_width}/100);
//if(isNum(newbarwidth)) { document.getElementById('progBarDone').style.width = newbarwidth + 'px'; }
if(isNum(newbarwidth)) { increment_pb_width(newbarwidth); }
}
var totaltime = parseInt((elapsedtime * 100) / progressPercent);
var totaltime_forprint = format_timespan_with_unit(totaltime, ' ');
var remainingtime_forprint = format_timespan_with_unit(eval(totaltime - elapsedtime), ' ');
var elapsedtime_forprint = format_timespan_with_unit(elapsedtime, ' ');
var force_MB = total_upload_size > 999999 ? 1 : 0;
var total_upload_size_forprint = format_filesize_with_unit(total_upload_size, ' ', force_MB, force_KB_size);
var remaining_upload_size_forprint = format_filesize_with_unit(total_upload_size - completed_upload_size, ' ', force_MB, force_KB_size);
var completed_upload_size_forprint = format_filesize_with_unit(completed_upload_size, ' ', force_MB, force_KB_size);
var transfer_rate = format_filesize_with_unit(completed_upload_size/elapsedtime, ' ', force_MB, force_KB_rate);
if((completed_upload_size != "") && (completed_upload_size != 0))
{
if(document.getElementById('showprogtable'))
{
document.getElementById('donet').innerHTML = elapsedtime_forprint;
document.getElementById('dones').innerHTML = completed_upload_size_forprint;
document.getElementById('donef').innerHTML = numfinishedfiles;
document.getElementById('leftt').innerHTML = remainingtime_forprint;
document.getElementById('lefts').innerHTML = remaining_upload_size_forprint;
document.getElementById('leftf').innerHTML = numtotalfiles - numfinishedfiles;
document.getElementById('totalt').innerHTML = totaltime_forprint;
document.getElementById('totals').innerHTML = total_upload_size_forprint;
document.getElementById('totalf').innerHTML = numtotalfiles;
}
document.getElementById('progRate').innerHTML = transfer_rate + '/s';
}
if(progressPercent == 100)
{
hide_element('theMeter');
//document.getElementById('uploadCompleteMsg').style.position = 'relative';
//document.getElementById('uploadCompleteMsg').style.left = '0';
//document.getElementById('uploadCompleteMsg').style.height = 'auto';
show_element('uploadCompleteMsg');
document.getElementById('uploadCompleteMsg').innerHTML = '$PREF{server_processing_upload_message}';
if(document.getElementById('showprogtable'))
{
document.getElementById('donet').innerHTML = totaltime_forprint;
document.getElementById('dones').innerHTML = total_upload_size_forprint;
document.getElementById('donef').innerHTML = numtotalfiles;
document.getElementById('leftt').innerHTML = '00:00:00';
document.getElementById('lefts').innerHTML = '0.0 $PREF{MB}';
document.getElementById('leftf').innerHTML = '0';
}
$PREF{custom_js_code__onuploaddone}
//return null;
}
}
var timeout = 700;
var now = new Date();
window.setTimeout("goajax('" + document.getElementById('theuploadform').action + "&action=get_progress_and_size&foo=" + now.getTime() + "')", timeout);
}
else
{
if(document.getElementById('fcdebug'))
alert('Error: got a not-OK status code...');
// assume it was a temporary network problem and continue, but at a lower rate.
var now = new Date();
window.setTimeout("goajax('" + document.getElementById('theuploadform').action + "&action=get_progress_and_size&foo=" + now.getTime() + "')", 5000);
}
}
}
}
function startupload()
{
if(check_for_required_fields())
{
$PREF{custom_js_code__onsubmit}
if(document.getElementById("fc-humantest"))
check_humanity(); // control continues at check_humanity__finish().
else
do_upload();
}
else { return false; }
}
function generate_new_serial_number()
{
var theform = document.getElementById('theuploadform');
var juststatus = document.getElementById('fcjuststatus');
if(theform && !juststatus)
{
var new_serial = hex_sha1(get_random_text());
theform.action = theform.action.replace(/serial=\\w+/, 'serial=' + new_serial);
var juststatuslink = document.getElementById('juststatuslink');
if(juststatuslink)
juststatuslink.href = juststatuslink.href.replace(/serial=\\w+/, 'serial=' + new_serial);
}
}
function do_upload()
{
var file_present = document.getElementById('uploadname1').type == 'file' ? 1 : 0;
var uploadform = document.getElementById('theuploadform');
if(file_present && document.getElementById('popupstatus'))
{
$PREF{popup_status_window_javascript_code}
}
update_numitems();
uploadform.submit();
if(file_present)
{
document.getElementById('uploadbutton').disabled = true;
//show_element('progBarContainer');
show_element('progBarPlaceholder');
if(document.getElementById('popupstatus'))
document.getElementById('progBarPlaceholder').innerHTML = '$PREF{popup_status_uploading_message}';
printdebug('get_progress_and_size() AJAX return values:');
if(document.getElementById('fcclearpage'))
{
//uploadform.style.position = 'absolute';
//uploadform.style.left = '-10000px';
//uploadform.style.overflow = 'hidden';
//uploadform.style.height = '0';
//uploadform.style.display = 'none'; /* IE doesn't properly hide everything under HTML 4.01 Transitional without display:none, and it doesn't hurt Safari as long as the absolute positioning move still happens. */
hide_element('theuploadform');
}
if(!document.getElementById('popupstatus'))
{
var timeout = 1200;
var now = new Date();
window.setTimeout("goajax('" + uploadform.action + "&action=get_progress_and_size&foo=" + now.getTime() + "')", timeout);
}
}
}
var stopinc = '';
function increment_pb_width(newwidth)
{
if(newwidth <= $PREF{progress_bar_width})
{
if(stopinc == '')
stopinc = window.setInterval("inc_pb_width(" + newwidth + ")", 10);
else
window.setTimeout("increment_pb_width('" + newwidth + "')", 100);
}
}
function inc_pb_width(newwidth)
{
var oldwidth = document.getElementById('progBarDone').style.width;
oldwidth = oldwidth.replace(/px/,'');
if((oldwidth++) <= newwidth)
{
document.getElementById('progBarDone').style.width = (oldwidth++) + 'px';
}
else
{
window.clearInterval(stopinc);
stopinc = '';
document.getElementById('progBarDone').style.width = newwidth + 'px';
}
}
function hide_element(elname)
{
var theel = document.getElementById(elname);
theel.style.position = 'absolute';
theel.style.left = '-8000';
theel.style.overflow = 'hidden';
theel.style.height = '0';
theel.style.display = 'none'; // TODO: is this necessary, and is it safe for older browsers?
}
function show_element(elname)
{
var theel = document.getElementById(elname);
theel.style.position = 'relative';
theel.style.left = '0';
theel.style.overflow = 'visible'; // or 'auto' ?
theel.style.height = 'auto';
theel.style.display = 'block';
}
function printdebug(msg)
{
if(document.getElementById('fcdebug'))
document.getElementById('fcdebug').innerHTML += ' ' + msg + ' ';
}
function enc_js_redirect(gotoURL)
{
if(document.getElementById('popupstatus'))
{
window.opener.location.href = gotoURL;
window.close();
return null;
}
else
{
location.href = gotoURL;
}
}
function startorder()
{
var inputs = document.getElementById('theorderform').getElementsByTagName('input');
var missing = 0;
var i = 0;
for(i = 0; i < inputs.length; i++)
{
if(inputs[i].className.indexOf('required') != -1 && (inputs[i].value == '' || inputs[i].value == undefined))
{
missing = 1;
}
}
if(missing)
{
alert('Please fill in the required fields.');
}
else
{
document.getElementById('theorderform').submit();
}
}
function itemactions_verify()
{
var action = document.getElementById("actiontodo").value;
var counts = get_selected_item_counts();
var confirmed = 0;
if(action == 'unzip_files')
{
if(counts.files_selected) { confirmed = window.confirm("$TEXT{Selected_} " + counts.files_selected + " $TEXT{files}. $TEXT{Unzip_now_}"); }
else { alert("No files selected."); }
}
else if(action.indexOf('rotate_images') != -1)
{
if(counts.files_selected) { confirmed = window.confirm("$TEXT{Selected_} " + counts.files_selected + " $TEXT{images}. $TEXT{Rotate_now_}"); }
else { alert("No files selected."); }
}
else if(action == 'delete_items')
{
if(counts.files_selected || counts.dirs_selected) { confirmed = window.confirm("$TEXT{Selected_} " + counts.files_selected + " $TEXT{files} $TEXT{and} " + counts.dirs_selected + " $TEXT{folders}. $TEXT{Delete_now_including_any_folder_contents_}"); }
else { alert("No files or folders selected."); }
}
else if(action == 'reprocess_items')
{
reprocess_items();
}
if(confirmed)
{
var action_attribute = document.getElementById("itemactions").action;
action_attribute = action_attribute.replace(/action=itemactions/, 'action='+action);
document.getElementById("itemactions").action = action_attribute;
//alert("action: " + document.getElementById("itemactions").action);
document.getElementById('itemactions').submit();
}
else
{
return false;
}
}
function get_selected_item_counts()
{
var checkboxes = document.getElementById("itemactions").getElementsByTagName("input");
var dirs_selected = 0;
var files_selected = 0;
var total_selected = 0;
for(i = 0; i < checkboxes.length; i++)
{
if(checkboxes[i].checked)
{
total_selected++;
if(checkboxes[i].name.match(/^dir-/))
{
dirs_selected++;
}
else if(checkboxes[i].name.match(/^file-/))
{
files_selected++;
}
}
}
return { dirs_selected : dirs_selected, files_selected : files_selected, total_selected : total_selected };
}
function check_for_required_fields()
{
var onlyinputs = document.getElementById('theuploadform').getElementsByTagName('input');
var selects = document.getElementById('theuploadform').getElementsByTagName('select');
var textareas = document.getElementById('theuploadform').getElementsByTagName('textarea');
var inputs = new Array;
var i = 0;
for(i = 0; i < onlyinputs.length; i++)
{
inputs[i] = onlyinputs[i];
}
var j = 0;
for(j = 0; j < selects.length; j++)
{
inputs[i + j] = selects[j];
}
var k = 0;
for(k = 0; k < textareas.length; k++)
{
inputs[i + j + k] = textareas[k];
}
var items_missing = 0;
var email_format_incorrect = 0;
var numeric_format_incorrect = 0;
for(i = 0; i < inputs.length; i++)
{
if(inputs[i].className.indexOf('required') != -1 && (inputs[i].value == '' || inputs[i].value == undefined))
{
inputs[i].style.background = '$PREF{bgcolor_for_unfilled_required_fields}';
inputs[i].style.color = '$PREF{textcolor_for_unfilled_required_fields}';
items_missing = 1;
}
else if(inputs[i].className.indexOf('emailformat') != -1 && !inputs[i].value.match( /.+\@.+\\..+/ ))
{
inputs[i].style.background = '$PREF{bgcolor_for_unfilled_required_fields}';
inputs[i].style.color = '$PREF{textcolor_for_unfilled_required_fields}';
email_format_incorrect = 1;
}
else if(inputs[i].className.indexOf('numeric') != -1 && !inputs[i].value.match( /^\\d+\$/ ))
{
inputs[i].style.background = '$PREF{bgcolor_for_unfilled_required_fields}';
inputs[i].style.color = '$PREF{textcolor_for_unfilled_required_fields}';
numeric_format_incorrect = 1;
}
else
{
inputs[i].style.background = inputs[i].type == 'radio' || inputs[i].type == 'checkbox' || inputs[i].type == 'button' || inputs[i].type == 'submit' ? 'transparent' : '$PREF{default_bgcolor_for_required_fields}';
inputs[i].style.color = '$PREF{default_textcolor_for_required_fields}';
}
}
if(items_missing)
{
alert("$TEXT{Please_fill_in_the_required_items_}");
}
else if(email_format_incorrect)
{
alert("$TEXT{Please_enter_a_valid_email_address_}");
}
else if(numeric_format_incorrect)
{
alert("$TEXT{Please_enter_a_number_}");
}
else
{
return 1;
}
return 0;
}
function format_filesize_with_unit(num,space,forceMB,forceKB)
{
if(!isNum(num,1)) { return "?" + space + "$PREF{KB}"; }
var unit;
if( ((num > 999999) || forceMB) && !forceKB)
{
num = num/(1024*1024);
num = num.toString();
var testnum = num.replace( /^(\\d+\\.\\d).*/, '\$1' ); // show 1 decimal place. // extra escaping b/c printing JS from Perl.
if(testnum == '0.0')
{
testnum = num.replace( /^(\\d+\\.\\d\\d).*/, '\$1' ); // show 2 decimal places.
}
if(testnum == '0.00')
{
testnum = num.replace( /^(\\d+\\.\\d\\d\\d).*/, '\$1' ); // show 3 decimal places.
}
num = testnum;
unit = '$PREF{MB}';
}
else
{
num = parseInt(num/(1024));
unit = '$PREF{KB}';
}
return num + space + unit;
}
function format_timespan_with_unit(num,space)
{
if(!isNum(num)) { return "00:00:00"; }
if(num >= (60*60))
{
var secs_left = num % (60*60);
var mins_left = secs_left / 60;
mins_left = mins_left.toString();
mins_left = mins_left.replace( /^(\\d+)\\..*/, '\$1' ); // show no decimal places. // extra escaping b/c printing JS from Perl.
mins_left = mins_left.replace( /^(\\d)\$/, '0\$1' ); // for single-digits, prepend a zero.
num = num/(60*60);
num = num.toString();
num = num.replace( /^(\\d+)\\..*/, '\$1' ); // show no decimal places.
num = num + ':' + mins_left + ':00';
}
else if(num >= 60)
{
var secs_left = num % 60;
secs_left = secs_left.toString().replace( /^(\\d)\$/, '0\$1' ); // for single-digits, prepend a zero.
num = num/60;
num = num.toString();
num = num.replace( /^(\\d+)\\..*/, '\$1' ); // show no decimal places. // extra escaping b/c printing JS from Perl.
num = num.replace( /^(\\d)\$/, '0\$1' ); // for single-digits, prepend a zero.
num = '00:' + num + ':' + secs_left;
}
else
{
num = num.toString();
num = num.replace( /^(\\d+)\\..*/, '\$1' ); // show no decimal places. // extra escaping b/c printing JS from Perl.
num = num.replace( /^(\\d)\$/, '0\$1' ); // for single-digits, prepend a zero.
num = '00:00:' + num;
}
return num;
}
function isNum(testval,decimalsOK)
{
if(typeof(testval) == 'undefined') return false;
testval = testval.toString();
if (!testval.length) return false;
var numbers = decimalsOK ? '.0123456789' : '0123456789';
for (i=0; i$TEXT{Delete}';
}
else if(cols[i].className == 'mv')
{
div.innerHTML += '$TEXT{Move} ';
}
else if(cols[i].className == 'info')
{
div.innerHTML += '$TEXT{Info} ';
}
else if(cols[i].className == 'sel')
{
div.innerHTML += '$TEXT{Select} ';
}
else if(cols[i].className == 'mopts')
{
div.innerHTML += '' + link.innerHTML + ' ';
}
else if(cols[i].className == 'perms')
{
div.innerHTML += '$TEXT{Permissions} ';
}
}
else
{
if(cols[i].className == 'size')
{
size = ` . ($PREF{show_size_column_in_filelist} =~ /no/i ? qq`'$TEXT{Size}: ' + children[j].nodeValue + '
'` : qq`''`) . qq`;
}
else if(cols[i].className == 'date')
{
date = ` . ($PREF{show_date_column_in_filelist} =~ /no/i ? qq`'$TEXT{Date}: ' + children[j].nodeValue + '
'` : qq`''`) . qq`;
}
}
}
}
div.innerHTML += size + date;
if(!div.innerHTML)
{
div.innerHTML += '$TEXT{_none_} ';
}
//div.innerHTML += "$TEXT{_Close_Menu_} ";
window.setTimeout("set_body_closeoptsmenu()", 500);
}
function set_body_closeoptsmenu()
{
old_document_body_onclick = document.body.onclick;
document.body.onclick = closeoptsmenu;
}
function closeoptsmenu()
{
if(document.getElementById("theoptsmenu"))
{
document.body.removeChild(document.getElementById("theoptsmenu"));
document.body.onclick = old_document_body_onclick;
return true;
}
}
function set_itemaction_highlights()
{
var list = document.getElementById("filelist") ? document.getElementById("filelist") : document.getElementById("filegrid")
if(list)
{
var filelist_inputs = list.getElementsByTagName("input");
var i = 0;
for(i = 0; i < filelist_inputs.length; i++)
{
if(filelist_inputs[i].className.indexOf('itemaction') != -1)
{
filelist_inputs[i].onchange = setbghighlight;
filelist_inputs[i].onclick = setbghighlight; // IE is garbage.
}
}
}
}
function setbghighlight()
{
var p = this.parentNode.parentNode;
if(this.checked)
{
p.style.background = '$PREF{filelist_row_highlight_bgcolor}';
p.onmouseover = '';
p.onmouseout = '';
}
else
{
if(document.getElementById("filelist"))
{
p.onmouseover = setbg;
unsettext(p);
if(p.className.indexOf('odd') != -1)
{
p.style.background = '$PREF{filelist_row_normal_bgcolor_odd}';
p.onmouseout = unsetbgodd;
}
else
{
p.style.background = '$PREF{filelist_row_normal_bgcolor_even}';
p.onmouseout = unsetbgeven;
}
}
else // filegrid.
{
p.style.background = '';
}
}
}
function set_row_mouseovers()
{
if(document.getElementById("filelist"))
{
var filelist_rows = document.getElementById("filelist").getElementsByTagName("tr");
for(i = 0; i < filelist_rows.length; i++)
{
var r = filelist_rows[i];
if(r.className.indexOf('even') != -1) { r.onmouseover = setbg; r.onmouseout = unsetbgeven; }
else if(r.className.indexOf('odd') != -1) { r.onmouseover = setbg; r.onmouseout = unsetbgodd; }
}
}
}
function setbg()
{
this.style.background = '$PREF{filelist_row_hover_bgcolor}';
` . (high_contrast_filelist_enabled() ? qq`
var tds = this.getElementsByTagName("td");
var i = 0;
for(i = 0; i < tds.length; i++)
{
tds[i].style.color = '$PREF{filelist_row_hover_text_color}';
if(tds[i].getElementsByTagName("a"))
{
var links = tds[i].getElementsByTagName("a");
var j = 0;
for(j = 0; j < links.length; j++)
{
links[j].style.color = '$PREF{filelist_row_hover_link_color}';
}
}
}
` : '') . qq`
}
function unsetbgeven()
{
this.style.background = '$PREF{filelist_row_normal_bgcolor_even}';
` . (high_contrast_filelist_enabled() ? qq`unsettext(this);` : '') . qq`
}
function unsetbgodd()
{
this.style.background = '$PREF{filelist_row_normal_bgcolor_odd}';
` . (high_contrast_filelist_enabled() ? qq`unsettext(this);` : '') . qq`
}
function unsettext(myself)
{
var tds = myself.getElementsByTagName("td");
var i = 0;
for(i = 0; i < tds.length; i++)
{
tds[i].style.color = '$PREF{filelist_row_normal_text_color}';
if(tds[i].getElementsByTagName("a"))
{
var links = tds[i].getElementsByTagName("a");
var j = 0;
for(j = 0; j < links.length; j++)
{
links[j].style.color = '$PREF{filelist_row_normal_link_color}';
}
}
}
}
function autofill_human_test()
{
var htfield = document.getElementById("fcht2");
if(htfield)
{
htfield.value = '$PREF{humantest_code}';
}
}
var serial_request = false;
function set_form_serial_number()
{
var url_to_get = '$ENV{SCRIPT_NAME}?ajax_get_serial';
if(document.getElementById('theuploadform'))
{
serial_request = new_ajax_request();
if(!serial_request)
{
alert('Error: could not get serial number; please reload this page.');
return false;
}
serial_request.onreadystatechange = set_form_serial_number__stage2;
serial_request.open('GET', url_to_get, true);
serial_request.send(null);
}
}
function set_form_serial_number__stage2()
{
if(serial_request)
{
if(serial_request.readyState == 4)
{
if(serial_request.status == 200)
{
var rawdata = serial_request.responseText.match(/(.+)<\\/data>/);
var new_serial = rawdata[1];
var theform = document.getElementById('theuploadform');
theform.action = theform.action.replace(/serial=\\w+/, 'serial=' + new_serial);
}
}
}
}
var humantest_request = false;
var uploadbutton_text_default = '';
function check_humanity()
{
var url_to_get = '$ENV{SCRIPT_NAME}?ajax_do_humantest&fcht1=' + document.getElementById("fcht1").value + '&fcht2=' + document.getElementById("fcht2").value;
if(document.getElementById('theuploadform'))
{
humantest_request = new_ajax_request();
if(!humantest_request)
{
alert('Error: could not run human test.');
return false;
}
uploadbutton_text_default = document.getElementById("uploadbutton").value;
document.getElementById("uploadbutton").value = "$TEXT{Please_wait}";
document.getElementById("uploadbutton").disabled = true;
humantest_request.onreadystatechange = check_humanity__stage2;
humantest_request.open('GET', url_to_get, true);
humantest_request.send(null);
}
}
function check_humanity__stage2()
{
if(humantest_request)
{
if(humantest_request.readyState == 4)
{
if(humantest_request.status == 200)
{
var rawdata = humantest_request.responseText.match(/(.+)<\\/data>/);
if(rawdata[1].match(/passed=true/))
check_humanity__finish(1);
else
check_humanity__finish(0);
}
}
}
}
function check_humanity__finish(testsuccess)
{
document.getElementById("uploadbutton").value = uploadbutton_text_default;
document.getElementById("uploadbutton").disabled = false;
if(testsuccess)
do_upload();
else
alert("$TEXT{Error__failed_human_test__please_try_again_}");
}
function add_file_element()
{
var firstfile_div = document.getElementById("firstfile");
var newfile_div = firstfile_div.cloneNode(true);
newfile_div.id = '';
var newnum = document.getElementById("numfileelements").value;
newnum++;
if(newnum > $PREF{max_files_allowed})
{
alert("$TEXT{The_owner_of_this_site_has_set_the_limit_to} $PREF{max_files_allowed}.");
return;
}
var i = 0;
var kids = new Array();
var new_divs = newfile_div.getElementsByTagName("div");
for(i = 0; i < new_divs.length; i++)
kids.push(new_divs[i]);
var new_inputs = newfile_div.getElementsByTagName("input");
for(i = 0; i < new_inputs.length; i++)
kids.push(new_inputs[i]);
var new_selects = newfile_div.getElementsByTagName("select");
for(i = 0; i < new_selects.length; i++)
kids.push(new_selects[i]);
var new_textareas = newfile_div.getElementsByTagName("textarea");
for(i = 0; i < new_textareas.length; i++)
kids.push(new_textareas[i]);
var new_labels = newfile_div.getElementsByTagName("label");
for(i = 0; i < new_labels.length; i++)
kids.push(new_labels[i]);
var new_spans = newfile_div.getElementsByTagName("span");
for(i = 0; i < new_spans.length; i++)
kids.push(new_spans[i]);
for(i = 0; i < kids.length; i++)
{
if(kids[i].name == 'uploadname1')
{
kids[i].id = 'uploadname' + newnum;
kids[i].name = 'uploadname' + newnum;
kids[i].value = '';
kids[i].className = kids[i].className.replace(/required/, '');
}
else if(kids[i].name == 'subdir1')
kids[i].name = 'subdir' + newnum;
else if(kids[i].name == 'newsubdir1')
kids[i].name = 'newsubdir' + newnum;
else if(kids[i].className == 'filei')
kids[i].innerHTML = newnum;
else if(kids[i].name && kids[i].name.match(/\\w+1\$/)) // for perfile formfields.
{
kids[i].name = kids[i].name.replace(/1\$/, newnum);
kids[i].value = '';
if(kids[i].id && kids[i].id.match(/\\w+1\$/))
{
kids[i].id = kids[i].id.replace(/1\$/, newnum);
}
}
}
if((newnum % 2)==0)
newfile_div.className = newfile_div.className.replace(/odd/, 'even');
newfile_div.className = newfile_div.className.replace(/first/, ''); // the new one isn't first...
firstfile_div.className = firstfile_div.className.replace(/last/, ''); // ...and now the first one isn't last anymore.
document.getElementById("numfileelements").value = newnum;
document.getElementById("numitems").value = newnum;
firstfile_div.parentNode.appendChild(newfile_div);
var spans = document.getElementById("filefields").getElementsByTagName("span");
for(i = 0; i < spans.length; i++)
{
if(spans[i].className == 'fileitotal')
spans[i].innerHTML = newnum;
}
}
var mouseX = 0;
var mouseY = 0;
function getMousePosition(event)
{
var mouseX = window.event ? window.event.clientX : event.pageX;
var mouseY = window.event ? window.event.clientY : event.pageY;
//document.getElementById("title").innerHTML = mouseX + ' ' + mouseY;
}
function mouse_coords_init()
{
document.onmousemove = getMousePosition;
}
function get_random_text()
{
var now = new Date();
var time = (now.getTime() - now.getMilliseconds()) / 1000;
var ms = now.getMilliseconds();
var ua = navigator.userAgent;
var sw = screen.width;
var sh = screen.height;
var rand = Math.random();
var mime = navigator.mimeTypes;
var mimestring = '';
for(var i=0; i> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for(var i = 0; i < x.length; i += 16)
{
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for(var j = 0; j < 80; j++)
{
if(j < 16) w[j] = x[i + j];
else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
function sha1_ft(t, b, c, d)
{
if(t < 20) return (b & c) | ((~b) & d);
if(t < 40) return b ^ c ^ d;
if(t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
function sha1_kt(t)
{
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
function safe_add(x, y)
{
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
function rol(num, cnt)
{
return (num << cnt) | (num >>> (32 - cnt));
}
function str2binb(str)
{
var bin = Array();
var mask = (1 << chrsz) - 1;
for(var i = 0; i < str.length * chrsz; i += chrsz)
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
return bin;
}
function binb2hex(binarray)
{
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for(var i = 0; i < binarray.length * 4; i++)
{
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
}
return str;
}
//////////////////////////////////////////////////////////// End SHA-1 code.
function schedule_onload_action(newfunc)
{
var already_scheduled = window.onload;
if(typeof window.onload != 'function')
{
window.onload = newfunc;
}
else
{
window.onload = function()
{
already_scheduled();
newfunc();
}
}
}
schedule_onload_action(mouse_coords_init);
//schedule_onload_action(set_form_serial_number);
schedule_onload_action(autofill_human_test);
schedule_onload_action(set_row_mouseovers);
schedule_onload_action(set_itemaction_highlights);
schedule_onload_action(generate_new_serial_number);
schedule_onload_action(start_juststatus);
$PREF{custom_js_code}
`;
return $js;
}
sub get_css
{
my $css = qq`
/* html { min-height: 100%; margin-bottom: 1px; } /* /* so #viewpath doesn't shift in FF when there's no scrollbar. -- update 200703: no longer needed since #viewpath is inside the table now. */
#fcbody { background: #ddd; font-family: sans-serif; font-size: 9pt; text-align: center; }
.popupstatusbody { background: #fff !important; }
#fcbody dl { margin: 0 0 1em; padding: 0; }
#fcbody dt, dd { margin: 0; padding: 0; }
#pb { margin: 14px auto 2px auto; padding: 3px; }
#pb a { color: #000; }
#pb a:hover { color: #aaa; }
#pb { position: absolute; left: -8000px; }
#fcfooter { color: #8b8f8b; margin: 24px auto 4px auto; font-size: 8pt; }
/* #uploaderpage, #filelistpage, #defaultpage etc, are the outer containers for their respective pages. */
#uploaderpage, #uploadcompletepage, #filelistpage, #defaultpage { width: 700px; margin: 15px auto; background: white; border: 1px solid #999; padding: 10px; }
#uploaderpage #title, #popupstatuspage #title, #uploadcompletepage #title, #filelistpage #title, #defaultpage #title { font-size: 200%; font-weight: bold; padding: 8px; }
#uploaderpage, #uploadcompletepage { width: 450px; }
#uploaderpage #intro { text-align: justify; }
#popupstatuspage { padding: 0; margin: 0 auto; }
#specialnote { font-weight: bold; }
#fc-container { padding: 8px 12px; } /* this is the whole page except for title and pb */
#fc-container a { color: #507090; }
#fc-container a:hover { color: #aaa; }
/* #progBarContainer includes everything (progress bar, text, table); #theMeter includes just the bar and the text (percent and rate) */
#progBarContainer { padding-top: 10px; }
#progBar, #progBarText { width: $PREF{progress_bar_width}px; }
#progBar { margin: 2px auto; height: 20px; border: 1px inset; background: #eee; text-align: left; }
#progBarDone { width: 0; height: 20px; border-right: 1px solid #444; background: #507090; background: #4a6695 url($PREF{path_to_filelist_images}pb-bg-02.png) repeat-x; }
#theMeter { margin-bottom: 20px; }
#uploadCompleteMsg { width: $PREF{progress_bar_width}px; margin: 0 auto 20px; }
#progBarContainer table { width: $PREF{progress_bar_width}px; margin: 4px auto 20px auto; text-align: right; border-collapse: collapse; border: 0; border-bottom: 1px solid #bbb;}
#progBarContainer table td { border-top: 1px solid #bbb; text-align: center; }
#progBarContainer #upload-row-1, #progBarContainer #upload-row-3 { background: #e6e6e6; }
#progBarContainer #upload-row-2, #progBarContainer #upload-row-4 { background: #efefef; }
#progBarText { font-size: 90%; margin: 1px auto; white-space: nowrap; }
#progRate { float: left; text-align: left; width: 19%; }
#progStatus { float: left; text-align: center; width: 70%; font-style: italic; }
#progPercent { float: right; text-align: right; width: 10%; }
#uploadsummary { margin-top: 20px; margin-bottom: 20px !important; }
#uploadsummary .file { margin-top: 8px; }
#uploadsummary dt { font-weight: bold; margin-bottom: 10px; }
#uploadstats dt { font-weight: bold; margin-bottom: 10px; }
td.headercell { font-weight: bold; }
`
. (
($PREF{using_upload_hook} =~ /yes/i)
?
qq`#tca1,#tcb1,#tcc1,#tcd1 { width: 25%; }`
. qq`\n#tca2,#donef,#leftf,#totalf { width: 25%; }`
. qq`\n#tca3,#dones,#lefts,#totals { width: 25%; }`
. qq`\n#tca4,#donet,#leftt,#totalt { width: 25%; }`
:
qq`#tca1,#tcb1,#tcc1,#tcd1 { width: 33%; }`
. qq`\n#tca2,#donef,#leftf,#totalf { position: absolute; left: -10000px; overflow: hidden; height: 0; }`
. qq`\n#tca3,#dones,#lefts,#totals { width: 34%; }`
. qq`\n#tca4,#donet,#leftt,#totalt { width: 33%; }`
)
. qq`
#viewpath { white-space: nowrap; background: #efefef; margin: 0 auto 0 auto; padding: 0px 4px 0px 4px; }
#viewpath-outer { padding: 6px; }
/* #viewpath-inner { border: 1px solid #000; } */
#viewpath-text { text-align: left; float: left; width: 61%; margin-top: 2px; }
#filelist #viewpath-text a { display: inline; }
div#optmenutop { text-align: right; float: right; width: 29%; }
#optmenutop select, #optmenutop input { margin: 0; padding: 0; vertical-align: middle; font-size: 85%; }
.actionrow .controls select, .actionrow .controls input { margin: 0; padding: 0; vertical-align: middle; font-size: 85%; }
/* form#optionstop, form#optionsbottom { display: inline; margin: 0; padding: 0; } */
#optmenutop optgroup, #optmenubottom optgroup { font-weight: bold; font-style: normal; }
#optmenutop option, #optmenubottom option { padding-left: 20px; }
#filelist { text-align: left; border-collapse: collapse; margin: 0 auto 2px auto; border: 1px solid #444; width: 670px; }
#filelist tr { border: 0px solid white; }
#filelist tr.even { background: $PREF{filelist_row_normal_bgcolor_even}; }
#filelist tr.odd { background: $PREF{filelist_row_normal_bgcolor_odd}; }
/* Add these to replace the JS-based row mouseovers:
#filelist tr.odd:hover, #filelist tr.even:hover { background: #507090; color: #fff; }
#filelist tr.odd:hover a, #filelist tr.even:hover a { color: #fff; }
*/
#filelist td { }
#filelist td#viewpath-cell { padding: 0; }
#filelist td#viewpath-cell a { text-decoration: underline; }
#filelist a:link { color: $PREF{filelist_row_normal_link_color}; text-decoration: none; display: block; width: 100%; padding: 4px 2px; }
#filelist a:visited { color: $PREF{filelist_row_visited_link_color}; text-decoration: none; display: block; width: 100%; padding: 4px 2px; }
#filelist a:hover { color: $PREF{filelist_row_hover_link_color}; }
#filelist .emptytable { text-align: center; font-style: italic; padding: 4px; }
#filelist td.pname { background: url($PREF{path_to_filelist_images}fcarrow.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.fname { background: url($PREF{path_to_filelist_images}fcfile.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.diricon { background: url($PREF{path_to_filelist_images}fcfolder.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.homeicon { background: url($PREF{path_to_filelist_images}fchome.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.dname { background-color: inherit; }
#filelist td.pname, #filelist td.dname, #filelist td.fname { width: 340px; padding-left: 20px; }
/* #filelist td.thumb { background-image: none; } */
#filelist .info, #filelist .mv, #filelist .sel, #filelist .del, #filelist .opt, #filelist .cinfo { text-align: center; }
#filelist .size { text-align: right; }
#filelist .size { white-space: pre; padding: 4px 10px 4px 2px; }
#filelist .date { white-space: pre; padding: 4px 5px; text-align: right; }
#filelist .info, #filelist .mv, #filelist .del, #filelist .sel, #filelist .opt, #filelist .cinfo { padding: 0 6px; }
#filelist .spc { padding: 0 6px 0 3px; }
#filelist .info, #filelist .mv, #filelist .sel, #filelist .mopts, #filelist .del, #filelist .perms { display: none; }
#filegrid .info, #filegrid .mv, #filegrid .sel, #filegrid .mopts, #filegrid .del, #filegrid .perms { display: none; }
#filelist #infohead, #filelist #mvhead, #filelist #selhead, #filelist #delhead, #filelist #moptshead, #filelist #permshead { display: none; }
#filegrid #infohead, #filegrid #mvhead, #filegrid #selhead, #filegrid #delhead, #filegrid #moptshead, #filegrid #permshead { display: none; }
.optsmenu { min-width: 90px; max-width: 150px; background: #eee; border: 1px solid #999; color: #000; text-align: left; }
.optsmenu a { display: block; text-decoration: none; padding: 5px; color: #000; }
.optsmenu div { display: block; padding: 5px; color: #555; white-space: nowrap; font-style: italic; }
.optsmenu a:hover { background: #c7c7c7; }
#filelist th { text-align: center; padding: 5px 0; font-size: 120%; background: #507090; color: #fff; border-bottom: 1px solid #444; }
#filelist #namehead { text-align: left; padding-left: 7px; }
#filelist #namehead a, #filelist #sizehead a, #filelist #datehead a { color: #fff; font-weight: bold; }
#filegrid { margin: 10px auto; text-align: center; }
#filegrid td { width: 33%; padding: 10px; border: 1px solid #fff; }
#filegrid td:hover { background: #efefef; border: 1px solid #bbb; }
#filegrid a.thumb { display: block; }
#filegrid a.icon { display: block; border: 0; }
#filegrid img.icon { border: 0; }
#filegrid .prnt .info, #filegrid .prnt .size, #filegrid .prnt .mv, #filegrid .prnt .sel, #filegrid .prnt .del { display: none; }
#filegrid .dir .info, #filegrid .dir .sel { display: none; }
#filegrid td#viewpath-cell a { text-decoration: underline; }
#filegrid .pname a:link, #filegrid .dname a:link, #filegrid .fname a:link { color: #000; text-decoration: none; padding: 4px 2px; }
#filegrid .pname a:visited, #filegrid .dname a:visited, #filegrid .fname a:visited { color: #000; text-decoration: none; padding: 4px 2px; }
#filegrid .pname a:hover, #filegrid .dname a:hover, #filegrid .fname a:hover { color: #000; text-decoration: underline; }
#filegrid .date, #filegrid .size { font-size: 90%; color: #676767; }
#filegrid .emptytable { text-align: center; font-style: italic; padding: 4px; }
form#itemactions { margin: 0; padding: 0; }
#filelist .actionrow a:link, #filelist .actionrow a:visited, #filegrid .actionrow a:link, #filegrid .actionrow a:visited { text-decoration: none; display: inline; width: auto; padding: 0; margin: 0; }
td.actionrow { padding: 6px; text-align: right; vertical-align: middle; white-space: nowrap; }
#filegrid { width: 100%; }
.actionrow .sizeinfo { float: left; text-align: left; padding-left: 5px; margin-top: 2px; }
.actionrow .links { float: right; text-align: right; padding-right: 10px; margin-top: 2px; width: 20%; }
.actionrow .controls { float: right; text-align: right; padding-right: 5px; padding-left: 8px; }
.actionrow a.toggle-counts { text-decoration: underline !important; }
#fcinfo { border-collapse: collapse; border: 1px solid #ccc; background: #efefef; padding: 3px; }
#fcinfo tr:hover { background: #e0e0e0; }
#fcinfo td { border-top: 1px solid #ccc; padding: 4px; }
#fcinfo .spacer { height: 25px; }
#fcinfo .f { text-align: left; width: 50%; font-weight: bold; }
#fcinfo .v { text-align: left; }
#fcinfo .h { text-align: left; font-size: 16pt; font-weight: bold; }
#setfilecount_wrapper { margin: 15px 0 12px 0; }
#theuploadform { }
#filefields { border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; border: 1px solid #ccc; /* background: #e3e3e3; */ }
#filefields .even { background: #eee; }
#filefields .odd { /* background: #e3e3e3; */ }
.fileelement { margin-bottom: 5px; }
.onesubgroup { padding: 15px 0 10px 0; }
.onesubgroup div { margin-bottom: 5px; }
.onesubgroup label { display: inline; font-size: 100%; } /* we're centered by default, so we don't need the floats and clearfix-filefield stuff; just inline it. */
#addanotherfile { margin-top: 15px; }
#uploadbutton { margin: 14px 0 6px 0; }
.uploader-comments { text-align: left; border: 1px solid #e0e0e0; padding: 4px; }
#fcbody .hr { height: 1px; border-bottom: 1px solid #000; margin: 15px 2px; line-height: 1px; }
#fcbody h1, #fcbody h2, #fcbody h3, #fcbody h4, #fcbody h5, #fcbody h6 { margin-top: 5px; margin-bottom: 5px; }
#fcbody form { margin: 0; padding: 0; }
#fcbody p { margin-top: 10px; margin-bottom: 10px; }
.comments textarea
{
width: 300px; height: 50px;
}
#top-textboxes, #perfile-textboxes, #bottom-textboxes, #specialnote, #fc-humantest
{
margin: 25px 0;
padding: 5px;
border: 1px solid #ccc;
}
#top-textboxes div, #perfile-textboxes div, #bottom-textboxes div
{
margin: 7px 2px;
}
#top-textboxes-title, #perfile-textboxes-title, #bottom-textboxes-title, #setfilecount_title, #choosefiles_title
{
font-size: 110%;
font-weight: bold;
}
#setfilecount_title { margin-bottom: 8px; }
#choosefiles_title { margin-top: 10px; }
#perfile-textboxes
{
margin: 8px 20px;
}
.textboxes-label
{
float: left;
width: 47%;
text-align: right;
margin-top: 3px !important;
}
.radiobox
{
margin-top: 3px !important;
}
#top-textboxes input.textfield, #top-textboxes textarea, #top-textboxes .radiobox,
#perfile-textboxes input.textfield, #perfile-textboxes textarea, #perfile-textboxes .radiobox,
#bottom-textboxes input.textfield, #bottom-textboxes textarea, #bottom-textboxes .radiobox
{
float: left;
width: 37%;
display: block;
}
#top-textboxes select,
#perfile-textboxes select,
#bottom-textboxes select
{
float: left;
}
#selections_table
{
border-collapse: collapse;
border: 1px solid #9a9a9a;
margin: 15px auto;
text-align: left;
}
#selections_table .odd { background: #e6e6e6; }
#selections_table .even { background: #efefef; }
#selections_table td { padding: 4px 4px 4px 20px; background: url($PREF{path_to_filelist_images}fcfile.gif) 1% 50% no-repeat; }
#place_order { text-align: center; }
#theorderform { width: 300px; margin: 0 auto; padding: 3px; text-align: left; border: 1px solid #999; background: #e6e6e6; }
#theorderform .text { width: 150px; margin: 5px; padding: 3px; border: 1px solid #676767; }
#theorderform .submit input { margin: 5px; }
#itemperms { border-collapse: collapse; border: 1px solid #bbb; text-align: center; margin: 10px auto; color: #575757; width: 90%; }
#itemperms th { background: #507090; color: #fff; padding: 12px; font: bold 16pt sans-serif; }
#itemperms .heading td { background: #83B96B; color: #fff; padding: 4px; font: bold 10pt sans-serif; }
#itemperms td { padding: 2px; }
#itemperms td.name { text-align: left; }
#itemperms td.path { text-align: left; }
#itemperms td.none { text-align: left; font-style: italic; }
#itemperms td.ro, #itemperms td.rw { text-align: left; padding-left: 80px; white-space: nowrap; }
#itemperms tr.odd { background: #e9e9e9; }
#itemperms tr.even { background: #efefef; }
#itemperms a { color: #000; }
#itemperms tr:hover { background: #83B96B; color: #fff; }
#itemperms tr:hover a { color: #fff; text-decoration: underline; }
#itemperms tr:hover a:hover { color: #000; }
.itemperms-letters { font-size: 120%; font-weight: bold; }
#fc-container .itemperms-letters a { padding: 4px; color: #507090; text-decoration: none; }
#fc-container .itemperms-letters a:hover { background: #507090; color: #fff; }
#fc-container .itemperms-letters a.current { text-decoration: underline; }
#itemperms .button { margin: 10px; }
.footnote { font: italic 9pt sans-serif; color: #888; margin: 5px 40px; }
.clear { height: 0; line-height: 0; font-size: 0; clear: both; }
.clearfixtb:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfixtb { display: inline-block; }
/* Hides from IE-mac \*/
* html .clearfixtb {height: 1%;}
.clearfixtb {display: block;}
/* End hide from IE-mac */
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix { display: inline-block; }
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
`;
my %styles = ();
$styles{light} = qq`
#filelist tr.actionrow { background: #507090; color: #fff; }
#filelist td.actionrow { border-top: 1px solid #444; }
#filelist .actionrow a:link { color: #fff; }
#filelist .actionrow a:visited { color: #fff; }
#filelist .actionrow a:hover, #filelist .actionrow a:visited:hover { color: #000; }
#filelist td#viewpath-cell a { color: #507090; }
#filelist td#viewpath-cell a:hover { color: #aaa; }
#filegrid td#viewpath-cell { background: #efefef; border: 1px solid #bbb; padding: 2px; }
#filegrid td.actionrow { background: #efefef; border: 1px solid #bbb; }
`;
$styles{light_ie} = qq`
`;
$styles{big} = qq`
/* big blocky style: */
#filelist a:link, #filelist a:visited { }
#filelist th, #filelist td { padding: 10px 6px; }
#filelist th { font-size: 140%; }
#filelist td.pname { background: url($PREF{path_to_filelist_images}fcarrowbig.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.dname { background: url($PREF{path_to_filelist_images}fcfolderbig.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.fname { background: url($PREF{path_to_filelist_images}fcfilebig.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.pname, #filelist td.dname, #filelist td.fname { width: 350px; padding-left: 15px; }
#filelist td.pname a:link, #filelist td.dname a:link, #filelist td.fname a:link, td.pname, #filelist td.pname a:visited { color: black; font-size: 14px; font-weight: bold; text-decoration: none; }
#filelist td.dname a:visited, #filelist td.fname a:visited { color: #000; font-size: 14px; font-weight: bold; text-decoration: none; }
#filelist td.pname a:hover, #filelist td.dname a:hover, #filelist td.fname a:hover { }
#filelist td.dname { padding-top: 12px; padding-bottom: 8px; }
#filelist tr.actionrow { background: #507090; color: #fff; }
#filelist td.actionrow { border-top: 1px solid #444; }
#filelist .actionrow a:link { color: #fff; }
#filelist .actionrow a:visited { color: #fff; }
#filelist .actionrow a:hover, #filelist .actionrow a:visited:hover { color: #000; }
#filelist td#viewpath-cell a { color: #507090; }
#filelist td#viewpath-cell a:hover { color: #aaa; }
#filelist td#viewpath-cell { background: #efefef; padding: 2px; }
#filegrid td#viewpath-cell { background: #efefef; border: 1px solid #bbb; padding: 2px; }
#filegrid td.actionrow { background: #efefef; border: 1px solid #bbb; }
`;
$styles{big_ie} = qq`
`;
$styles{dark} = qq`
#fcbody { background: #434343; color: #fff; }
#title { padding-top: 10px !important; color: #fff; }
#intro { margin: 0 7px; }
#fc-container a { color: #ccc; }
#fc-container a:hover { color: #000; }
#uploaderpage, #uploadcompletepage, #filelistpage, #defaultpage { background: #5a775a; border: 0px; padding: 0; padding-bottom: 10px; }
#fc-container { padding: 0; margin: 0; }
#uploaderpage { width: 600px; padding-top: 12px; }
#uploadbuttonwrapper { margin: 15px 5px; }
#progBarContainer table { color: #fff; background: #424242; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#progBarContainer #upload-row-1, #progBarContainer #upload-row-3 { background: #545454; }
#progBarContainer #upload-row-2, #progBarContainer #upload-row-4 { background: #545454; }
#progBarContainer table td#tca1,#progBarContainer table td#tca2,#progBarContainer table td#tca3,#progBarContainer table td#tca4 { border-top: 0; }
#dones,#lefts,#totals,#donef,#leftf,#totalf,#donet,#leftt,#totalt { border-top: 1px solid #676767; }
#progBar { background: #6a6a6a; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#progBarDone { border-right: 1px solid #000; background: #993333; }
#filefields { background: #333; background: transparent; color: #000; margin: 0px 20px; border: 1px solid #393939; }
#filefields .even { background: #5a6d5a; }
#filefields div { margin-top: 8px; margin-bottom: 12px; }
.onesubgroup { padding: 3px 0; }
#top-textboxes, #perfile-textboxes, #bottom-textboxes { margin: 25px 20px; padding: 5px; border: 1px solid #393939; }
table#filelist { color: $PREF{filelist_row_normal_text_color}; border: 1px solid #333; border-bottom: 1px solid #333; margin: 0 auto 20px auto; }
#filelist th { background: #333; border-bottom: 0px solid #000; }
#filelist td { border-top: 1px solid #676767; }
#filelist a:hover { color: #fff; }
#filelist td#viewpath-cell { border-top: 0; border-bottom: 1px solid #676767; padding: 0; }
#filelist td#viewpath-cell a:hover { color: #000; }
#viewpath { background: $PREF{filelist_row_normal_bgcolor_even}; }
#filegrid { width: 95%; }
#filegrid { border-collapse: collapse; }
#filegrid td { border: 0; }
#filegrid td:hover { border: 0; background: #648564; }
#filegrid .date, #filegrid .size { font-size: 90%; color: #fff; }
#filegrid td.actionrow { background: $PREF{filelist_row_normal_bgcolor_even}; border: 1px solid #333; }
#filegrid td#viewpath-cell { background: $PREF{filelist_row_normal_bgcolor_even}; border: 1px solid #333; padding: 3px; }
#filelist tr.actionrow { background: #333; }
#filelist td.actionrow { border-top: 1px solid #444; }
#filelist .actionrow a:link { color: #fff; }
#filelist .actionrow a:visited { color: #fff; }
#filelist .actionrow a:hover, #filelist .actionrow a:visited:hover { color: #000; }
#filelist td.actionrow { background: #333; border: 1px solid #333; }
#fcfooter { background: #333; margin-top: 0; padding: 10px 4px; }
#fcfooter a { color: #fff; text-decoration: none; font-weight: bold; }
#fcfooter a:hover { color: #aa3333; }
`;
$styles{dark_ie} = qq`
`;
$styles{darker} = qq`
#fcbody { background: #434343; color: #fff; }
#title { color: #fff; }
#fc-container a { color: #aaa; }
#fc-container a:hover { color: #fff; }
#uploaderpage, #uploadcompletepage, #filelistpage, #defaultpage { background: #575757; border: 0; border-top: 1px solid #fff; border-left: 1px solid #fff; border-bottom: 1px solid #000; border-right: 1px solid #000; }
#progBarContainer table { color: #fff; background: #424242; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#progBarContainer #upload-row-1, #progBarContainer #upload-row-3 { background: #424242; }
#progBarContainer #upload-row-2, #progBarContainer #upload-row-4 { background: #4a4a4a; }
#progBarContainer table td { border: 0; }
#progBar { background: #424242; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#progBarDone { border-right: 1px solid #444; background: #4a774a; }
#filefields { border: 0px solid #393939; background: #4a774a; color: black; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#filefields div { margin-top: 8px; margin-bottom: 12px; }
table#filelist { border: 0px solid #000; color: $PREF{filelist_row_normal_text_color}; border-top: 1px solid #000; border-left: 1px solid #000; border-bottom: 1px solid #fff; border-right: 1px solid #fff; }
#filelist th { background: #437743; border-bottom: 0px solid #000; }
/* input,select { background: #000; color: #fff; border: 2px inset #fff; } */
`;
$styles{minimal} = qq`
/* minimal style: */
#fcbody { background: #fff; font-family: serif; }
#uploaderpage, #uploadcompletepage, #filelistpage, #defaultpage { border: 0; }
#filelistpage #title { position: absolute; left: -10000px; }
#fcfooter { color: #555; }
#fcfooter a { color: #000; }
#fcfooter a:hover { color: #507090; }
#pb a { color: #737373; }
#pb a:hover { color: #000; }
#uploader { background: #fff; border: 0; }
#filelist { border: 1px dashed #bbb; border-left: 0; border-right: 0; }
#filelist tr { border-top: 1px dashed #bbb; }
#filelist tr.even { background: $PREF{filelist_row_normal_bgcolor_even}; background: #fff; }
#filelist tr.odd { background: $PREF{filelist_row_normal_bgcolor_odd}; background: #fff; }
#filelist a:link, #filelist a:visited { }
#filelist th, #filelist td { padding: 1px 6px; font-size: 0.8em; }
#filelist th { font-size: 0.9em; color: #000; background: #fff; border-bottom: 0; }
#filelist #namehead a, #filelist #sizehead a, #filelist #datehead a { color: #000; }
#filelist td.pname { background: url($PREF{path_to_filelist_images}fcarrow.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.dname { background: url($PREF{path_to_filelist_images}fcfolder.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.fname { background: url($PREF{path_to_filelist_images}fcfile.gif) 1% 50% no-repeat; background-color: inherit; }
#filelist td.pname, #filelist td.dname, #filelist td.fname { width: 350px; padding-left: 18px; }
#filelist td.pname a:link, #filelist td.dname a:link, #filelist td.fname a:link, td.pname, #filelist td.pname a:visited { color: black; text-decoration: none; }
#filelist td.dname a:visited, #filelist td.fname a:visited { color: #555; text-decoration: none; }
#filelist td.pname a:hover, #filelist td.dname a:hover, #filelist td.fname a:hover { }
td.size { color: #444; }
td.date { color: #444; }
`;
$styles{round} = qq`
/* round style: */
#uploaderpage, #uploadcompletepage, #filelistpage, #defaultpage { padding: 0; border: 0; }
#fcbody { background: #e3e3e3; }
#fcc1 { background: url($PREF{path_to_filelist_images}fcc-TL-e3e3e3.png) top left no-repeat; }
#fcc2 { background: url($PREF{path_to_filelist_images}fcc-TR-e3e3e3.png) top right no-repeat; }
#fcc3 { background: url($PREF{path_to_filelist_images}fcc-BR-e3e3e3.png) bottom right no-repeat; }
#fcc4 { background: url($PREF{path_to_filelist_images}fcc-BL-e3e3e3.png) bottom left no-repeat; }
#title img { margin: 10px auto 0px auto; }
#uploaderpage #title, #uploadcompletepage #title, #filelistpage #title, #defaultpage #title { padding: 10px 1px 1px 1px; color: #53a4cd; }
#fc-container, #intro { margin-top: 0px; padding-top: 0px; }
#uploaderpage #fcfooter { margin-bottom: 15px; font-size: 8pt; }
table#filelist { border: 0px solid #ccc; color: #444; width: 630px; margin: 10px auto 0 auto; }
#filelist th { background: #e3e3e3; border: 0; font-size: 90%; padding: 0px; color: #878787; }
#filelist #namehead a, #filelist #sizehead a, #filelist #datehead a { color: #878787; font-weight: bold; }
#filelist td { border-top: 1px solid #ddd; font-size: 8.5pt; }
#filelist td.actionrow { background: #e3e3e3; border-bottom: 1px solid #ddd; }
#filelist td.actionrow a:hover { color: #888; }
#filelist td#viewpath-cell { border-top: 0; border-bottom: 1px solid #ddd; background: transparent; padding: 0; }
#filelist td#viewpath-cell a:hover { color: #53a4cd; text-decoration: underline; }
#filegrid { margin: 10px auto 0 auto; border-collapse: collapse; background: #efefef; width: 630px; }
#filegrid td { border: 0; }
#filegrid td:hover { border: 0; background: #e6e6e6; }
#filegrid td.actionrow { background: #e3e3e3; border-top: 1px solid #bbb; border-bottom: 1px solid #bbb; }
#filegrid td.actionrow .links a { font-size: 8pt; }
#filegrid td#viewpath-cell { border-top: 0; border-bottom: 1px solid #bbb; background: transparent; padding: 0; }
#viewpath { background: #efefef url($PREF{path_to_filelist_images}fcc-TL-efefef.png) top left no-repeat; color: #53a4cd; margin: 0px auto 0px auto; text-align: left; border: 0; padding: 0; font-size: 8.5pt; }
#viewpath-outer { padding: 0; }
#viewpath-inner { background: url($PREF{path_to_filelist_images}fcc-TR-efefef.png) top right no-repeat; }
#viewpath-text { padding: 10px 5px 10px 15px; font-size: 110%; font-weight: bold; font-family: Tahoma, Arial, sans-serif; letter-spacing: 1px; }
#optmenutop { padding: 12px 15px 10px 5px; font-size: 10pt; }
#filelistpage #fcfooter { background: #efefef url($PREF{path_to_filelist_images}fcc-BR-efefef.png) bottom right no-repeat; color: #444; margin: 0px auto 10px auto; width: 630px; font-size: 8pt; }
#filelistpage #fcfooter-inner { background: url($PREF{path_to_filelist_images}fcc-BL-efefef.png) bottom left no-repeat; width: 630px; }
#filelistpage #fcfooter-text { padding: 14px; }
#fc-container a { font-weight: bold; }
#fc-container #fcfooter a { color: #65c460; text-decoration: none; font-size: 10pt; }
#fc-container #fcfooter a:hover { background: #65c460; color: white; }
`;
$css .= "\n\n" . $styles{$PREF{current_filelist_style}} . "\n\n";
# Note: any conditional comments must come AFTER custom_css_section.
$css .= qq`
$PREF{custom_css_section}
`
. qq`\n`
. $PREF{extra_header_output}
. qq`\n`
. qq`\n`;
}
elsif($PREF{default_sitewide_header_file} && -e $PREF{default_sitewide_header_file})
{
open(HEADERFH, "<$PREF{default_sitewide_header_file}") or die "$0: couldn't open \$PREF{default_sitewide_header_file} ('$PREF{default_sitewide_header_file}') for reading:: $!\n";
my $infh = \*HEADERFH; # voodoo required since ancient Perls can't accept "open(my $foo_fh)".
flock $infh, 1;
seek $infh, 0, 0;
while(<$infh>)
{
s!%%title%%!$title!g;
s!%%js%%!!g;
s!%%css%%! !g;
print $_;
}
close $infh or die "$0: couldn't close \$PREF{default_sitewide_header_file} ('$PREF{default_sitewide_header_file}') after reading:: $!\n";
print $PREF{extra_header_output};
print qq`$PREF{outer_container}\n`;
}
else
{
print $PREF{extra_header_output};
print qq`$PREF{outer_container}\n`;
}
print qq`$PREF{title}\n` if ($PREF{title} && $PREF{title_inside_perpage_container} !~ /yes/i);
print qq`$PREF{perpage_container}\n`; # this is #uploaderpage, #filelistpage, #defaultpage, etc.
print qq`$PREF{title}\n` if ($PREF{title} && $PREF{title_inside_perpage_container} =~ /yes/i);
print qq`$PREF{inner_container}\n`;
}
sub finish_html_output
{
return if $PREF{finish_html_output_called};
$PREF{finish_html_output_called} = 1;
print_footer_links(@_) if (@_ && $PREF{footer_inside_perpage_container} =~ /yes/i);
print qq`\n$PREF{inner_container_end}\n`; # end fc-container DIV.
print_powered_by() unless $PREF{hide_poweredby} =~ /yes/i;
print qq`\n$PREF{perpage_container_end}\n`; # end perpage_container DIV (#uploaderpage, #filelistpage, #defaultpage, etc).
print_footer_links(@_) if (@_ && $PREF{footer_inside_perpage_container} !~ /yes/i);
if(($qs =~ /debug/) && ($PREF{debug}))
{
my %perms = ();
my ($curdir) = ($ENV{SCRIPT_NAME} =~ m!^(.*)/!);
$perms{1}{item} = $ENV{SCRIPT_NAME};
$perms{1}{required} = '0755';
$perms{1}{actual} = sprintf "%04o", ((stat( "$PREF{DOCROOT}/$ENV{SCRIPT_NAME}" ))[2] & $PREF{writable_dir_perms_mask_as_octal});
$perms{2}{item} = $PREF{datadir};
$perms{2}{required} = $PREF{writable_dir_perms_as_string};
$perms{2}{actual} = sprintf "%04o", ((stat( "$PREF{datadir}" ))[2] & $PREF{writable_dir_perms_mask_as_octal});
$perms{3}{item} = $PREF{uploaded_files_realpath};
$perms{3}{required} = $PREF{writable_dir_perms_as_string};
$perms{3}{actual} = sprintf "%04o", ((stat( "$PREF{uploaded_files_realpath}" ))[2] & $PREF{writable_dir_perms_mask_as_octal});
print qq`\n\n\n\n`;
}
#
# print qq``
# . qq`\n`
# . qq`\n`
# . qq`\n`;
#
if($ENV{REQUEST_METHOD} =~ /post/i || $PREF{"print_full_html_tags_for_$PREF{on_page}"} =~ /yes/i || ($PREF{print_full_html_tags} =~ /yes/i && $PREF{"print_full_html_tags_for_$PREF{on_page}"} !~ /no/i))
{
print $PREF{extra_footer_output};
print qq`\n