Solved

0 byte file created on file upload

Posted on 2003-11-25
28
912 Views
Last Modified: 2008-01-09
Hi,

I am currently trying to get a file to upload with the following code.....it appears to work succesfully,  and it creates a file in the appropriate directory, but when I look at the file it has 0 bytes in it.

After I get this working I will need to check for file size / type...but first things first...

As far as I know all permissions on the directory where the file is going is OK.... (chmod 766 or whatever?)

Any ideas on what I am doing wrong or missing?

Mike
Going crazy in Prince Edward Island Canada!

******************************************************************************

<form ACTION="//localhost/upload.pl" METHOD="get" ENCTYPE="multipart/form-data" NAME="upload_form">      
  <input TYPE="text" NAME="bio_name">
  <input TYPE="text" NAME="prod_name">
  <input TYPE="file" NAME="bio_image_name"><input TYPE="submit" VALUE="Upload Now"></td>
  <input TYPE="file" NAME="prod_image_name"><input TYPE="submit" VALUE="Upload Now"></td>
</form>

******************************************************************************

file name is upload.pl

#!/usr/bin/perl -w

use CGI;

use Data::Dumper;

my $q = new CGI();

##  Read the file name that the user has entered
my $bio_DocLocation = $q->param('bio_image_name');
my $bio_name = $q->param('bio_name');

#print "<pre>debug:" . Dumper($q) . "</pre>";


open(OUTFILE,"> ".$bio_name) || die("cannt copy image over ! ... ".$!);
binmode OUTFILE;

##  Read 1024 bytes at a time
my ($size, $bytesread, $data);
while($bytesread=read($bio_DocLocation,$data,1024)){
        $size+=$bytesread;              ##  Extra!! also count the size of the file
        print OUTFILE $data;         ##  Store the ACTUAL file content
}
close $bio_DocLocation;
close OUTFILE;
0
Comment
Question by:mike_allain
  • 15
  • 9
  • 4
28 Comments
 
LVL 20

Expert Comment

by:jmcg
ID: 9821847
Try using the $query->upload('bio_image_name') approach instead. This will more reliably return a filehandle, at least according to the embedded documentation.
0
 

Author Comment

by:mike_allain
ID: 9822335
Thanks jmeg...I tried usine the $query->upload('bio_image_name')  but still no success...(However that is not to say that I am approaching it correctly)

I am not sure if this is important but I ran a  print "<pre>debug:" . Dumper($!) . "</pre>" immeadiately after I attempt to open the file and I get the following error ...

debug:$VAR1 = 'Inappropriate ioctl for device';

I also ran the file through the perl debugger and manually assigned the values for $bio_doclocation and $bio_name...... and I get the error....

read() on unopened filehandle at upload.pl line 19.

I then check the directory where I want the file to go and it once again contains a 0 byte file......

Mike
0
 
LVL 20

Expert Comment

by:jmcg
ID: 9822478
The CGI module is doing things in a slightly tricky fashion with these upload file params; I remember marveling at the source code in CGI.pm.

The last time someone had a problem like this, it ended up being caused by some weird system administration procedures relating to quotas. Have you successfully written files (of non-zero size) in the directory in question? Can you check to see if you are perhaps attempting to exceed some quota?

Since you are saying 'binmode', I have to suspect you are running this script on a Windows system. I'm not much of a wiz on Windows but we have several other experts around here who are. What you're doing in terms of Perl looks correct; I can't think of a reason in Perl why you should not be able to write to a file you successfully created.
0
 
LVL 20

Expert Comment

by:jmcg
ID: 9822483
By the way, have you looked at the value in your $size variable after end of the loop? Does Perl think it wrote anything?
0
 

Author Comment

by:mike_allain
ID: 9824482
I have since added the line use strict; to my code which at least stops the program from running any further than the error....

I checked in the apache server log file and it gives this error...
Can't use an undefined value as a symbol reference at upload.pl line 23.

the program doesn't reach the $size variable....

I am currently running this in a testing evironment that I have set up...

Redhat linux 9
perl 5.0.8
apache 1.28 (Documentation says 1.3)

jmeg, I added binmode only becouse it was include in a code segment I tried from here (I was not exactly sure what it did)...but I have since looked into it further and found this... "In other words: regardless of platform, use binmode() on binary files (like for example images)." at this  address  http://www.perldoc.com/perl5.8.0/pod/func/binmode.html

>>The last time someone had a problem like this, it ended up being caused by some weird system >>administration procedures relating to quotas. Have you successfully written files (of non-zero size) in >>the directory in question? Can you check to see if you are perhaps attempting to exceed some quota?

I have not writen files to this directory in the past...(This is my first attempt at uploading / writing files using  perl ), ..as for quota's or permission issues...I have no idea where to even begin!!!

Mike




0
 

Author Comment

by:mike_allain
ID: 9824499
Correction to above post....it should read

perl 5.8.0
0
 

Author Comment

by:mike_allain
ID: 9824574
Another correction Apache version 1.3.28

I also upped the points on this

Thanks

Mike
0
 

Author Comment

by:mike_allain
ID: 9825383
Hi,

I have since made some changes  ie ..$query->upload....and the inclusion of the use strict; statement...

The following code will fail evrerytime on line 8.  with :
Inappropriate ioctl for device at upload.pl line 10

#!/usr/bin/perl -w

1   - use strict;
2   - use CGI;

3   - use Data::Dumper;
4   -  my $query = new CGI();
5   -  
6   - print "<pre>debug:" . Dumper($query) . "</pre>";
7   -
8   - my $fh = $query->upload('bio_image_name') || die "Content-type: text/html\n\n no fh $!";
9   -
10 - print "<pre>debug:" . Dumper($fh) . "</pre>";

However the output from line 6 is:

debug:$VAR1 = bless( {
                 '.parameters' => [
                                    'bio_name',
                                    'prod_name',
                                    'bio_image_name',
                                    'prod_image_name'
                                  ],
                 'prod_name' => [
                                  ''
                                ],
                 'bio_name' => [
                                 'Bulb'
                               ],
                 'bio_image_name' => [
                                       'Bulb.gif'
                                     ],
                 '.r' => bless( do{\(my $o = 155405596)}, 'Apache' ),
                 '.charset' => 'ISO-8859-1',
                 'prod_image_name' => [
                                        ''
                                      ],
                 '.fieldnames' => {},
                 'escape' => 1
               }, 'CGI' );

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9829068
Could you try printing this before doing new CGI():
     print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;
Does that print a valid path, where you (well, the webserver account) can write to?

Try setting it to a path where you know you can write before calling new CGI().

0
 

Author Comment

by:mike_allain
ID: 9829304
I ran thestatement:

print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;     and got the following:

Tempdir for cgi = HTTP/1.1 500 Internal Server Error
Date: Thu, 27 Nov 2003 03:08:32 GMT
Server: Apache/1.3.28 (Unix) mod_perl/1.28
Set-Cookie: session=1; path=/; expires=Fri, 26-Nov-2004 03:08:33 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

257
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>500 Internal Server Error</TITLE>
</HEAD><BODY>
<H1>Internal Server Error</H1>
The server encountered an internal error or
misconfiguration and was unable to complete
your request.<P>
Please contact the server administrator,
and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.<P>
More information about this error may be available
in the server error log.<P>
<HR>
<ADDRESS>Apache/1.3.28 Server at localhost Port 80</ADDRESS>
</BODY></HTML>

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9830558
Ah, I was hoping you would have shell access...
Ok, try it again and print a header first:

print "Content-type: text/plain\n\n";
print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;

On my system it prints:
Tempdir for cgi = /var/tmp

0
 

Author Comment

by:mike_allain
ID: 9831503
Hi kandura,

I ran the the following:

#!/usr/bin/perl -w
print "Content-type: text/plain\n\n";
print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;

and it returned:

Content-type: text/plain

Tempdir for cgi =

It would appear that my apache setup has no temp directory configured....

Any idea where / what I should do from here?

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9831824
No, I'm sorry, please try this complete script; that $TempFile::TMPDIRECTORY is defined by CGI.pm:

#!/usr/bin/perl -w
use CGI;
print "Content-type: text/plain\n\n";
print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;


If that doesn't print anything useful either, then you should set it to something useful, like the directory where you tried to write your images in the first place.


I just noticed that you did this in your original script:
   my $bio_name = $q->param('bio_name');
   open(OUTFILE,"> ".$bio_name) ....
That's very dangerous. You should never let the outside world specify the path of a file you're writing to. It could be used to overwrite system files, put viruses etc. on your machine.
Make your own path here, and make your own filename. *You* should be in control of what gets written where, not some anonymous surfer.

0
 

Author Comment

by:mike_allain
ID: 9831945
Thanks for the tip kandura, I will certainly rewrite the script to ensure I do the file naming, etc....

as for the output from the print statements....I did try it with the   use CGI;     and got the same results.....nothing...

You mention something about setting the temp directory to something useful (ie. directory where I was uploading the files in the first place.)  Not to sound like a complete fool...but how would I do that,  I am quite new to open source languages , etc, and need a little guidance.  Once nudged in the right direction I think I may be able to figure it out.  (I'm sure i'll be back however)

Mike
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 18

Expert Comment

by:kandura
ID: 9832088
Well, I'd start with
/tmp
as a first candidate.

Other possibilities are:
/var/tmp
/usr/tmp
/opt/tmp

Do you know the complete path to where your scripts are on the machine?
Is it something like /home/username/cgi-bin ?
Then try that path as another attempt.

You would set any of these by doing this:
use CGI;
$TempFile::TMPDIRECTORY = '/tmp';

I can't tell you exactly which ones of these suggestions will work, since that depends on the setup of your machine (which differs from mine given that CGI.pm can't figure out a temporary directory).
0
 
LVL 20

Expert Comment

by:jmcg
ID: 9832207
It's not my desire to ignore you, Mike, but the Thanksgiving Holiday here has pulled me away from being online. You're in good hands with Kandura, I think, and I'll be back if he doesn't fix you up.
0
 

Author Comment

by:mike_allain
ID: 9832752
kandura,  I want you to know I really appreciate the help...this issue has been causing me grief for a couple of days now.....

Also wanted to say thanks for not flaming me on the previous question....I can't believe it was that simple.

That being siad....i checked for and found a /var/tmp/ directory so I set the directory to that.....

I then re ran the print statement....and everything ...ok.. I then tried to create the file handle again and it dies there with a 500 internal server error.  I checked the apache error log and it indicates that it died on the my $fh = $query->upload line....

Here is what I ran:

#!/usr/bin/perl -w
use CGI;

$TempFile::TMPDIRECTORY = '/var/tmp/';
print "Content-type: text/plain\n\n";
print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;
my $query = new CGI;
my $fh = $query->upload('bio_image_name') || die $!;

I am not sure if this will help but what I am doing is running Slashcode on a virtual host....
but it seems to be running fine....what I am trying to do is add additional functionallity to the site (i.e upload a image file for an individual's  bio).   Also even though it is set up as a virtual host...it is the only site on the server....(hope this make sence :) )

jmeg, thanks,  I'm sure there will be another time when you are not busy that I will need your help :)

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9832884
Hi Mike,

I'm glad to help you :-)

Until we get this running, it may be helpful to put
    use CGI::Carp qw(fatalsToBrowser);
at the top of your script, to show you the errors in your browser.

Did you get the same error message? Have you tried the other paths I suggested? Do you know why you're not allowed to write to /var/tmp? Is it mounted read-only by any chance?
How is the directory structure for your virtual host layed out? And what about users: do you know under which account your site is running?



0
 

Author Comment

by:mike_allain
ID: 9833231
You Asked:
>>Did you get the same error message?
Answer:  Yes.  Regardless of wether or not the line: $TempFile::TMPDIRECTORY = '/var/tmp/'; I get the same message.  The error message is: Inappropriate ioctl for device at /usr/local/slash/site/talkenergy/htdocs/upload.pl line 11.  The Code on line 11 is: my $fh = $query->upload('bio_image_name') || die $!;

>> Have you tried the other paths I suggested?
answer:  Yes:  No Luck.  On my system I have a folder called /var/tmp/,  a /usr/tmp which is a link to /var/tmp.  The folder /opt/tmp/ does not exist on my system.

>>Do you know why you're not allowed to write to /var/tmp?
answer:  No, as far as I know I am able to.  The permissions on the /var/tmp/ folder are read/write/execute and sticky (chmod 1777)  Not sure what sticky is!

>>How is the directory structure for your virtual host layed out?
Answer:  DocumentRoot = /usr/local/slash/site/talkenergy/htdocs
/usr/local/slash/site/talkenergy/backups
/usr/local/slash/site/talkenergy/logs
/usr/local/slash/site/talkenergy/misc
/usr/local/slash/site/talkenergy/sbin
/usr/local/slash/site/talkenergy/task

>>do you know under which account your site is running?
answer:  As far as I know it is user Nobody who is a member of a group called nobody.  This was set up when I was installing slash.

You asked about the location of my cgi-bin folder:  It is located under /usr/local/apache/cgi-bin/  however the slash website root directory is set up to run scripts as I can place scripts in the /usr/local/slash/sites/talkenergy/htdocs/ folder and run them......

I'm curious....does the line my $fh=$query->upload('bio_image_name') || die $!;  actually attempt to write or use the temp folder at this point?  What exactly is this line doing?  

Mike





0
 
LVL 18

Expert Comment

by:kandura
ID: 9833442
Ì'll answer your last question first: when a file is uploaded to your server, CGI.pm puts it in a temporary file, and gives you the filehandle through $query->upload.
As it turned out, the CGI module had no idea what the path to the temp dir was, so I thought we'd supply it ourselves. Unfortunately that doesn't seem to work on your system, and at the moment I don't have a clue why that would be. It sure seems the permissions on /var/tmp are sufficient.

Is there enough free disk space on the partition where /var/tmp lives?
Could you try it with /usr/local/slash/site/talkenergy/misc as the temp path?
Do you by any chance have telnet or ssh access to this machine?
0
 

Author Comment

by:mike_allain
ID: 9834239
kandura,

I am only using 26% of the space allocated for the partition that the /var/tmp directory is located on...,

I tried $TempFile::TMPDIRECTORY = ' /usr/local/slash/site/talkenergy/misc'; then creating the file handle...no luck...

I have since installed telnet....but I have no idea how to use this....

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9837120
I was wondering if you could run the following snippet from the command line on that machine, to see what it does when running under your user account:

#!/usr/bin/perl -w
use CGI;

$TempFile::TMPDIRECTORY = '/var/tmp/';
print "Content-type: text/plain\n\n";
print "Tempdir for cgi = ", $TempFile::TMPDIRECTORY;
my $query = new CGI;
my $fh = $query->upload('bio_image_name') or die $!;


I'm a bit confused about your remark regarding telnet: I was under the impression that this was a remote machine and that you didn't have shell access to it; yet you were able to install telnet, and the whole slash code. Is it on your desk then? Do you sit at the console? Because that would make it easier to debug things :-)

0
 

Author Comment

by:mike_allain
ID: 9837475
Hi kandura,

I am sorry for the confusion about my machine....I thought I had mentioned earlier that it was a machine I built for testing....

The machine is a laptop sitting on my desk running Linux 9, Apache 1.3.28, and  perl 5.8.0,  I am also running mod_perl and mySQL on the unit as well.

I tried running that snippit of code and it dies on line 8 with the following:

Content-type: text/plain

Tempdir for cgi = /var/tmp/HTTP/1.1 500 Internal Server Error
Date: Fri, 28 Nov 2003 13:12:20 GMT
Server: Apache/1.3.28 (Unix) mod_perl/1.28
Set-Cookie: session=1; path=/; expires=Sat, 27-Nov-2004 13:12:20 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

123
<h1>Software error:</h1>
<pre> at /usr/local/slash/site/talkenergy/htdocs/upload.pl line 8.</pre>
<p>
For help, please send mail to the webmaster (<a href="mailto:xxxxx@xxxxxxxx">xxxxx@xxxxxxxx</a>), giving this error message
and the time and date of the error.

</p>

0

Jus t to let you know I run this script by pasting it in a upload.pl file and then call that file from my browser / webpage form....I am assuming this is how you want it run.....

I did try creating a new file and running it from terminal with: perl scriptname.pl....this died on line 8 also...but I suspect for different reasons....ie no value passed in from form...

Mike
0
 
LVL 18

Accepted Solution

by:
kandura earned 250 total points
ID: 9837873
I don't know if mod_perl might be of influence here; unfortunately I don't have any experience with it. I did however see a lot of references on the web that it should work as you coded it without modification.
Just to be sure, could you try the script with mod_perl disabled?
Also please try it again with the $TempFile::TMPDIRECTORY set to /usr/local/slash/site/talkenergy/htdocs, since you reported earlier that you did see the empty file there (that's right, isn't it?).

I haven't found any meaningful info on the Inappropriate ioctl error message either, except in the context of low level device communication. I have the feeling that this shouldn't normally occur with writing a file to a hard disk, as it only came up in the context of 'special' files (such as sockets, ttys, pipes etc.).
I'm beginning to think that there is something special about your system setup. It could be some Apache directive, or mod_perl setting that is playing tricks with us, but again, I don't really know a lot about those. I'll try to search some more in the meantime.

We can always make a script that tries to find a place on the filesystem where it _can_ write to, but I'd rather get to the bottom of this. It seems weird enough that CGI.pm didn't originally have a tmp path set in the first place...

Sorry, still no answer yet; but we'll keep trying :-)
0
 

Author Comment

by:mike_allain
ID: 9838797
I tried disabling mod_perl (or at least I think this line did it) by replacing PerlHandler Apache::Registry with PerlHandler Apache::PerlRun,  this was the only reference I could find on disabling mod_perl....but it did not make a difference......

I tried the script again with the dierectory you specified...along with the /htdocs/images/tmp directory as well....both do not work.

Each time the server is re-booted there is "no" default tmp path environmental variable set.......
How does one go about setting a default tmp evironmental variable.......( other than when the upload.pl script runs.....)


Mike
0
 

Author Comment

by:mike_allain
ID: 9839472
kandura,
A little bit of good new....

All the slash site configuration options for the apache server are accessed by  a Include line in the httpd.conf  file.  I remmed that line out...restarted the server...and it was like I was back to fresh install of apache....

I then created a new test.cgi file and placed it in the cgi-bin for apache and I created a new html page with a form on it.....

I then tried the line $TempFile::TMPDIRECTORY; in the new test.cgi script and it returned the same thing as earlier....nothing....however I tried to open a filehandle and it worked....I then proceeded to upload a file to the /var/tmp/ directory succesfully.....Yaaa!

Now I would assume that I need to figure out when the slash virtual server is running....why it will not let me upload a file....but at least now I have a starting point......

Any idea's what I would be looking for in the slash Include file ????

Mike
0
 

Author Comment

by:mike_allain
ID: 9847072
Hi kandura,

I finnally nailed a solution!

I located and emailed a Slash guru and found out that Slash + CGI.pm are a no no and very bad things happen when you try to use them together :)

He then proceeded to give me a example of some code that would alow me to upload...and low and behold it worked....

However I really do appreciate the effort you made in attempting a solution to my issue and therefore I am still awarding points to you for your efforts...as well I learned much from our attempts at a solution.

Thanks Once again

Mike
0
 
LVL 18

Expert Comment

by:kandura
ID: 9850536
Hi Mike,

glad you managed to find out what the problem was :-)

As jmcg always says: keep asking interesting questions, and this one certainly was!

Kandura
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now