Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

sub uploadfile { for ($i=1; $i<=5; $i++) { if ($q->param("file$i")) { $filename = $q->param("file$i"); $filename =~ s/.*[\/\\]//; print "$filename"; open (FILE,">$user{'site_id'}/$filename") || &error("Could not + create $filename: $!"); binmode (FILE); print FILE $q->param("file$i"); close (FILE); } } }
Ok when it prints the file it will say C:/windows/pizza/perl/, it wont print out the what the file contains??

Edit kudra, 2002-06-14 Changed title

Replies are listed 'Best First'.
Re: perl trouble
by jarich (Curate) on Jun 14, 2002 at 00:47 UTC
    I think you have misunderstood how CGI works. When you write print FILE $q->param("file$i"); you are asking for the filename, not the contents of the file. It is possible to use the filename as a filehandle, but that would mean you'd do something like:
    my $filename = $q->param("file$i"); while(<$filename>) { print FILE $_; }
    Have a look at CGI's upload function, as it's a better choice than param for getting the filehandle/filename.

    You should also note that the filename that you get depends wholly on the user's filename, so if your code uses that filename exactly then other users can overwrite each others files.

    I think you'll find code that answers your problem here and in many other places in this monastery if you search.

    Hope this helps.

    jarich

Re: CGI File Uploading Modules
by cjf (Parson) on Jun 14, 2002 at 09:09 UTC
Re: perl trouble
by Anonymous Monk on Jun 14, 2002 at 05:21 UTC
    for some reason when, I do this it doesnt print any thing, it just makes the file.
    sub uploadfile { for ($i=1; $i<=5; $i++) { if ($q->param("file$i")) { $filename = $q->param("file$i"); $file = $q->param("file$i"); $filename =~ s/.*[\/\\]//; open (FILE,">$user{'site_id'}/$filename") || &error("Could not + create $filename: $!"); { local $/=""; my $uploaded = <$file>; print FILE $uploaded; } close FILE or die "$!"; } } }
      What does your file field look like in your form? Are you sure that your form has the appropriate type? That is, if you're planning on uploading files then you have to tell your browser to expect to upload a file:
      <form action="upload.cgi" method="POST" enctype="multipart/form-data">
      assuming of course that your script is called upload.cgi.

      Likewise your file field should look something like this:

      <input type="file" name="filename">
      If you don't specify your form type with enctype="multipart/form-data" then you'll get your filename in your parameters but no file.

      On a separate issue, you're running a big risk by not ensuring that the filename you're creating is unique. If you're uploading resumes for example you'll find that many people call their files "resume.doc" and they're all over-write each other. The same can be true of photos and other random files.

      The link I gave before pointed to code that should have helped there, but I'll write it out for you here too.

      sub uploadfile { use strict; # a good thing to do use File::Basename; my ($q, %user) = @_; # look through all five upload options and # save any uploaded files for (my $i=1; $i<=5; $i++) { my $file = $q->upload("file$i"); next unless $file; # find the filename and it's extension my ($filename, $type) = split '\.', basename($fh); # untaint the filename and extension $filename =~ s/[^A-Za-z0-9_-]//g; $type =~ s/[^A-Za-z0-9_-]//g; my $directory = $user{'site_id'}; # make a unique filename my $i = 0; while(-e "$directory/$filename$i.$type") { $i++; } # this won't write over anything else. my $newfilename = "$directory/$filename$i.$type"; # Write contents of uploaded file to $director +y open(FILE, "> $newfilename") or die "$!\n"; { local $/=""; my $uploaded = <$filename>; print FILE $uploaded; } close FILE or die "$!"; } }
      Using upload() is preferrable to using param() because it returns a filehandle which is magical and can act as a string. This means that you can use strict throughout without it complaining about symbolic references.

      Hope this helps.

      jarich