×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

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

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

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

(OP)
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="ariel" color = #0000FF align ="center">Please click browse to Upload the File</FONT>
<TABLE width="510" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
 <tr><td align="left" valign="top" height="20">
<FORM METHOD = POST ACTION ="http://sandbox.storyserver.zdnet.com/karora/cgi-bin/test.cgi"; ENCTYPE="multipart/form-data">


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

<tr><td align="left" valign="top" height="20"><br>
&#032;&#032;<INPUT TYPE = "submit" value ="Transfer File">
<INPUT TYPE = "reset" value= "Reset ">
</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 "Content-type:text/html\n\n";

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

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

print "</body></html>";

~                            
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

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

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 "do" another one.

Tom


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

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

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

(OP)

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

print "Content-type:text/html\n";

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

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

I have changed and double checked my syntax but i keep getting a syntax error.

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

You need two newlines after your content type:

print "Content-type: text/html\n\n;"

You need a semicolon in your "unless":

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

You need to "use" 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.
http://www.oac-design.com

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

(OP)
#!/opt/ZDperl/bin/perl

use CGI;
use Fcntl ':flock';

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

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

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

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

print "</body></html>";
~                     

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.

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

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 "TEXT".  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 "new CGI".


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
#!/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{"UPLOAD"};

# check if it's there, and write it to disk
if ($upload)
  # if it's plain text
  {
    open (TEXT, ">filename.txt") || die "$!";
    unless (flock (TEXT, LOCK_EX)) {die "$!";}
        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 "main::in" used only once: possible typo at cgiScript.pl line 10.

Please help.
thanks

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

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.


#!/opt/ZDperl/bin/perl

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

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

translated into english - set $upload to the result or applying the 'param'
method to the CGI object ($mycgi) with the argument "UPLOAD".
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

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

(OP)
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="ariel" color = #0000FF align ="center">Please click browse to Upload the File</FONT>
<TABLE width="510" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
 <tr><td align="left" valign="top" height="20">
<FORM ENCTYPE="multipart/form-data"  ACTION ="http://sandbox.storyserver.zdnet.com/karora/cgi-bin/cgiScript.pl"; METHOD = "POST" >


Local File: <INPUT TYPE ="FILE" value= "UPLOAD" >
</td></tr><br>

<tr><td align="left" valign="top" height="20"><br>
&#032;&#032;<INPUT TYPE = "submit" value ="Transfer File">
<INPUT TYPE = "reset" value= "Reset ">
</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("UPLOAD");

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

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.
  

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

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="POST" ACTION="http://yourserver.com/cgi-bin/upload_file.cgi"; ENCTYPE="multipart/form-data">
Enter or Browse to the file you would like to upload.<BR>
<INPUT TYPE="file" NAME="fileID" VALUE="" SIZE=50 MAXLENGTH=80><BR>
<INPUT TYPE="submit" NAME="doWhat" VALUE="uploadMe">
</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=>"UPLOAD THIS");

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

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

    open(OPF,">$newFile") || &showError("Failed to open OPF, $!");
    while ($bytesread=read($fileID,$buffer,1024)) { print OPF "$buffer"; }
    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;
        &showError("Dangerous file type.<BR>Deleted file.");
        }

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

sub showError
{
my @error = @_;
print "<CENTER><font color=\"\#ff4500\">Fatal ERROR - @error</font><BR>\n";
print "Submission aborted - your data was not saved!!<BR>\n";
print "Please use the BACK button to return to the previous page<BR>\n";
print "and correct the error.<BR></CENTER>\n";
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

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

(OP)
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 "main::thisCGI" used only once: possible typo at load.pl line 6.
Name "main::bytesread" 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.

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

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{"UPLOAD"};

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

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

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

# 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.
http://www.oac-design.com

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

(OP)
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.

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

Get rid of the "use strict" then.  It's not necessary.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

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

Thanks

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

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 "use Fcntl ':flock';" 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.
http://www.oac-design.com

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

(OP)
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.

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

I don't know, that doesn't make much sense.  Please post your code and I'll have a look at it.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)

#!/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{"UPLOAD"};
my $filename = "http://sandbox.storyserver.zdnet.com/karora/cgi-bin/filename.txt
";

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

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

# 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");
}

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

Well, my first observation is that you need to use a valid system path, not a URL.  In other words, if "http://sandbox.storyserver.zdnet.com/karora/cgi-bin/filename.txt"; is the url to your file, then you have to reference it like "/home/users/karora/cgi-bin/filename.txt" assuming that is your file structure.  You'll have to ask your sysadmin the full path to your account.  Also, you should never put data files in your cgi-bin.  Instead you should put it somewhere like "/home/users/karora/datadir/filename.txt".  But that is just a security precaution... your system should let you write your file to your cgi-bin if you want to as long as it is owned by the webserver user and is chmod 777.

The second suggestion would be to try commenting out the flock code.  Some systems to not provide flock compatibility.  So, try commenting it out and see if that changes anything.

Does it run correctly from the command line?


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

owned by the webserver user and is chmod 777

i would definately not do this. firstly you should probably never have a data file in your cgi directory chmoded 777. i would make it 666, meaning read and write privledges for everyone. if you have it 777 you are, which is read/write/execute for everyone, you are just asking for problems. secondly, i would also not have any of my files owned by the webservers user account. that means someone else hosted on the system can arbitrarily change the permissions on your file, or do much worse, just by running a cgi program of their own. or, someone else could have it change things by writing to your chmod 777 file then running it.

if you have to make a file publicly writiable, dont give it execute permissions, and if you have to make a file publicly executable, dont give it write permission.

adam@aauser.com

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

I meant owned by the webserver user or chmod 777.  Otherwise you won't have permission to write the file from your perl script (unless you are using some sort of cgi-wrapper which changes the owner in some way).  This is also why I suggested NOT putting data files in your cgi-bin, but in a non-web-accessible directory.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

chmod 777 is still not a good idea for data files. even if its in a non web accessible directory.

adam@aauser.com

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

Well, if the webserver user does not have permission to write to that directory otherwise, you have no choice but to chmod 777.  In most cases, you'd be better off chowning that directory to the webserver user, though.  Sorry if I wasn't specific in my recommendation.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

no. why do you need 777? if you want to give it execute 755 is fine. if you want to give it write 666 is fine. you dont need to give the webserver write privledges to a file its going to execute.

adam@aauser.com

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

We're talking about writing a file.  The script needs to write a new datafile to the target directory.  So, it either needs to own that directory or have write permission.  You're right in that 666 would be sufficient for writing data files, but adding execution priviledges to non-executable files doesn't add any security risk as far as I know.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
Hi ,Thanks for all the help ,When i run the code on the command line it asks for the input and i set the variable $upload to the path of the file name and then it hangs up ,i think it does not assign the file contents to the variable $upload so it never enters the loop.

Please see the code below ,when i try to print the contents of the form it gives me the file name ,how can i find out if the contents are being uploaded.


#!/opt/ZDperl/bin/perl -w
> # CGI routines
> use CGI_Lite;
> #use Fcntl qw(:flock);
> my $cgi = new CGI_Lite;
> my %in = $cgi->parse_form_data;
>
> # get the file from the input stream
> my $upload = $in{"UPLOAD"};
>
> my $filename = "home/karora/textDir/filename.txt";
> # print your html header
> print "Content-type: text/html\n\n";
>
> # check if it's there, and write it to disk
> if ($upload)
> {
>   open(TEXT, ">$filename") || CgiDie("Cannot open $filename for
> writing");
>   #unless (flock (TEXT, LOCK_EX)) {CgiDie("Cannot lock $filename: $!");}
>   print TEXT $upload;
>   close(TEXT);
> }
> else {CgiDie("Error: file did not upload.");}
>
> # print the page
> print "<html><head><title>Form Output</title></head>";
> print "<body>";
> print "<h2>Results from FORM post:</h2><br>";
> #print "$upload";
> $view=$cgi->print_form_data;
> print $view;
> print "</body></html>";
>
> sub CgiDie
> {
>   my ($message) = @_;
>   print $message;
> #die ("$message");
> }

Thanks again for all the help.

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

To test your CGI script on the command line, you have to pass it your parameters in the same fashion that they would appear through CGI.  In your case, do something like this:

perl your_script.pl "UPLOAD='this is the contents of the file'"

Your script should then parse that into the %in array just as it would a file if you were uploading a text file with that line in it.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

if the file has a write privledge for everyone, there is a risk.

adam@aauser.com

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

Of course there is a risk in having anything world-writable.  But that is the only way that your script can write the file unless it owns the directory.  It is not too much of a risk if nobody but you has an account on your server, which ought to be the case if you are dealing with any sensitive data.  Or, if you have to share the system, then put your data in an RDMS protected by a password -- but that is still not too secure since the password must be contained in your necessarily readable script.  The point is, that in order for kavi98 to be able to write his uploaded file to his server's filesystem, then the directory he is writing to must be owned by the webserver user or world-writable.  Agreed?


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
perl load1.cgi
[ Reading query from standard input. Press ^D to stop! ]
UPLOAD = this has to be uploaded and the contents should alsio be a part of it
Content-type: text/html

Error: file did not upload.<html><head><title>Form Output</title></head><body><h
2>Results from FORM post:</h2><br>UPLOAD  =  this has to be uploaded and the con
tents should alsio be a part of it
</body></html>>                

This is the error generated,it still does not enter th loop,

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

yes, i agrred on that, but there is no reason to make a world-writeable file world executeable.

adam@aauser.com

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

That makes absolutely no sense whatsoever.  First, it outputs the error message which would only occur if $upload did not contain any data.  At that point, it should have died.  But, it continued running anyway despite the explicit die command.  And then, in the output, it printed the contents of $upload as what you typed in!  So, like I said, this makes no sense to me.  It should work just fine.  If $upload contains data, as it apparently does since it printed it out, then it shouldn't return an error.

Try putting the parameter on the command line like I showed you in my last post rather than allowing it to read from STDIN.  Also, is it still giving you an error if you do it from the web page form?


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
Thanks for all the help,the script works fine.


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

Does it really, or are you just tired of trying


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
No it actually does on the command line it transfers perfectly but then when i use it from the browser it just does not load.
Any reasons you can think why it does that.

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

What does not load?

Did you look at your error log?


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

Gotta' be getting close....;^)

Exactly what do you mean 'it does not load'?  Step by Step..... you bring up an HTML input page, identify a file to upload and click a submit button.... and so on........where exactly in the string of events does it 'not load'.  And what, in descriptive language, does it do or not do.



 
 
 
 keep the rudder amid ship and beware the odd typo

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

(OP)
If i type in the contents of the file on the command line it transfers then to the file given in the path,but when i try to run the same script as above i get a file not loaded error which is in the code,it does not get the contents of the file which i am trying to upload.

it is just not getting any contents from the web page.
this does not work .

my %in = $cgi->parse_form_data;

Thanks

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

Well, CGI_Lite is working if it is parsing it from the command line, so that's not the problem.  It might be your form on your webpage.  Make sure you have enctype="multipart/form-data" in your form tag, and make sure it is a POST.  Also, be sure you have a closing form tag.  Why don't you post your form here?


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
my html form
<!Form to upload a text file to generate a script .>
<HTML>
<HEAD>
<TITLE>Uploading File</TITLE>
</HEAD>
<BODY>
<FONT size=6 type="ariel" color = #0000FF align ="center">Please click browse to Upload the File</FONT>
<TABLE width="510" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
 <tr><td align="left" valign="top" height="20">
<FORM ENCTYPE="multipart/form-data"  ACTION ="http://sandbox.storyserver.zdnet.com/karora/cgi-bin/load1.cgi"; METHOD = "POST" >


Local File: <INPUT TYPE ="FILE" value= "UPLOAD" >
</td></tr><br>

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

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

There's your problem... your file input needs to named "UPLOAD", not valued "UPLOAD".

<input type="file" name="UPLOAD">


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
I have changed the name to UPLOAD but I transfer the name of the file and not the contents

the code that works is
#!/opt/ZDperl/bin/perl -w
# CGI routines
use CGI_Lite;
use Fcntl qw(:flock);
my $cgi = new CGI_Lite;
my %in = $cgi->parse_form_data();

# get the file from the input stream
my $upload = $in{"UPLOAD"};
my $filename = "/zd/home/karora/textDir/filename.txt";

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

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

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

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

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

That doesn't make any sense.  But what else is new?  Try testing it from a different machine.  That sounds like a browser error... the type="file" is supposed to send the contents of the selected file, not its name.  The name should never be sent to the CGI (unless maybe the file did not exist?).  The problem is on the client-side not the server-side.  You're using the HTML exactly as you wrote it above?  Make sure you upload a file that exists on your local drive.

Also, I'd remove the line that says "<!Form to upload a text file to generate a script .>".  I don't think that is a valid comment, nor closed correctly.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
I did try it on another machine maybe the parse_form data is not working as when i type on the command line i give the contents of the file it does not have to get it from the file.

it still transfers the filename,can i work some thing around it.
Please help.

Thanks

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

I'm am not up to speed on using CGI_Lite, so I may be barking up a non-existent tree.....but,..

If I do this same trick with CGI.pm (not advocating switching at this point, just drawing a comparison), the file name that CGI.pm gets from the upload variable is also a FILE HANDLE which is then read from.  

<snippet>

$fileID = $query->param('fileID'); # get file name
@pathName = split(/\\/,$fileID);   # throw away path
$newFile = '/some/path/to/put/the/new_file/'; # build local path for new file
$newFile .= pop(@pathName);                     # new path/name for new file
open(OPF,">$newFile") || &showError("Failed to open OPF, $!");
# $fileID is a filename and in the following context is a file HANDLE.
# read incoming stream and print to OPF, new file on local system
while ($bytesread=read($fileID,$buffer,1024)) { print OPF "$buffer"; }
close OPF;

</snippet>

Where in kavi98's post from today, is the 'read' happening?  Like I said, I'm not familiar with CGI_Lite, so maybe there is more going on in the code than I see.  If CGI_Lite works similarly to CGI.pm, and it appears it does, then printing $upload would simply print the name of the file being uploaded, and not it's contents.  If there is a behind the scenes 'read' going on, how do you descern between the filename and the file contents?


 
 
 
 keep the rudder amid ship and beware the odd typo

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

Ok, I've never had to do this (since you don't have to do this in cgi-lib.pl and CGI_Lite is basically compatible with the same code), but I found this in the documentation, and it appears to answer your question.  Right before you parse_form_data() do this:

$cgi->set_file_type ('handle');

Then use $in{'UPLOAD'} as a file handle.

http://theoryx5.uwinnipeg.ca/CPAN/data/CGI_Lite/CGI_Lite.html


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
#!/opt/ZDperl/bin/perl -w
# CGI routines
use CGI_Lite;
use Fcntl qw(:flock);
my $cgi = new CGI_Lite;
$cgi->set_file_type ('UPLOAD');
my %in = $cgi->parse_form_data();

# get the file from the input stream
my $upload = $in{"UPLOAD"};
my $filename = "/zd/home/karora/textDir/filename.txt";
 

this what i am doing?
I hope it is right,but it still uploads the name to the destination file.

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

(OP)
go boating ,
I have a question for you the snippet you have pasted above,
I am using it in the script and it keeps giving me an error of unintialised variable.
how do you set a variable to null or 0 before you use it.

Thanks

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

good morning kavi98,

You can simply do it.  like this .....    $variable = '; to set it to null.
But, if you are getting that error, it means something.  You don't want to set anything to '0' before this.  If you are saying that you are using the small chunk between the <snippet> tags, then all variables in that snippet should be set going into that section of code.

Also, that snippet uses CGI.pm.  As stated in that post, it is not compatible with CGI_Lite.  However, while I am not up to speed on CGI_Lite, I can do this trick with CGI.pm, easily.  Do you have CGI.pm installed?  If so, I am confident that we could get you running fairly quickly.  Even with the OO syntax.... it is really not that hard.  I can't believe this thread has meandered around for 40+ posts.  You must be tired of this.

Let me know how I can help.

on second thought, I will reiterate now.  If you have CGI.pm, then the following code will work.  It is in two sections.  The first is an HTML front page that should look very familiar (you stuff slightly tweaked).  The second is a piece of CGI that accepts the information from the HTML input page and does the upload.

Save the following code to your html directory.
## HTML Page ##
<HTML><HEAD><TITLE>UPLOAD THIS</TITLE></HEAD>
<BODY>
<FORM METHOD="POST" ACTION="http://sandbox.storyserver.zdnet.com/karora/cgi-bin/load1.cgi"; ENCTYPE="multipart/form-data">
Enter or Browse to the file you would like to upload.<BR>
<INPUT TYPE="file" NAME="UPLOAD" VALUE="" SIZE=50 MAXLENGTH=80><BR>
<INPUT TYPE="submit" NAME="doWhat" VALUE="uploadMe"></FORM>
</BODY>
</HTML>

## end HTML Page ##

Save the following code to your cgi-bin directory.
## CGI Code ##
#!/opt/ZDperl/bin/perl
use CGI;
$query = new CGI;
print $query->header;
print $query->start_html(-title=>"UPLOAD PLEASE");
$fileID = $query->param('UPLOAD');
@pathName = split(/\\/,$fileID);

unless ($fileID) { &showError('No file name specified.'); }
# if $fileID is not null, read file from remote machine and write locally.
if ($fileID)
    {
    # you must change the following line to point to a
    # dir on your machine that is writable by the web server
    # process

     $newFile ='/path/to/put/the/new/file/';
        
    # add upload filename to the new path
    $newFile .= pop(@pathName);

    # open a handle to the new file you will write
    open(OPF,">$newFile") || &showError("Failed to open OPF, $!");

    # while you read from the remote machine,
    # write to the output file.
    print "<P>Uploading <BR>$fileID <BR>to<BR>$newFile<BR></P>\n";
    while ($bytesread=read($fileID,$buffer,1024))
        { print OPF "$buffer"; }
    close OPF;

    # check to make sure the uploaded file is safe to keep
    # first retrieve the file type from the CGI object
    # then, check that it is something you want.
    $type = $query->uploadInfo($fileID)->{'Content-Type'};
    
    # if it is not 'text/html', delete it.
    # Depending on what type of file you want to upload
    # you may need to change the allowable types.

    unless ($type =~ /text\/html/i)
        {
        unlink $newFile;
        &showError("Dangerous file type.<BR>Deleted file.");
        }
    }
print $query->end_html;
    
sub showError
{
# a generic complaint generator
my @error = @_;
print "<CENTER><font color=\"\#ff4500\">ERROR - @error</font><BR>\n";
print "Please use the BACK button to return to the previous page<BR>\n";
print "and correct the error.<BR></CENTER>\n";
print $query->end_html;
exit;
}

## end CGI Code ##

You should be able to save the HTML portion as anything you want in your normal HTML dir.  Then copy/paste the CGI code into a file named load1.cgi, modify the parts that are shown in red in this post, and save that to cgi-bin dir specified in the <FORM ACTION='...> tag of the HTML page.  If you are on a UNIX box, ... looks like you are, make sure the execute bits are set on load1.cgi.

I wrote this on a Sun Solaris box, it worked.  Then, copied onto a WinNT 4.0, changed the red parts and the URL of the CGI code in the HTML page and it worked there also.

Admittedly, the HTML output is not pretty.  But, if you get the upload stuff working, making the HTML pretty is trivial.

I hope this helps.... feel free to ask questions.....

 
 
 
 keep the rudder amid ship and beware the odd typo

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

kavi98, I said to use "cgi->set_file_type ('handle');" not "cgi->set_file_type ('UPLOAD');".  Go to the link I posted for the full explanation.

goBoating, that's what I thought too.  I've used this code on multiple servers for many applications.  Strange that it gives errors now.

The main reason I don't like CGI.pm is because it takes too much control of what you are doing.  I like to get to the guts of things.  Just one reason I don't like OO programming that much... the entire theory of it is to hide the true functionality from the user.  As we've seen with Windows, that is a bad philosophy because you cannot fix the inherent bugs and it strips power away from you in controlling your own system.  I like CGI_Lite because its functions simply dump the input into the %in array at which point I can work on it as I please.  So, I would say that CGI.pm is to Windows, as CGI_Lite.pm is to Linux.  Of course, that is not entirely true, since you could go into the module and change stuff around, but on the surface, that is what it is like.  Maybe a better comparison would be that CGI.pm is to FrontPage, as CGI_Lite.pm is to Emacs.  Yeah, that gets to the core of it.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

Tom,
On the whole, I agree that flexibility in the tool is important.  But, I find that in the universe of things I want to do with CGI code, CGI.pm does some of them pretty well with minimal labor on my part.  There are other things that it is pretty poor at, so I take other routes.  This upload trick is pretty easy with CGI.pm, so I use it.

Later,

 
 
 
 keep the rudder amid ship and beware the odd typo

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

(OP)
goboating ,
I have tried to check for synatax mistakes i might have made ,but this error keeps comming.
used only once: possible typo at (eval 18) line 5.
Can't use an undefined value as a HASH reference at /zd/home/karora/cgi-bin/try2.cgi line 23.

@pathName = split(/\\/,$fileID);
it just keeps giving an error on  this line and

$type = $query->uploadInfo($fileID)->{'Content-Type'};
    
    thanks for all the help,but i am at a loss totally as to why it is doing it,but when i use CGI::Debug it transfers the file and prints out the error.

Thanks
Another question can i call another perl program within a CGI script.


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

OK,

There must be a disconnect between the HTML front page and your CGI.  Fields are named inconsistently or something like that.  I can't tell exactly with out more of the code.

I will help until it works, but, as I stated before, I don't know nada about CGI_Lite or cgi_lib.  So, are you using CGI.pm exclusively and did you try to copy/paste the code I posted this morning?  If yes, then email those text files to me at john.ulmer@noaa.gov.  I'll take a look at them and get back with you.  We can get this working and then post our solution once we get one.

If you want to try to use the other modules, I will have to leave this to Tom.  He is much better with them than I.

What ever works...;^)


 
 
 
 keep the rudder amid ship and beware the odd typo

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

Hey, the Perl motto is, there's more than one way to do it!  There are other modules besides CGI_Lite.pm and CGI.pm that do this as well.  Pick one and go with it.  The fix to that one line I pointed out should get the code working.  Or use the CGI.pm method.  Personally, I'd go the lowest level possible, even to the point of parsing STDIN yourself.  In fact, that would be the best way to know what these modules are actually trying to do with their object-oriented functions.  Why learn a proprietary interface to your code, when you could just learn the code itself? ...and probably more easily!


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

(OP)
The code that works
I want to thank you all for helping me make it work.

#!/opt/ZDperl/bin/perl -w
use CGI;
$query = new CGI|| die("$!");
print $query->header;
print $query->start_html(-title=>"UPLOAD THIS");
$fileID = $query->param('UPLOAD');
@pathName = split(/\\/,$fileID);

unless ($fileID) { &showError('No file name specified.'); }
if ($fileID)
    {
    $newFile = '/zd/home/karora/textDir/';
    $newFile .= pop(@pathName);
    chmod (0755, "$newFile");
    open(OPF,">$newFile") || &showError("Failed to open OPF, $!");
    print "<P>Uploading <BR>$fileID <BR>to<BR>$newFile<BR></P>\n";
    while (read($fileID,$buffer,1024)) { print OPF "$buffer"; }
    close OPF;
   }
    print "<BR>Upload of $newFile Successful<BR>\n";
    print $query->end_html;

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

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

goBoating, I've renamed the FAQ I wrote in this forum to specify the libraries it uses.  Please write a FAQ illustrating the use of CGI.pm for file uploads, well commented if possible.  I think it will be very helpful to have that.


Sincerely,
 
Tom Anderson
CEO, Order amid Chaos, Inc.
http://www.oac-design.com

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

' will do.

Thanks


 
 
 
 keep the rudder amid ship and beware the odd typo

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close