einerwitzen has asked for the wisdom of the Perl Monks concerning the following question:

I have managed to piece together (from looking at other's scripts) a very simple script that takes all of the elements sent to it via html form and arranges them and emails the results.

All I am trying to do now is add a little modification of making a few of the fields required. A problem, the script doesn't have the fields being sent to it hard coded into it so I can't easily put a simple if ($firstname = "") in it. It loops, reading each name=value.

You can see below I tried just coding into the loop to check for if $name = "firstname" then check if $value = "". But it doesn't work at all. I could use some help, hack at me all ya can!

#!/usr/bin/perl $mailprog = "/usr/lib/sendmail"; $msg = ""; $send_to = "webmaster\@3dwc.com"; $subject = "Online Repair Status Inquiry"; $from = "Form Submission"; $ok_url = "/thanks.html"; $bad_url = "/nogo.html"; %f = &parseform; foreach $key (sort keys %f) { $mystring = "$key: $f{$key}\n"; $msg .= $mystring; } &sendmail($from,$send_to,$subject,$msg); print "Location: $ok_url\n\n"; sub sendmail { my($from,$to,$subject,@msg) = @_; open(MAIL,"|$mailprog -t"); print MAIL "To: $to\n"; print MAIL "From: $from\n"; print MAIL "Subject: $subject\n\n"; print MAIL <<EndMail; @msg EndMail close(MAIL); } sub parseform { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; if ($name = "firstname"){ if ($value = ""){ die print "must enter first name"; }else{ #all is well } }elsif ($name = "lastname{ #all is well } } return %FORM; }


Replies are listed 'Best First'.
Re: modification of simple form-email script
by gellyfish (Monsignor) on Mar 06, 2002 at 21:17 UTC

    To cut a long story short you have been looking at the wrong scripts to modify - in the first instance I would suggest that you look at the nms form to e-mail program.

    To expand a bit, firstly the program will not run cleanly with '-w' or 'use strict', the parseform() subroutine will not return the correct details with a perfectly valid form submission. parseform() cannot handle a GET request however their is no attempt to detect what the request method is. There is no attempt to determine whether the pipe to 'sendmail' was opened successfully. parseform() will potentially output before any CGI headers are output... you probably want to check where the $to variable you are using in your mail message is being assigned - I think you forgot the $send_to variable you assigned to earlier.

    /J\

Re: modification of simple form-email script
by perrin (Chancellor) on Mar 06, 2002 at 22:04 UTC
    Just please, please, PLEASE promise me that you will make it totally impossible for anyone to change the TO, CC, or BCC fields of the e-mail by sending data to your script! I have received literally tens of thousands of spam e-mails because of the security flaws in Matt Wright's formmail.pl script. I am not exaggerating this at all.
Re: modification of simple form-email script
by silent11 (Vicar) on Mar 06, 2002 at 21:15 UTC
    use CGI; it takes care of your input from html forms and takes does your sub parseform{} for you. Throw away the sub parseform{} and look at the CGI module. Type 'cgi' into the search bar and read up on the docs.

    UPDATE:
    email.pl
    this code is self explaintory, and eaisily modifiable.
    #!/usr/bin/perl use CGI qw/:standard/; $to=param('to'); $from=param('from'); $fromhandle=param('fromhandle'); $subject=param('subject'); $contents=param('contents'); if (param()) { open(MAIL, "|/usr/sbin/sendmail -t") || die "cant open"; print MAIL "To: $to \nFrom: $from ($fromhandle)\n"; print MAIL "Subject: $subject \n\n"; print MAIL "$contents\n"; close(MAIL); print "Content-type: text/html\n\n"; print "To:$to<br>\n"; print "From:$from rather know as: \'$fromhandle\'<br>\n"; print "Subject: $subject<br>\n\n\n"; print "$contents"; } else { print "Content-type: text/html\n\n"; print <<EOF; <html><body> <form action="email.pl" method="post"> to:<br> <input type="text" name="to"><br> from:<br> <input type="text" name="from"><br> from handle:<br> <input type="text" name="fromhandle"><br> subject:<br> <input type="text" name="subject"><br> Contents:<br> <textarea name="contents" rows=30 cols=64></textarea> <input type="submit"> <input type="Reset"> </form> </body> </html> EOF }
    -Silent11
Re: modification of simple form-email script
by trs80 (Priest) on Mar 06, 2002 at 21:23 UTC
    The problem may lie in the if statement it self.
    if ($name = "firstname"){
    isn't checking anything it is assigning someting. You want
    if ($name eq "firstname"){
    '=' assigns '==' is numerical comparisons and 'eq' is for string comparisons. (by design not by force)

    If you did this with CGI you could do this:
    use CGI; use strict; my %FORM; map {$FORM{$_} = uri_unescape($cgi->param("$_"))} $cgi->param(); if ($FORM{firstname} eq '') { die print "must enter first name"; }
    or something along those lines, but you shouldn't die in CGI either. There are much more graceful and correct ways to handle it. So a super search for CGI Ovid and you should find loads of helpful information.
Re: modification of simple form-email script
by einerwitzen (Sexton) on Mar 06, 2002 at 21:11 UTC
    sorry just noticed a mistake in my post the elsif part isn't supposed to be there. Pretend it's just else cuz it doesn't work either way :)