#!/usr/local/bin/perl -w #revised by Nick (see http://illx.org for more details) use strict; use CGI qw(:standard); my $q = new CGI; my $upload_dir = "/tmp"; use constant MAX_FILE_SIZE => 1_048_576; # Limit each upload to 1 MB use constant MAX_DIR_SIZE => 100 * 1_048_576; # Limit total uploads to 100 MB use constant MAX_OPEN_TRIES => 100; print $q->header; my $s = $q->param('submit'); if($s) { my $filename = $q->param( "file" ) || error( $q, "No file received." ); my $ofile = $filename; if ( dir_size($upload_dir) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) { error( $q, "Upload directory is full." ); } # Allow letters, digits, periods, underscores, dashes # Convert anything else to an underscore $filename =~ s/[^\w.-]/_/g; if ( $filename =~ /^(\w[\w.-]*)/ ) { $filename = $1; } else { error( $q, "Invalid file name; files must start with a letter or number." ); } # Open output file, making sure the name is unique my $count = 0; while(1) { if(-e "$upload_dir/$filename") { $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e; error( $q, "Unable to save your file." ) if $count >= MAX_OPEN_TRIES; if(-e "$upload_dir/$filename") { next; } else { write_out(); last; } } else { write_out(); last; } $count++; } #didn't do the binmode stuff, because this is UNIX sub write_out { # Write contents to output file open(OUT, ">$upload_dir/$filename") or die "can't open $upload_dir/$filename: $!\n"; while (<$ofile>) { print OUT $_; #print $q->br,"$_",$q->br; } print "file uploaded"; close(OUT); } } else { print $q->start_multipart_form(), $q->filefield(-name=>'file',-size=>60),$q->br, $q->submit(-label=>'Upload File',-name=>'submit',-value=>'test'), $q->end_form; } sub dir_size { my $dir = shift; my $dir_size = 0; # Loop through files and sum the sizes; doesn't descend down subdirs opendir DIR, $dir or die "Unable to open $dir: $!"; while ( my $f = readdir DIR ) { $dir_size += -s "$upload_dir/$f"; } return $dir_size; } sub error { my( $q, $reason ) = @_; print $q->header( "text/html" ), $q->start_html( "Error" ), $q->h1( "Error" ), $q->p( "Your upload was not procesed because the following error ", "occured: " ), $q->p( $q->i( $reason ) ), $q->end_html; exit; }