Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

sendmail working for me but not another

by kickingchicken (Initiate)
on May 25, 2020 at 12:12 UTC ( [id://11117230]=perlquestion: print w/replies, xml ) Need Help??

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

Hello, I am using sendmail to send form data to 3 emails. Then the user is sent to a confirmation page. It works for me, and others as I am receiving emails, but for a few others it does not. They are being sent to the confirmation page but no emails are ever sent out. Am I doing something wrong, or is this server related?

#!/usr/bin/perl use CGI qw/:standard/; $CGI::POST_MAX=1024 * 1; #$CGI::Validate::IgnoreNonMatchingFields = 1; $fstname = substr param ('first'), 0, 40; $lstname = substr param ('last'), 0, 40; $adda = substr param ('1ad1a'), 0, 60; $addb = substr param ('1ad1b'), 0, 60; $city = substr param ('1ad2'), 0, 60; $state = substr param ('1ad3'), 0, 20; $zip = substr param ('1ad4'), 0, 5; $email = substr param ('eadd'), 0, 70; $phone = substr param ('pnum'), 0, 16; $residence = substr param ('residence'), 0, 9; $yardtype = substr param ('yardtype'), 0, 16; $yardtypeother = substr param ('yardtypeother'), 0, 40; $landlord = substr param ('landlord'), 0, 40; $preadda = substr param ('2ad1'), 0, 60; $precity = substr param ('2ad2'), 0, 60; $prestate = substr param ('2ad3'), 0, 20; $prezip = substr param ('2ad4'), 0, 5; $alone = substr param ('alone'), 0, 14; $household = substr param ('household'), 0, 100; $vet = substr param ('vet'), 0, 45; $pet = substr param ('pet'), 0, 3; $petname = substr param ('petnme'), 0, 30; $currentpets = substr param ('currentpets'), 0, 60; $previouspets = substr param ('previouspets'), 0, 60; $references = substr param ('references'), 0, 140; $ok = substr param ('ok'), 0, 7; ## Clear out unwanted characters $fstname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $lstname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $adda =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $addb =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $city =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $state =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $zip =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $email =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $phone =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $residence =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $yardtype =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $landlord =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $preadda =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $precity =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $prestate =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $prezip =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $alone =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $household =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $vet =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $pet =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $petname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $currentpets =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $previouspets =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $references =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $ok =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $email =~ tr/[A-Z]/[a-z]/; ## Check email address if (($email ne "") && ($email !~ m/[\w]+@[\w]+\.[\w]+/)) { print "Content-type: text/html\n\n"; print "error (Your email is invalid, please check and resubmit you +r application)</ br></ br>"; exit; } ## Check data $total_form = "$fstname$lstname$email"; if (length($total_form) < 25) { print "Content-type: text/html\n\n"; print "error (The form was incomplete, please check that you fill +ed in your full first and last name, and email address, then resubmit + your application.)</ br></ br>"; exit; } # residence replace with response ##if ($residence eq "1") ## { ## $residence = "House" ## } ##if ($residence eq "2") ## { ## $residence = "Apartment" ## } $recipient = "email1\@emailsrv1, email2\@emailsrv2, email3\@emailsrv3" +; ## Create the email message body $email_message = qq{To: $recipient Subject: Adoption Application From: $fstname $lstname<$email> First name: $fstname Last name: $lstname Current address: $adda $addb $city $state $zip _________________________________________________ Email address: $email Phone number: $phone Type of residence: $residence Yard: $yardtype Landlord contact info: $landlord Previous address: $preadda $precity $prestate $prezip How many hours will pet be alone: $alone Name and age of people in household: $household Veterinarian: $vet Dog or Cat: $pet Name of pet requested: $petname Current pets: $currentpets Previous pets: $previouspets References: $references Aggree to consent form: $ok }; ## Send email $mailprog = '/usr/sbin/sendmail'; open (MAIL, "|$mailprog -t"); print MAIL $email_message; close (MAIL); print "Location: application-submitted \n\n"; exit; __END__

Replies are listed 'Best First'.
Re: sendmail working for me but not another
by tobyink (Canon) on May 25, 2020 at 14:51 UTC

    Firstly, your $email_message looks weird. There should be a blank line after the final header line. So after the "From" line, but before the "First name" line, leave a totally blank line. Not even any whitespace characters on it. That certainly could be causing issues; fix that first.

    If that doesn't help, you state two different issues in your question which might seem the same, but very much are not:

    • People do not receive emails
    • Emails are never sent out

    If people are not receiving emails, it doesn't mean that they were never sent out. They could have been sent but lost somewhere along the way to the user's inbox, perhaps dropped by an overzealous spam filter.

    You want to check your outgoing mail server log files to find out if the emails are being sent or not. That log may also have some useful information about the status codes the recipient's mail server has responded with.

    If my first suggestion didn't fix things, and there's no clues in the mail log about what went wrong, then I would suggest the most common explanation is that your mail is being filtered as spam, so fixing that would be a good thing to attempt. Look into configuring your mail server to add DKIM headers to outgoing mail, and put DKIM and SPF entries into your DNS.

    Oh, and by the way, your check to see if an email address is valid is pretty bad. It rejects bob-smith@bobs-furniture.com.

      ## Create the email message body $email_message = qq{To: $recipient Subject: Adoption Application From: $fstname $lstname<$email> First name: $fstname Last name: $lstname

      So you are saying it should look like this? Thank you toby, i'm trying to clarify it, its just hard to explain. I do receive emails of the form data, i have received about 20 so far. However a few people have complained they have submitted but I haven't received the data, neither have the other 2 email boxes. One person in particular, submits the form and makes it to the confirmation page, but no one gets the data in an email. I know the code is horrible but i'm learning. I will just remove the email validity code. I don't send an email to that, its just a means to collect their address for this application.

      My host is telling me i'm not allowed to look at the email logs, I've asked them what I can access and i'm waiting to hear. I'm not sure they know what i'm talking about, but they did present to me a list of emails that were sent successfully with my perl but that doesn't help me.. cause I know they were sent, I have them. I can't ssh in right now, having trouble with it and i'm trying to correct that through them. I will try this new empty line you asked me to add, and also what bliako mentioned. Thanks you two.

        So you are saying it should look like this?

        Yes, what you showed is correct. Note it's generally better to use heredocs instead of a multiline qq, so e.g.

        my $email_message = <<"ENDMAIL"; To: $recipient Subject: Adoption Application ... ENDMAIL
        My host is telling me i'm not allowed to look at the email logs, I've asked them what I can access and i'm waiting to hear.

        You could write out your data to a logfile on your account, in case something with the emails doesn't work out.

        I know the code is horrible but i'm learning.

        If this were a legacy script, ok, but if this a new script, then you'd be much better off learning something more modern. I've been doing a lot with Mojolicious recently, and I think it's pretty great. See Mojolicious::Guides::Tutorial for getting started. Otherwise, at the very least what this script needs is to Use strict and warnings! See also UP-TO-DATE Comparison of CGI Alternatives.

        And with that many variables, it'd be much better to store them in a data structure like a hash. Then you could do things like loop over it so you don't have to repeat the regex a bunch of times. (Also, note you don't seem to be doing anything with the yardtypeother field.)

        Also, you should check if the host has Email::Sender::Simple installed, that should be much better and easier to use than shelling out to sendmail.

        Also, here's what I mean about eliminating repetition. It's untested though.

        #!/usr/bin/perl use strict; use warnings; use CGI qw/:standard/; $CGI::POST_MAX = 1024 * 1; my %fields = ( fstname => [ first => 40 ], lstname => [ last => 40 ], adda => [ 1ad1a => 60 ], addb => [ 1ad1b => 60 ], city => [ 1ad2 => 60 ], state => [ 1ad3 => 20 ], zip => [ 1ad4 => 5 ], email => [ eadd => 70 ], phone => [ pnum => 16 ], residence => [ residence => 9 ], yardtype => [ yardtype => 16 ], yardtypeother => [ yardtypeother => 40 ], landlord => [ landlord => 40 ], preadda => [ 2ad1 => 60 ], precity => [ 2ad2 => 60 ], prestate => [ 2ad3 => 20 ], prezip => [ 2ad4 => 5 ], alone => [ alone => 14 ], household => [ household => 100 ], vet => [ vet => 45 ], pet => [ pet => 3 ], petname => [ petnme => 30 ], currentpets => [ currentpets => 60 ], previouspets => [ previouspets => 60 ], references => [ references => 140 ], ok => [ ok => 7 ], ); my %values; for my $key ( keys %fields ) { my ( $post_param, $max_length ) = @{ $fields{$key} } my $value = substr( param($post_param), 0, $max_length ); $value =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $values{$key} = $value; } $values{email} =~ tr/[A-Z]/[a-z]/; ## Check email address if ( $values{email} ne "" and $values{email} !~ /\@/ ) { print "Content-type: text/plain\n\n"; print "error (Your email is invalid, please check and resubmit you +r application)"; exit; } ## Check data my $total_form = $values{fstname} . $values{lstname} . $values{email}; if ( length($total_form) < 25 ) { print "Content-type: text/plain\n\n"; print "error (The form was incomplete, please check that you fille +d in your full first and last name, and email address, then resubmit +your application.)"; exit; } my $recipient = "email1\@emailsrv1, email2\@emailsrv2, email3\@emailsr +v3"; ## Create the email message body my $email_message = <<"MESSAGE" To: $values{recipient} Subject: Adoption Application From: $values{fstname} $values{lstname} <$values{email}> First name: $values{fstname} Last name: $values{lstname} Current address: $values{adda} $values{addb} $values{city} $values{state} $values{zip} _________________________________________________ Email address: $values{email} Phone number: $values{phone} Type of residence: $values{residence} Yard: $values{yardtype} Landlord contact info: $values{landlord} Previous address: $values{preadda} $values{precity} $values{prestate} $values{prezip} How many hours will pet be alone: $values{alone} Name and age of people in household: $values{household} Veterinarian: $values{vet} Dog or Cat: $values{pet} Name of pet requested: $values{petname} Current pets: $values{currentpets} Previous pets: $values{previouspets} References: $values{references} Aggree to consent form: $values{ok} MESSAGE ## Send email my $mailprog = '/usr/sbin/sendmail'; open my $mailhandle, '|-' "$mailprog -t" or die "Could not open mailhandle"; print $mailhandle $email_message; close $mailhandle; print "Location: application-submitted\n\n"; exit;

        Yep, that's where the empty line should be.

        Sucks not having access to logs. I'm generally admin of most machines I work on these days, but I have had to deal with limited hosting accounts at times and not having direct access to logs can be one of the most frustrating things, especially with how prone I am to typos and other silly little mistakes.

        And don't worry about your code. It's not that bad; standard beginner stuff. Could be a lot worse. It's pretty repetitive though. As you start learning more, you'll learn to hate repetitive code, and start to use loops and write things in a more abstract way. Everybody has to start somewhere though. :)

Re: sendmail working for me but not another
by jwkrahn (Abbot) on May 25, 2020 at 21:26 UTC
    ## Clear out unwanted characters $fstname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $lstname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $adda =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $addb =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $city =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $state =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $zip =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $email =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $phone =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $residence =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $yardtype =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $landlord =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $preadda =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $precity =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $prestate =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $prezip =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $alone =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $household =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $vet =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $pet =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $petname =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $currentpets =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $previouspets =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $references =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g; $ok =~ s/[\|\/\\}{\[\]\(\)\*&\^%\$\#<>;:]/ /g;

    You have a lot of repetition that can be eliminated and using tr/// is more efficient than using s///g.

    ## Clear out unwanted characters tr/|\/\\{}[]()<>*&^%$#;:/ / for $fstname, $lstname, $adda, $addb, $city, $state, $zip, $email, $phone, $residence, $yardtype, $landlord, $preadda, $precity, $prestate, $prezip, $alone, $household, $vet, $pet, $petname, $currentpets, $previouspets, $references, $ok;
    $email =~ tr/[A-Z]/[a-z]/;

    You are replacing all the '[' characters with the '[' character and all the ']' characters with the ']' character. That should be:

    $email =~ tr/A-Z/a-z/;

    Or you could use the lc() function:

    $email = lc $email;
    ## Check email address if (($email ne "") && ($email !~ m/[\w]+@[\w]+\.[\w]+/))

    You have needlessly included a character class inside a character class.

    ## Check email address if ( $email ne "" && $email !~ /\w+@\w+\.\w+/ )
Re: sendmail working for me but not another
by bliako (Monsignor) on May 25, 2020 at 15:31 UTC

    The sendmail logs will reveal a lot of details, for sure, but this may give you some hints in case you can't find the logs: open (MAIL, "|$mailprog -t >> XXX 2>&1"); Replace XXX with a filepath residing in a dir your www-user can write to, perhaps /tmp/xyz.log (which will not survive a reboot).

    Add the empty line after headers as tobyink suggested. And also save the mail contents to local file for further debugging, with something like:

    my $fh; if( ! open($fh, '>>', 'XXX') ){ # log error } else { print $fh $email_message."\n-------------\n"; close $fh } $mailprog = '/usr/sbin/sendmail'; open (MAIL, "|$mailprog -t >> XXX 2>&1"); print MAIL $email_message; if( ! close (MAIL) ){ # replace this with your error-logging facility print "Content-type: text/html\n\n"; print "error, command failed with ".($?>>8)."<br>\n" print "message was:<br>\n${email_message}<br>\nEND message<br>\n"; } else { # EDIT: wrapped this in else! print "Location: application-submitted \n\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11117230]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-19 04:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found