Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

need to pass on a file from a form to cgi script to perl program

Status
Not open for further replies.

kavi98

Programmer
Dec 14, 2000
48
0
0
US
the html form is to take the file name upload it to the cgi script and then the file is to be passed on to a perl program to be used in execution there.

the form
<!Form to upload a text file to generate a script .>
<HTML>
<HEAD>
<TITLE>Uploading File</TITLE>
</HEAD>
<BODY>
<FONT size=6 type=&quot;ariel&quot; color = #0000FF align =&quot;center&quot;>Please click browse to Upload the File</FONT>
<TABLE width=&quot;510&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; bgcolor=&quot;#FFFFFF&quot;>
<tr><td align=&quot;left&quot; valign=&quot;top&quot; height=&quot;20&quot;>
<FORM METHOD = POST ACTION =&quot; ENCTYPE=&quot;multipart/form-data&quot;>


Local File: <INPUT TYPE =&quot;file&quot; value= &quot;UPLOAD&quot; ACCEPT=&quot;text/plain,image/gif&quot;>
</td></tr><br>

<tr><td align=&quot;left&quot; valign=&quot;top&quot; height=&quot;20&quot;><br>
&amp;#032;&amp;#032;<INPUT TYPE = &quot;submit&quot; value =&quot;Transfer File&quot;>
<INPUT TYPE = &quot;reset&quot; value= &quot;Reset &quot;>
</td></tr>
</FORM>
</TABLE>
</BODY></HTML>

the cgi script which i am still trying to understand and write.So it still has a lot of loose ends.

#!/usr/local/bin/perl

print &quot;Content-type:text/html\n\n&quot;;

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&amp;/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$FORM{$name} = $value;
}
print &quot;$value \n&quot;;
print &quot;<html><head><title>Form Output</title></head><body>&quot;;
print &quot;<h2>Results from FORM post</h2>\n&quot;;

foreach $key (keys(%FORM)) {
print &quot;$key = $FORM{$key}<br>&quot;;
}

print &quot;</body></html>&quot;;

~
from this script i want to pass the file to the perl program and use the data in the text file passed

thanks for the help
 
Check out faq219-352.

BTW, why are you using two seperate perl programs on the back end? Just use one! Or, from one, you can &quot;do&quot; another one.

Tom
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
Sorry, I don't have time to closely scrutinize your code. However, I did answer a similar question in thread219-28183


That post contains code that produces the HTML upload page and the cgi to catch and save the uploaded file.

'hope that helps....




keep the rudder amid ship and beware the odd typo
 

#!/usr/local/bin/perl
use CGI;

print &quot;Content-type:text/html\n&quot;;

# get the file from the input stream
$upload = $in{&quot;UPLOAD&quot;};

# check if it's there, and write it to disk
if ($upload)
# if it's plain text
{
open (TEXT, &quot;>filename.txt&quot;) || die &quot;$!&quot;;
unless (flock (TEXT, LOCK_EX)) {die &quot;$!&quot;}
print TEXT $upload;
close(TEXT);
}

I have changed and double checked my syntax but i keep getting a syntax error.
 
You need two newlines after your content type:

print &quot;Content-type: text/html\n\n;&quot;

You need a semicolon in your &quot;unless&quot;:

unless (flock (TEXT, LOCK_EX)) {die &quot;$!&quot;;}

You need to &quot;use&quot; the Fcntl module to define your file-locking constants, otherwise it doesn't understand LOCK_EX:

use Fcntl ':flock';

I think that should do it.
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
#!/opt/ZDperl/bin/perl

use CGI;
use Fcntl ':flock';

$mycgi = new CGI;
print $mycgi->header;

# get the file from the input stream
$upload = $in{&quot;UPLOAD&quot;};

# check if it's there, and write it to disk
if ($upload)
# if it's plain text
{
open (TEXT, &quot;>filename.txt&quot;) || die &quot;$!&quot;;
unless (flock (TEXT, LOCK_EX)) {die &quot;$!&quot;;}
print TEXT $upload;
close(TEXT);
}
print &quot;<html><head><title>Form Output</title></head><body>&quot;;
print &quot;<h2>Results from FORM post</h2>\n&quot;;

foreach $x (TEXT) {
print &quot;$x\n&quot;;
}

print &quot;</body></html>&quot;;
~

this works but i don't get the content of filename.txt ,but it just writes TEXT as the output.
Please if you can tell me why it does that.

Thanks again for all the help.
 
TEXT is a filehandle, not the contents of the file. In your foreach loop, it is seen as a list of characters, so it prints &quot;TEXT&quot;. If you wanted to get the contents of the file, you'd have to open it read/write and then set @TEXT=<TEXT> and print @TEXT through your foreach loop. But, in your case, you already have the contents of the file in the form of $upload, so just print that:

print qq~
<html><head><title>Form Output</title></head>
<body>
<h2>Results from FORM post:</h2><br>
$upload
</body></html>
~;

BTW, I'm surprised your use of CGI.pm works the way you used it. I would think that %in wouldn't be defined, but I guess it automatically creates the %in array when you instantiate a &quot;new CGI&quot;.
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
#!/opt/ZDperl/bin/perl

use CGI;
use Fcntl qw:)flock);

$mycgi = new CGI;
print $mycgi->header;

# get the file from the input stream
$upload =$in{&quot;UPLOAD&quot;};

# check if it's there, and write it to disk
if ($upload)
# if it's plain text
{
open (TEXT, &quot;>filename.txt&quot;) || die &quot;$!&quot;;
unless (flock (TEXT, LOCK_EX)) {die &quot;$!&quot;;}
print TEXT $upload ;
close(TEXT);
}
print qq~
<html><head><title>Form Output</title></head>
<body>
<h2>Results from FORM post:</h2><br>
$upload
</body></html>
~;
~

when ever i check for syntax i get this error ,and I don't seem to manage to print the contents of the file.



Name &quot;main::in&quot; used only once: possible typo at cgiScript.pl line 10.

Please help.
thanks
 
CGI.pm does not create %in, as far as I know. I think Tom answered your question before you posted it. If you want to retrieve a parameter from the parsed input from the HTML form, use the param method.

Code:
#!/opt/ZDperl/bin/perl

$mycgi = new CGI;
print $mycgi->header;

# get the file from the input stream
$upload = $mycgi->param(&quot;UPLOAD&quot;);
translated into english - set $upload to the result or applying the 'param'
method to the CGI object ($mycgi) with the argument &quot;UPLOAD&quot;.
or - $upload is set to CGIOBJECT->apply method param for (upload)


There is nothing broken with the way you wrote it, except the hash '%in' does not exist. It would compile fine, just would not get a value for $upload. Therefore, when you try to get an upload file name, you get null back. The syntax check was intelligent enough to notice that you used a variable only once. If you only use it once, then it can't be doing anything.

Once you get to where you can get some of this stuff running, I would suggest using the -w switch or 'use Strict;'. These are two automatic complainers that tell you when you code is doing something that does not make sense. I do not always use 'use Strict' because it is so strict, but I nearly always use the '-w'.

#!/opt/ZDperl/bin/perl -w

'hope this helps.




keep the rudder amid ship and beware the odd typo
 
thanks for all the help given by all of you
I still am stuck with no luck in dgetting the solution ,please help

i try to upload a file selected from my desktop,which is a basic html form with a post method

<!Form to upload a text file to generate a script .>
<HTML>
<HEAD>
<TITLE>Uploading File</TITLE>
</HEAD>
<BODY>
<FONT size=6 type=&quot;ariel&quot; color = #0000FF align =&quot;center&quot;>Please click browse to Upload the File</FONT>
<TABLE width=&quot;510&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; bgcolor=&quot;#FFFFFF&quot;>
<tr><td align=&quot;left&quot; valign=&quot;top&quot; height=&quot;20&quot;>
<FORM ENCTYPE=&quot;multipart/form-data&quot; ACTION =&quot; METHOD = &quot;POST&quot; >


Local File: <INPUT TYPE =&quot;FILE&quot; value= &quot;UPLOAD&quot; >
</td></tr><br>

<tr><td align=&quot;left&quot; valign=&quot;top&quot; height=&quot;20&quot;><br>
&amp;#032;&amp;#032;<INPUT TYPE = &quot;submit&quot; value =&quot;Transfer File&quot;>
<INPUT TYPE = &quot;reset&quot; value= &quot;Reset &quot;>
</td></tr>
</FORM>
</TABLE>
</BODY></HTML>

then i use this cgi Script to get the uploaded file and write out the contents of the file uploaded

#!/opt/ZDperl/bin/perl -w

use CGI::Debug;
use Fcntl qw:)DEFAULT :flock);

$mycgi = new CGI(\*STDIN);
print $mycgi->header;

# get the file from the input stream
$upload =$mycgi->param(&quot;UPLOAD&quot;);

# check if it's there, and write it to disk
if ($upload)
# if it's plain text
{
open (TEXT, &quot;>filename.txt&quot;) || die &quot;$!&quot;;
unless (flock (TEXT, LOCK_EX)) {die &quot;$!&quot;;}
print TEXT $upload ;
close(TEXT);
}
print&quot;<html><head><title>Form Output</title></head>&quot;;
print&quot;<body>&quot;;
print&quot;<h2>Results from FORM post:</h2><br>&quot;;
print &quot;$upload\n&quot;;
print&quot;</body></html>&quot;;

it does not create any file with the name filename.txt,nor it writes any contents in it ,i don't even think the contents of the file get uploaded.
 
OK, I'm kind-of pressed for time. So, I have broken an example into two files, an HTML input page and a CGI upload program. I usually do it all with one piece of CGI, but, maybe this is a little easier to understand.

here is some code for an HTML input page. You need to change the form action to point at your cgi on your server.

<HTML>
<HEAD>
<TITLE>UPLOAD THIS</TITLE>
</HEAD>
<BODY>
<FORM METHOD=&quot;POST&quot; ACTION=&quot; ENCTYPE=&quot;multipart/form-data&quot;>
Enter or Browse to the file you would like to upload.<BR>
<INPUT TYPE=&quot;file&quot; NAME=&quot;fileID&quot; VALUE=&quot;&quot; SIZE=50 MAXLENGTH=80><BR>
<INPUT TYPE=&quot;submit&quot; NAME=&quot;doWhat&quot; VALUE=&quot;uploadMe&quot;>
</FORM>
</BODY>
</HTML>


and here is some code that catches the file, prints it to disk and prints it to the browser screen. You need to give it a real path to put the new file in.

#!/opt/ZDperl/bin/perl -w
use CGI;

$query = new CGI;
$thisCGI = $query->url();
print $query->header,$query->start_html(-title=>&quot;UPLOAD THIS&quot;);

$fileID = $query->param('fileID');
@pathName = split(/\\/,$fileID);

if ($fileID)
{
$newFile = '/path/to/where/you/want/to/put/newFile/';
$newFile .= pop(@pathName);

open(OPF,&quot;>$newFile&quot;) || &amp;showError(&quot;Failed to open OPF, $!&quot;);
while ($bytesread=read($fileID,$buffer,1024)) { print OPF &quot;$buffer&quot;; }
close OPF;

# if you try to upload anything other than text or html, this kills the upload
# and deletes the uploaded file.
$type = $query->uploadInfo($fileID)->{'Content-Type'};
unless ($type =~ /text\/html/i)
{
unlink $newFile;
&amp;showError(&quot;Dangerous file type.<BR>Deleted file.&quot;);
}

print &quot;<BR>Upload of $newFile of type $type Successful<BR>\n&quot;;
open(IPF,&quot;<$newFile&quot;) or &amp;showError(&quot;Failed to open uploaded file.&quot;);
while (<IPF>) { print &quot;$_&quot;; }
close IPF;
}

sub showError
{
my @error = @_;
print &quot;<CENTER><font color=\&quot;\#ff4500\&quot;>Fatal ERROR - @error</font><BR>\n&quot;;
print &quot;Submission aborted - your data was not saved!!<BR>\n&quot;;
print &quot;Please use the BACK button to return to the previous page<BR>\n&quot;;
print &quot;and correct the error.<BR></CENTER>\n&quot;;
print $query->end_form,$query->end_html;
exit;
}


This stuff works. I just ran it. You will need to put your flocking back in when you get it running.

'hope this helps.... gotta' run.




keep the rudder amid ship and beware the odd typo
 
When i try to run the exact same code on my server(unix)i get this error,Is something wrong with the server.

the error i get is
Name &quot;main::thisCGI&quot; used only once: possible typo at load.pl line 6.
Name &quot;main::bytesread&quot; used only once: possible typo at load.pl line 18.
load.pl syntax OK

so when i do run it on the browser i get am internal server error.

Thanks for helping me out.I really appreciate it.
 
Try this (with your HTML code as is):

#!/opt/ZDperl/bin/perl -w -T

# Restrict unsafe constructs
use strict;

# CGI routines (I prefer CGI_Lite over CGI)
use CGI_Lite;
my $cgi = new CGI_Lite;
my %in = $cgi->parse_form_data;

# get the file from the input stream
my $upload = $in{&quot;UPLOAD&quot;};

# path and filename
my $filename = &quot;/path/to/your/file.txt&quot;;

# print your html header
print &quot;Content-type: text/html\n\n&quot;;

# check if it's there, and write it to disk
if ($upload)
{
open (TEXT, &quot;>$filename&quot;) || CgiDie(&quot;Cannot open $filename for writing: $!&quot;);
unless (flock (TEXT, LOCK_EX)) {CgiDie(&quot;Cannot lock $filename: $!&quot;);}
print TEXT $upload;
close(TEXT);
}
else {CgiDie(&quot;Error: file did not upload.&quot;);}

# print the page
print qq~
<html><head><title>Form Output</title></head>
<body>
<h2>Results from FORM post:</h2><br>
$upload
</body></html>
~;

sub CgiDie
{
my ($message) = @_;
print $message;
die $message;
}

This is more in spirit with the code you were originally using (rather than going into that CGI.pm OO confusion), but fully fleshed out and with more error checking.

Make sure you have read/write permissions on the directory you plan to write your file to. CHMOD 777. Obviously, for security reasons, you wouldn't want that directory in your web tree.
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
when i run the script ,gives a internal server error and says that LOCK_EX can't be used with Strict.

Thanks for going out of your way to solve this one ,as i have been stuck with this internal server error for days.

Does it make a difference if the file has a .pl extension or a cgi extencion.

 
I did that but it still gives me a server error when i try to execute the script from the form.

Thanks
 
Do you have the CGI_Lite module installed on your system? If not, get it from CPAN, or you can use cgi-lib.pl with the same code above.

Did you run it from the command line?

I didn't put &quot;use Fcntl ':flock';&quot; in that code above... did you include that?

C'mon, do some debugging. I didn't try to run that code, so there may be syntax errors. That is something you should be able to figure out on your own. Is there any part of that code that you do not understand?
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
Please can you explain this error ,i don't understand <> chunk 2

Use of uninitialized value at (eval 1) line 21, <> chunk 2.
Content-type: text/html

Error: file did not upload. at ./load1.cgi line 39, <> chunk 2.
Error: file did not upload.
 
#!/opt/ZDperl/bin/perl -w
# CGI routines
use CGI_Lite;
use Fcntl ':flock';
my $cgi = new CGI_Lite;
my %in = $cgi->parse_form_data;

# get the file from the input stream
my $upload = $in{&quot;UPLOAD&quot;};
my $filename = &quot;&quot;;

# print your html header
print &quot;Content-type: text/html\n\n&quot;;

# check if it's there, and write it to disk
if ($upload)
{
open (TEXT, &quot;>$filename&quot;) || CgiDie(&quot;Cannot open $filename for writing: $!&quot;);
unless (flock (TEXT, LOCK_EX)) {CgiDie(&quot;Cannot lock $filename: $!&quot;);}
print TEXT $upload;
close(TEXT);
}
else {CgiDie(&quot;Error: file did not upload.&quot;);}

# print the page
print qq~
<html><head><title>Form Output</title></head>
<body>
<h2>Results from FORM post:</h2><br>
$upload
</body></html>

~;

sub CgiDie
{
my ($message) = @_;
print $message;
die (&quot;$message&quot;);
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top