use Fcntl qw( :DEFAULT :flock ); use CGI; use constant BUFFER_SIZE => 16_384; 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; no strict; $CGI::DISABLE_UPLOADS = 0; $CGI::POST_MAX = MAX_FILE_SIZE; our $page = new CGI; print $page->header(); print $page->start_html( -title => $TITLE, -style => { 'src'=> $style }, ); $page->cgi_error and error( $page, "Error transferring file: " . $page->cgi_error ); my $filename = $page->param( "file" ) || error( $page, "No filename entered." ); my $fh = $page->upload('file'); # upload takes the name of "input file upload"-field if (!$fh && $page->cgi_error) { print $page->header(-status=>$page->cgi_error); exit 0; } my $buffer; if ( dir_size( $UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) { error( $page, "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( $page, "Invalid file name; files must start with a letter or number." ); } # Open output file, making sure the name is unique until ( sysopen(OUTPUT, $UPLOAD_DIR . $filename, O_WRONLY | O_EXCL | O_CREAT) ) { $filename =~ s/(\d*)(\.*\w+)$/($1||0) + 1 . $2/e; error( $page, "Unable to save your file." ) if $1 >= MAX_OPEN_TRIES ; } # This is necessary for non-Unix systems; does nothing on Unix binmode $fh; binmode OUTPUT; while ( read( $fh, $buffer, BUFFER_SIZE ) ) { print OUTPUT $buffer; } close OUTPUT; my $sql_insert = "INSERT INTO bonsai_pics (name,bonsai_id,filename,timestamp) VALUES (?,?,?,?)"; $dbh->do($sql_insert,undef, $page->param('name'), $page->param('bonsai_id'), $UPLOAD_DIR . $filename, $date) || error $page,"Could not insert $sql_insert :\n"; print "Added $filename
";