The upload() function's return is meant to be used as a filehandle (a re-writing of your code):
#!/usr/bin/perl -w
use strict;
use CGI qw(:standard);
# (update: in your code you didn't import anything?!
# I guess that you didn't show us the real code then...
# (copy-and-paste if your friend.) (I'm referring
# to the 'use CGI' line, of course.))
my $fh = upload('file');
open TEMP, ">temp.jpg" or die "error opening temp.jpg for writing: $!\
+n";
binmode TEMP; # very important on Windows-based machines
{
# this block is so the assignment to $/
# will not effect the rest of the script
local $/ = \1024; # tell <...> to read in 1024-byte chunks.
print TEMP $_ while <$fh>;
}
close TEMP or warn "error closing temp.jpg: $!\n";
(The use of strict and warnings is strongly reccommended.)
| [reply] [d/l] [select] |
indeed that's not the original code, that was the code I simplified it down to thinking I had made some stupid mistake. your additions seemed to do the trick. thanks!
-Eric
| [reply] |
++wog for getting you on the right track and ++tilly for explaining where and why the problem was arising.
I just thought that I would add this as an extra.
To help show what you can do with the "local" filename and why you might want it. Also, if you are using CGI.pm, you might aswell use it.
#!/usr/bin/perl
use CGI;
$co = new CGI;
if (!$co->param()) {
print $co->header,
$co->start_html('upload a file'),
"<table border=1><tr><td>",
$co->center('upload a file'),
$co->start_multipart_form,
$co->filefield(-name=>'file1', -size=>30),
$co->br,
$co->submit(-value=>'Upload'),
$co->end_form,
"</td></tr></table>";
} else {
$file = $co->param('file1');
print $co->header,
$co->start_html('file uploaded'),
"Uploading $file ...<br>";
@filename = split(/\\/, $file);
open (FILE, ">safe/$filename[$#filename]"),
print "... $filename[$#filename] uploaded.";
print FILE <$file>;
close FILE;
}
print $co->end_html;
This is working, but of course, this script is JUST AN EXAMPLE, and you should not trust input forms. Use -T and check the file path for bad chars. Basic error checking, referrer checking, etc.
"Better secure than sorry." -xtype | [reply] [d/l] |
You have already been told how to get the result you want,
but not why it was done this way.
The thought was that the browser sends the actual filename
of what is sent, and that information can be useful, so it
should not be lost. However that name can have any garbage,
and so should not be trusted. Furthermore the name of the
temporary file that has the data should be irrelevant to
you, you just want to get the data and do something with
it.
Therefore the API was chosen so that you can get all of
the information that is relevant to you and the temporary
file is managed without any work on your part. (I also
think that it tends to confuse people to have this magical
thing which can be used as a string or a filehandle both,
but that is how it was done.) | [reply] |
The behavior of sending the entire filepath to the server is peculiar to Internet Explorer. So you should filter the filename with a regex to have a valid filename. Something like the following could do:
my ($new_file_name) = $full_path_name =~ m!(?:.*\\|.*\/)?(.+)$!;
Update: well, it seems your problem was of another nature and already been solved: it's a bad habit to post before reading the full thread... sorry
$|=$_='1g2i1u1l2i4e2n0k',map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g | [reply] [d/l] |
Or you could use File::Basename which I believe is standard
with the Perl distributions.
use File::Basename;
my $new_file_name = basename($full_path_name, 'jpg|JPG');
# or
$new_file_name = basename($full_path_name, '\..*');
# but this will return "James" from
# "James.John.jpg"
or you could use split, or many other options. :)
jarich | [reply] [d/l] |
Using File::Basename isn't that easy indeed, cause you got to suggest him the operating system of the client. You can do it by checking CGI server variables but i prefer the regex way, it's more straight forward IMHO.
Maybe split solution could be more readable, even if less efficient:
my $new_file_name = pop @{[split /\/|\\/, $full_path_name]};
$|=$_='1g2i1u1l2i4e2n0k',map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g | [reply] [d/l] |