user3160199
user3160199

Reputation: 35

Telnet smtp command bash 2.05 script problem

Line by line works but in script it does not.

I tried everything i could think of.

This does not work in bash 2.05

  { sleep 1; echo "helo localhost"; sleep 1; echo "mail from: [email protected]"; sleep 1; echo "rcpt to: [email protected]"; sleep 1; echo "data"; sleep 1; echo "subject: test"; echo; echo "some text" ;echo "."; echo "quit"; } | telnet mailserver.actualdomain.org 25

but if you do line by line

telnet mailserver.actualdomain.org 25
220...
helo localhost
250...ok
mail from: [email protected]
250..ok
rcpt to: [email protected]
250...ok
data
354 Start mail input; end with <CRLF>.<CRLF>
subject: test

some text
.
quit

then it works and i get mail. the script works in newer bash 4.4 but i need it to work in 2.05. seems to me that it does not do echo "." et the end and does not finish mail...and therefore does not send it. but why???

I expect it to send mail but it does not

Upvotes: 2

Views: 962

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295618

This is probably a difference in the version of telnet, not the version of bash.

One common problem when using network tools in a pipeline like this is how they handle EOFs on stdin. What you need is behavior like this:

  • Your input is written to telnet's stdin
  • ...while this is happening, telnet starts sending that input to the remote server...
  • Telnet's stdin is given an EOF (end-of-file). Some broken versions of telnet exit immediately at this point.
  • ...telnet keeps sending everything it read from its stdin over to the remote server.
  • ...telnet finishes sending everything it read to the remote server, and then closes the sending side of the socket (via a FIN packet)
  • ...the server keeps sending content to the client until it's sent any responses that need to be done, and then the server closes its own side by sending another FIN
  • telnet prints everything it got prior to getting a FIN from the server. Completion of this step is when a correctly-written telnet actually exits.

As noted above, many versions of telnet that actually exist were written assuming they would be used by humans, not scripts. Instead of sending buffered content over the wire on receiving an EOF, and waiting to receive any responses from the server before shutting down the receive side, they just quit immediately the moment an EOF is seen.


You can work around it by adding a delay at the end.

It's an ugly hack, and better replaced with using tools that know how to shut down a socket correctly, but the cheap-and-dirty approach looks something like this:

{ ...; echo "."; echo "quit"; sleep 2; } | telnet mailserver.actualdomain.org 25

For new development, consider using a built-to-purpose tool like socat, or one of the many implementations of netcat.

socat's documented behavior explicitly makes it wait to finish sending content it received on its stdin, and printing responses it received over the socket, before exiting; insofar as it has a timeout on how long it waits for responses from the server, that timeout can be explicitly configured.

Upvotes: 3

Anuradha Fernando
Anuradha Fernando

Reputation: 1157

Agree with Charles, this must be a different version of telnet. And a few thoughts,

  1. You can simply use expect and send commands to automate the telnet command,
#!/user/bin/expect
spawn telnet localhost 25 <<EOF
hello localhost
mail from: local@localhost
rcpet to: user@localhost
data
Some data
.
EOF

Or,

  1. create a text file with the mail commands and use netcat (if the telnet doesn't support for stream input)

cat mailCmd.txt | nc localhost 25

  1. The best and reliable way is to use a utility like socat or sendmail

sendmail user@localhost < "Emailcontent.txt"

Upvotes: 0

Related Questions