Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Socket SMTP email inappropriate i/o control operation

by $h4X4_|=73}{ (Monk)
on Aug 05, 2016 at 09:07 UTC ( [id://1169158]=perlquestion: print w/replies, xml ) Need Help??

$h4X4_|=73}{ has asked for the wisdom of the Perl Monks concerning the following question:

I'm getting an error when using the Socket SMTP part of this code (not the sendmail part) below on Windows 10 Perl 5.22 with taint mode on.
I would like to get the code working on windows and linux, but the first test on windows gave this error.
Sending Email: Sender address 'valid@email.was.used' not valid. inappropriate i/o control operation
What can be done to get this portable?

sub send_email { my ($self, %email_set) = @_; my ($x, $here, $there, $null) = ('', '', '', ''); # Format input. $email_set{to} =~ s/[ \t]+/, /g; $email_set{from} =~ s/.*<([^\s]*?)>/$1/; $email_set{message} =~ s/^\./\.\./gm; #$email_set{message} =~ s/\r\n/\n/g; #$email_set{message} =~ s/\n/\r\n/g; $cfg{smtp_server} =~ s/\A\s+|\s+\z//g; # Send email via SMTP. if ($cfg{mail_type} == 1) { ($x, $x, $x, $x, $here) = gethostbyname($null); ($x, $x, $x, $x, $there) = gethostbyname($cfg{smtp_server}); my $thisserver = pack('S n a4 x8', 2, 0, $here); my $remoteserver = pack('S n a4 x8', 2, 25, $there); use Carp; croak "Socket failure. $!" if (!(socket(S, 2, 1, 6))); croak "Bind failure. $!" if (!(bind(S, $thisserver))); croak "Connection to $cfg{smtp_server} has failed. $!" if (!(connect(S, $remoteserver))); my $oldfh = select(S); $| = 1; select($oldfh); $_ = <S>; croak "Sending Email: data in Connect error - 220. $!" if ($_ !~ /^220/); print S "HELO $cfg{smtp_server}\r\n"; $_ = <S>; croak "Sending Email: data in Connect error - 250. $!" if ($_ !~ /^250/); print S "MAIL FROM:<$email_set{from}>\n"; $_ = <S>; croak "Sending Email: Sender address '$email_set{from}' not valid. $ +!" if ($_ !~ /^250/); print S "RCPT TO:<$email_set{to}>\n"; $_ = <S>; croak "Sending Email: Recipient address '$email_set{to}' not valid. +$!" if ($_ !~ /^250/); print S "DATA\n"; $_ = <S>; croak "Sending Email: Message send failed - 354. $!" if ($_ !~ /^354/); } # Send email via sendmail. $ENV{PATH} = ''; if ($cfg{mail_type} == 0) { open S, "| $cfg{mail_program} -t" or croak "Mailprogram error. at $! +"; print S <<THE_EMAIL; From: $email_set{from} Subject: $email_set{subject} To: $email_set{to} X-Mailer: Flex-WPS Mail_Module v1.0 Content-type: text/plain $email_set{message} THE_EMAIL } # Send email via SMTP. if ($cfg{mail_type} == 1) { $_ = <S>; croak "Sending Email: Message send failed - try again - 250. $!" if ($_ !~ /^250/); print S "QUIT\n"; } close(S); return 1; }

Replies are listed 'Best First'.
Re: Socket SMTP email inappropriate i/o control operation
by Corion (Patriarch) on Aug 05, 2016 at 09:30 UTC

    You haven't binmode'd your socket, so I wonder how this works under Unix, and on Windows instead of sending \n you'll send \r\n to the socket.

    For better debugging, consider printing the server answer in $_.

    Have you considered simply using MIME::Lite instead? It works on Windows and systems with sendmail available and has been tested.

      The value of $_ is 421 4.4.2 service timed out.
      I tried binmode in many places on S and STDOUT, but maybe I didn't use it correctly.
      I thought it maybe windows firewall so I turned that off, but it still does the same thing.
      The better/faster way would be to use a module, so I will probably do that when I have more time to play with it.

Re: Socket SMTP email inappropriate i/o control operation
by Mr. Muskrat (Canon) on Aug 05, 2016 at 14:00 UTC

    Unrelated to your question but ($x, $x, $x, $x, $here) = gethostbyname($null); can be written (undef, undef, undef, undef, $here) = gethostbyname($null);.

      yes and it can also be written like this.
      ($here) = (gethostbyname($null))[4];

        Parentheses on the LHS not needed. (And around $null either.)
        $here = (gethostbyname $null)[4];

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Socket SMTP email inappropriate i/o control operation
by $h4X4_&#124;=73}{ (Monk) on Aug 05, 2016 at 19:46 UTC

    I got the SMTP part to work with the code below.
    Corion said to use binmode with \r\n, but I'm not sure if Socket is doing it. Because it seems to work with and without binmode now.
    Update: FYI: The code below needs you to have a tab \t in the start of the message for it to work.

    sub send_email { my ($self, %email_set) = @_; # Format input. $email_set{to} =~ s/[ \t]+/, /g; $email_set{from} =~ s/.*<([^\s]*?)>/$1/; $email_set{message} =~ s/^\./\.\./gm; $email_set{message} =~ s/\r\n/\n/g; $email_set{message} =~ s/\n/\r\n/g; $cfg{smtp_server} =~ s/\A\s+|\s+\z//g; # Send email via SMTP. if ($cfg{mail_type} == 1) { use Carp; use Socket; my $proto = getprotobyname('tcp') || 6; my $port = getservbyname('SMTP', 'tcp') || 25; my $remoteserver = inet_aton($cfg{smtp_server}) or croak 'Unable to resolve hostname : '.$cfg{smtp_server}; croak 'Socket failure. '.$! if (! socket(S, AF_INET, SOCK_STREAM, $p +roto)); croak 'Bind failure. '.$! if (! bind(S, sockaddr_in(0, INADDR_ANY))) +; croak 'Connection to '.$cfg{smtp_server}.' has failed. '.$! if (! connect(S, sockaddr_in($port, $remoteserver))); my $oldfh = select(S); $| = 1; select($oldfh); $_ = <S>; croak "Sending Email: data in Connect error - 220. $_ $!" if ($_ !~ /^220/); print S "HELO $cfg{smtp_server}\r\n"; $_ = <S>; croak "Sending Email: data in Connect error - 250. $_ $!" if ($_ !~ /^250/); print S "MAIL FROM:<$email_set{from}>\r\n"; $_ = <S>; croak "Sending Email: Sender address '$email_set{from}' not valid. $ +_ $!" if ($_ !~ /^250/); print S "RCPT TO: <$email_set{to}>\r\n"; $_ = <S>; croak "Sending Email: Recipient address '$email_set{to}' not valid. +$_ $!" if ($_ !~ /^250/); print S "DATA\r\n"; $_ = <S>; croak "Sending Email: Message send failed - 354. $_ $!" if ($_ !~ /^354/); } # Send email via sendmail. $ENV{PATH} = ''; if ($cfg{mail_type} == 0) { open S, '| '.$cfg{mail_program}.' -t' or croak 'Mailprogram error. a +t '.$!; } print S "To: $email_set{to}\r\n"; print S "From: $email_set{from}\r\n"; print S "Subject: $email_set{subject}\r\n"; print S "$email_set{message}"; print S "\r\n.\r\n"; # Send email via SMTP. if ($cfg{mail_type} == 1) { $_ = <S>; croak "Sending Email: Message send failed - try again - 250. $_ $!" if ($_ !~ /^250/); print S "QUIT\r\n"; } close(S); return 1; }

Re: Socket SMTP email inappropriate i/o control operation
by Anonymous Monk on Aug 05, 2016 at 09:11 UTC
    ? What is the contents of $_
      as readline teaches, $! is only significant if readline returned undef , if $_ is undef

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-03-29 12:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found