whats up everybody? havent been on daniweb in a while. self-motivation like whut....until now. anyways ive got this script that makes an html form with 19 or so fields. its supposed to put the form info into a file (mediaRequest_log.txt). it gets this information by way of

# get form info from POST method
	read(STDIN, $text, $ENV{'CONTENT_LENGTH'});

	my @value_pairs = split (/&/,$text);
	my %form_results = ();

	foreach $pair (@value_pairs) {                 
    		($key, $value) = split (/=/,$pair);
    		$value =~ tr/+/ /;
   		$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
    		$form_results{$key} = $value;  # store the key in the results hash
	}

and then to put it into a variable and append it to a file

foreach $key (sort keys(%form_results)) {
    	#	print "$key has value $form_results{$key}<BR>\n";
	#	$mail_string .= "$key = $form_results{$key}\n";
		$file_string .= "$form_results{$key}|";
	}

	chop($file_string); 

	# add newline to end of $file_string
	$file_string .= "\n";

	$filename = "mediaRequest_log.txt";
	open(DAT,">>$filename") || die("Cannot Open File");
	print DAT "$file_string"; 
	close(DAT);

now i also use this

use CGI;
$query =  new CGI;

to format the form element values for a email string ($mail_string) and a display string to display the results when the submit button is clicked ($display_string). long story short, this script works fine except that it does not write anything to the file except for a blank line. why is this happeneing???? can i not use both methods together? if thats not so, how can i fix my script to make it write the form element values to the text file? your help is greatly appreciated.

Recommended Answers

All 8 Replies

#!/usr/local/bin/perl

# Simple Email Function
# ($to, $from, $subject, $message)
sub sendEmail
{
	my ($to, $from, $subject, $message) = @_;
	my $sendmail = '/usr/lib/sendmail';
	open(MAIL, "|$sendmail -oi -t");
	print MAIL "From: $from\n";
	print MAIL "To: $to\n";
	print MAIL "Subject: $subject\n\n";
	print MAIL "$message\n";
	close(MAIL);
}

use CGI;
$query =  new CGI;

# get username
$user = $ENV{'REMOTE_USER'};

if ( $ENV{'CONTENT_LENGTH'} > 0 )
{
# ~~~~~~~~~~~~~~~~~~~~~~  GETTING FORM INFO FOR $file_string   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	# get form info from POST method
	read(STDIN, $text, $ENV{'CONTENT_LENGTH'});

	my @value_pairs = split (/&/,$text);
	my %form_results = ();

	foreach $pair (@value_pairs) {                 
    		($key, $value) = split (/=/,$pair);
    		$value =~ tr/+/ /;
   		$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
    		$form_results{$key} = $value;  # store the key in the results hash
	}

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

	# loop through the results and print each key/value
	# also make $file_string from each key/value
	foreach $key (sort keys(%form_results)) {
    	#	print "$key has value $form_results{$key}<BR>\n";
	#	$mail_string .= "$key = $form_results{$key}\n";
		$file_string .= "$form_results{$key}|";
	}

	chop($file_string); 

	# add newline to end of $file_string
	$file_string .= "\n";

	$filename = "mediaRequest_log.txt";
	open(DAT,">>$filename") || die("Cannot Open File");
	print DAT "$file_string"; 
	close(DAT);

	print "Here is the file string: " . $file_string;

# ~~~~~~~~~~~~~~~~~~~~~  ADD INFO TO $mail_string   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	$mail_string = "User: " . $query->param('user') . "\n";
	$mail_string .= "Date of Media Request: " . $query->param('date') . "\n";
	$mail_string .= "Requested by: " . $query->param('req_by') . "\n";
	$mail_string .= "Ship-to Address: " . $query->param('ship_to') . "\n";
	if ( $query->param('is_free') eq "on" )
	{
		$mail_string .= "Is this a free EO3 webcast? YES \n";
	}
	else
	{
		$mail_string .= "Is this a free EO3 webcast? NO  \n";
		$mail_string .= "Billing Address: " . $query->param('bill_to') . "\n";
	}
	$mail_string .= "Date of Program Requested: " . $query->param('dateOfProg') . "\n";
	$mail_string .= "Title/Description of Program: " . $query->param('title') . "\n\n";
	$mail_string .= "PHYSICAL MEDIA PREFERENCES\n";
	$mail_string .= "Number of CDs Requested: " . $query->param('cd') . "\n";
	$mail_string .= "Number of DVDs Requested: " . $query->param('dvd') . "\n";
	$mail_string .= "Number of VHS Tapes Requested: " . $query->param('vhs') . "\n\n";
	$mail_string .= "FILE FORMATS REQUESTED\n";
	if ( $query->param('windows') eq "on" )
	{
		$mail_string .= "Include Windows files.\n";
	}
	if ( $query->param('real') eq "on" )
	{
		$mail_string .= "Include Real files.\n";
	}
	if ( $query->param('quicktime') eq "on" )
	{
		$mail_string .= "Include Quicktime files.\n";
	}
	if ( $query->param('caption') eq "on" )
	{
		$mail_string .= "Include Caption files.\n";
	}
	$mail_string .= "\nUrgency: " . $query->param('urgency') . "\n";
	$mail_string .= "Selected Shipping Method: " . $query->param('shipping') . "\n";
	$mail_string .= "Special Instructions: " . $query->param('specInstr') . "\n";
	$mail_string .= "E-mailed to: " . $query->param('email_to') . "\n";

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  END SECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~~~~~~~~~~~~~~  ADD INFO TO $display_string  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	$display_string = "User: " . $query->param('user') . "<br>";
	$display_string .= "Date of Media Request: " . $query->param('date') . "<br>";
	$display_string .= "Requested by: " . $query->param('req_by') . "<br>";
	$display_string .= "Ship-to Address: " . $query->param('ship_to') . "<br>";
	if ( $query->param('is_free') eq "on" )
	{
		$display_string .= "Is this a free EO3 webcast? YES <br>";
	}
	else
	{
		$display_string .= "Is this a free EO3 webcast? NO  <br>";
		$display_string .= "Billing Address: " . $query->param('bill_to') . "<br>";
	}
	$display_string .= "Date of Program Requested: " . $query->param('dateOfProg') . "<br>";
	$display_string .= "Title/Description of Program: " . $query->param('title') . "<p>";
	$display_string .= "<b>PHYSICAL MEDIA PREFERENCES</b><br>";
	$display_string .= "Number of CDs Requested: " . $query->param('cd') . "<br>";
	$display_string .= "Number of DVDs Requested: " . $query->param('dvd') . "<br>";
	$display_string .= "Number of VHS Tapes Requested: " . $query->param('vhs') . "<p>";
	$display_string .= "<b>FILE FORMATS REQUESTED</b><br>";
	if ( $query->param('windows') eq "on" )
	{
		$display_string .= "Include Windows files.<br>";
	}
	if ( $query->param('real') eq "on" )
	{
		$display_string .= "Include Real files.<br>";
	}
	if ( $query->param('quicktime') eq "on" )
	{
		$display_string .= "Include Quicktime files.<br>";
	}
	if ( $query->param('caption') eq "on" )
	{
		$display_string .= "Include Caption files.<br>";
	}
	$display_string .= "<p>Urgency: " . $query->param('urgency') . "<br>";
	$display_string .= "Selected Shipping Method: " . $query->param('shipping') . "<br>";
	$display_string .= "Special Instructions: " . $query->param('specInstr') . "<br>";
	$display_string .= "E-mailed to: " . $query->param('email_to') . "<p>";

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  END SECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	sendEmail( $query->param('email_to'), "sara\@aanet.org", "New Media Request.", 
		$mail_string );

	print "<h3>Here is the new Media Request you just added.</h3><p>";

	print "<img src=\"http://gothics.aanet.org/images/eagle1.gif\" align=\"right\" alt=\"Great Job!\"><p>";
	print "<h3 align=\"right\">Great Job!</h3>";

	print $display_string;

# ~~~~~~~~~~~~~~~~~~  OLD display media request you just added  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#	print "<table border=\"2\">";

#	foreach $key (sort keys(%form_results)) {
#    		print "<th>$key</th>";
#	}
	
#	print "<tr>";
#	foreach $key (sort keys(%form_results)) {
#    		print "<td>$form_results{$key}</td>";
#	}
#	print "</tr>";
	
#	print "</table><p>";
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	
	
	# link back to main menu
	print "<a href=\"http://gothics.aanet.org/cgi-bin/media/mediamenu.cgi\">Main Menu</a>";

	print "</body></html>\n";
}
else
{
	# get time info from perl's time function
	@timeData = localtime(time);	
	$timeData[4] += 1;
	$timeData[5] += 1900;

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

	print "<h2>Make a New Media Request.</h2>\n";

	print "<form name=\"media_request\" method=\"post\" action=\"request.cgi\">";

	print "<img src=\"http://gothics.aanet.org/images/eddie_van_halen_jump.jpg\" align=\"right\" alt=\"Jump\">";

	print "User: <input type=\"text\" name=\"user\" value=\"$user\"><p>\n";
	print "Date: <input type=\"text\" name=\"date\" value=\"$timeData[4]/$timeData[3]/$timeData[5]\"><p>\n";
	print "Requested by: <input type=\"text\" name=\"req_by\"><p>\n";
	print "Ship-to Address: <input type=\"text\" size=\"60\" name=\"ship_to\"><p>\n";

	print "Complimentary copy of EO3 webcast? (one per member): <input type=\"checkbox\" name=\"is_free\">
		Yes (if not, leave unchecked)<p>\n";

	print "If not free, send bill to (same as ship-to): <input type=\"text\" name=\"bill_to\" size=\"60\"><p>\n";
	print "Date of program requested: <input type=\"text\" name=\"dateOfProg\" size=\"35\"><p>\n";
	print "Description/Title of program: <input type=\"text\" size=\"60\" name=\"title\"><p>\n";

	print "<b>Choose your media preferences below.</b><p>";
	print "How many CDs?: <input type=\"text\" name=\"cd\"><p>\n";
	print "How many DVDs?: <input type=\"text\" name=\"dvd\"><p>\n";
	print "How many VHS tapes?: <input type=\"text\" name=\"vhs\"><p>\n";

	print "<b>Standard files to be included: </b><p>
			<input type=\"checkbox\" checked=\"yes\" name=\"windows\"> Windows<p>\n" . 
			"<input type=\"checkbox\" checked=\"yes\" name=\"real\"> Real<p>\n" . 
			"<input type=\"checkbox\" checked=\"yes\" name=\"quicktime\"> Quicktime<p>\n" . 
			"<input type=\"checkbox\" checked=\"yes\" name=\"caption\"> Captioning<p>\n";

	print "Urgency: <input type=\"text\" name=\"urgency\"><p>\n";
	
	print "Please choose a shipping method: <select name=\"shipping\">" . 
		"<option value=\"\">Shipping Methods</option>" .
		"<option value=\"DHL-next day by 10:30am\">DHL next day by 10:30am</option>" . 
		"<option value=\"DHL-next day by noon\">DHL next day by noon</option>" .
		"<option value=\"DHL-next day by 3:00pm \">DHL next day by 3:00pm</option>" .
		"<option value=\"DHL-2 day\">DHL 2 day</option>" .
		"<option value=\"USPS\">USPS (not recommended)</option>";
	print "</select><p>\n";

	print "Special Instructions: <input type=\"text\" name=\"specInstr\" size=\"60\"><p>\n";
	print "E-mail to: <input type=\"text\" name=\"email_to\"><p>\n";
		
	print "<input type=\"submit\" name=\"submit_all\" value=\"Submit\"><p>\n";

	print "</form>\n";
	print "</body></html>\n";
}

why are you mixing that terrible form parsing code in with CGI anyway? Use the CGI module to get all the form data, don't mix it with that insecure code you are using. Also, when the script reads the data from STDIN:

read(STDIN, $text, $ENV{'CONTENT_LENGTH'});

it empties the buffer, so any subsequent attemptsto read the same data will fail. That may explain your situation, but i did not take a close look at your code.

i am fairly new to perl. can you explain what you mean by this?

"why are you mixing that terrible form parsing code in with CGI anyway? Use the CGI module to get all the form data, don't mix it with that insecure code you are using."

This is the terrible code I refer to:

if ( $ENV{'CONTENT_LENGTH'} > 0 )
{
# ~~~~~~~~~~~~~~~~~~~~~~ GETTING FORM INFO FOR $file_string ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# get form info from POST method
read(STDIN, $text, $ENV{'CONTENT_LENGTH'});
my @value_pairs = split (/&/,$text);
my %form_results = ();
foreach $pair (@value_pairs) {
($key, $value) = split (/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
$form_results{$key} = $value; # store the key in the results hash
}

You have loaded the CGI module and created a CGI object ($query)

use CGI;

$query = new CGI;

That is what you shoud use to get all the form data, like you do in some parts of the code:

$query->param('bill_to')

This is the terrible code I refer to:

if ( $ENV{'CONTENT_LENGTH'} > 0 )
{
# ~~~~~~~~~~~~~~~~~~~~~~ GETTING FORM INFO FOR $file_string ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# get form info from POST method
read(STDIN, $text, $ENV{'CONTENT_LENGTH'});
my @value_pairs = split (/&/,$text);
my %form_results = ();
foreach $pair (@value_pairs) {
($key, $value) = split (/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;
$form_results{$key} = $value; # store the key in the results hash
}

You have loaded the CGI module and created a CGI object ($query)

use CGI;

$query = new CGI;

That is what you shoud use to get all the form data, like you do in some parts of the code:

$query->param('bill_to')

well i was using that because it was a fast and easy way to get all the form elements into a string delimited by a '|' character. u keep saying its terrible code.....but why is it terrible code? believe me i would like to do everything using $query->param('watever') but id rather not write out each element to just put it in a string.

btw i was able to do what i want to do without using

use cgi;
$query = new CGI;

if you know of an easy way to get all the form element values into a string delimited by '|' then please share it!!!!

untested but should work

use CGI;
my $query = CGI->new;
my %form_results = $query->Vars;
my $file_string = join ('|',map {$form_results{$_}} sort keys %form_results);
print $file_string;

read the CI module documentation. I know it is long and some parts are a bit hard to follow, but the part about importing all the params as a list or hash or array is easy to understand.

thank you for your help that bit of code works great. i still would like to know what is so bad about the other code i was using.....you said it was insecure. what makes it insecure? i guess my question is why should i use the CGI module instead, besides the fact taht its easier.

Some reading if you are interested:

http://users.easystreet.com/ovid/cgi_course/lessons/lesson_two.html

You should also be using Taint mode with all CGI scripts.

Ask on www.perlmonks.com why you should not use the form parsing code you posted above and you should get some more opinions. Mine is my own, the opinion of others may vary. Exposure to more opinions may at first be confusing but hopefully it will be educational.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.