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

Well,
I'm getting nuts. Wrote a upload script that worked on unix and doesn't on NT.

Let's take the example from the Q&A;
#!/usrb/bin/perl use CGI; use CGI::Carp qw/fatalsToBrowser/; $C = new CGI; if ($C->param) { $file=$C->param("FILE1"); $full = "D:/inetpub/general/nt/cv"; open (UPLOAD, ">$full") || die "Can't open"; while ($bytesread=read($file,$buffer,1024)) { binmode UPLOAD; print UPLOAD $buffer; } print $C->header; print $C->start_html; print qq(<p>file uploaded successfully</p>); print $C->end_html; exit; } else { print $C->header; print $C->start_html; print $C->start_multipart_form; print $C->filefield(-name=>'file'); print qq(<input type="submit" name="submit" value="submit"> </form> ); print $C->end_html; exit; }


so you see, I also tried to put a end slash to my path, tried to change the slashes to \\.

The write perms are ok , when I write to a textfile that works.

I don't understand it anymore...

--
My opinions may have changed,
but not the fact that I am right

Replies are listed 'Best First'.
Re: Uploading and NT
by Corion (Patriarch) on Aug 16, 2000 at 15:07 UTC

    You use binmode() on the output file but you forgot to use binmode() on the input file. Or at least it seems to me. Either your code is incomplete or you aren't even opening $file for reading. I hope the code is incomplete, because it couldn't have worked under UNIX in this form either, as read() takes a filehandle as the first parameter and not a filename. Also, it's not necessary to use binmode() on an opened filehandle more than once before closing it.

    Update : In the context of a CGI script, the filename of the uploaded file might or might not contain the full (local) path to the uploaded file. In fact, it might contain the full path to the remote file, like c:\program files\test.txt, which was where the file resided on the user machine. Also, I fixed some type globs (note the asterisk before the file handles)

    Here is some code that should work on any platform, and which should also be reasonably secure against users supplying malicious filenames to trick your http server into doing stuff (I hope) :

    #!/usr/bin/perl -w use strict; use HTML::Entities; local *INFILE; local *OUTFILE; my $uploadedfilename = ""; # fill this in my $fullfilename = "D:/inetpub/general/nt/cv"; # This is the name we echo back to the user : my $htmlfilename = encode_entities($uploadedfilename); die "Upload temp file $htmlfilename not found !\n" unless -x $uploaded +filename; open INFILE, "< $uploadedfilename" or die "Opening the temp file $html +filename : $!\n"; binmode INFILE; open OUTFILE, "> $fullfilename" or die "Can't create $fullfilename : $ +!\n"; binmode OUTFILE; my ($bytesread, $buffer); while ($bytesread=read(INFILE,$buffer,1024)) { print OUTFILE $buffer; } close OUTFILE; close INFILE;

    Update: If you are dealing with CGI.pm, the documentation mentions the following idiom, adapted to our needs, to handle uploaded files :

    $fh = $query->upload('FILE1'); binmode $fh; while ($bytesread=read($fh, $buffer, 1024)) { print OUTFILE $buffer; }
    This is the correct way and should be used. Using a string as a parameter to read() is allowed but deprecated.

      Update: Actually the most varations I tried should have worked. But I found out what the real problem was. In the filename I gave a concatenated the filename with a date/time stamp.Well in unix a : in a filename is no problem, well in NT it is. Problem solved, and concluded the most difficult problems are not the coding, but knowing what the Os specifics are.

      All by all a experience richer!


      Damn,
      I,m guilty of not testing code... This was an example. My code which I tested worked on linux.

      $basedir = "/home/geert/www/cv"; $onnum = 1; while ($onnum != 11) { $file = $req->param("FILE$onnum"); if ($file ne "") { $filename = $file; $filename =~ s!^.*(\\|\/)!!; open (OUTFILE, ">$basedir/$filename"); print "$basedir/$filename<br>"; while (my $bytesread = read($file, my $buffer, 1024)) { print OUTFILE $buffer; } close (OUTFILE); } $onnum++; }

      This worked, but it doesn't work on NT. And I used binmode...

      --
      My opinions may have changed,
      but not the fact that I am right