Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

gawk smtp

Status
Not open for further replies.

codemut

Programmer
Feb 29, 2008
26
US
Here's a quiz...

How to use smtp with gawk. What works on the bash command line is not working in an awk script. Consider the following code:

BEGIN {
RS = ORS = "\r\n"
to = "name@server.com"
from = "name2@server.com"
text = "testing1...testing2...testing3..."
subject = "testing 1...2...3"
smtp = "mail.server.com"
connection = "/inet/tcp/0/"smtp"/25"

print "HELO "smtp |& connection; connection |& getline
print "MAIL FROM:<"from">" |& connection; connection |& getline
print "RCPT TO:<"to">" |& connection; connection |& getline
print "DATA" |& connection; connection |& getline
print "Subject: "subject"\n"text |& connection; connection |& getline
print "." |& smtp; connection |& getline
print "QUIT" |& connection; connection |& getline
close(connection);
}

The fix might be to correct the read of server messages after each print with the two-way pipe ability of |&
 
As far as I can tell (and I haven't used it much), |& is for communicating with a co-process. In your example connection is not a process (or command), but just the file itself.

I think the solution is simpler than what you're trying to do, i.e.:

Code:
   print "HELO "smtp > connection
   getline smtpoutput < connection
   print smtpoutput

Annihilannic.
 
Hi

Annihilannic said:
In your example connection is not a process (or command), but just the file itself.
Nope. It is a socket. For example this will get the Tek-Tips main page :
Code:
[red]BEGIN[/red] [teal]{[/teal]
  host[teal]=[/teal][green][i]"tek-tips.com"[/i][/green]
  c[teal]=[/teal][green][i]"/inet/tcp/0/"[/i][/green] host [green][i]"/80"[/i][/green]
  [COLOR=chocolate]print[/color] [green][i]"GET / HTTP/1.0[/i][/green][lime][i]\n[/i][/lime][green][i]Host: "[/i][/green] host [green][i]"[/i][/green][lime][i]\n[/i][/lime][green][i]"[/i][/green] [teal]|&[/teal] c
  [b]while[/b] [teal]([/teal]c [teal]|&[/teal] [COLOR=chocolate]getline[/color] str[teal])[/teal] [COLOR=chocolate]print[/color] [COLOR=chocolate]gensub[/color][teal](/<[^<>]+>/,[/teal][green][i]""[/i][/green][teal],[/teal][green][i]"g"[/i][/green][teal],[/teal]str[teal])[/teal]
[teal]}[/teal]
zedlan, I would not suppose that all SMTP servers will send exactly one line of response after each received line. So I would enclose those [tt]connection |& getline[/tt] commands in [tt]while[/tt] loops to ensure they can be executed zero or more times if needed.

Feherke.
 
Yep, I realise it is a socket... but "everything in Unix is a file" as the saying goes, so what I was saying was that it behaves the same way as a file, not the same way as a process.

Annihilannic.
 
Hi

Well, my example certainly works with co-process piping ( [tt]|&[/tt] ) and certainly not works with redirecting ( [tt]<[/tt] [tt]>[/tt] ). So I would say, socket communications are like inter-process communications, at least in [tt]gawk[/tt]. And zedlan's original code seems to be correct, just naive because assumes fixed amount of response.

Feherke.
 
A print statement was added to view server info. The "print "HELO ..." statement yields the server's 1st msg: "220 mail.server.com ESMTP" ... then the script hangs w/out any further output (even with the above code suggestions).

Maybe fflush() or close() is in order... but how to do w/out disconnecting? Maybe a "wait" command like w/ bash?

By the way, a typo was fixed -- line 15 should have read: "print "." |& connection ...".

With http there are no such difficulties. For smtp, server interaction seems a puzzle.
 
I sit corrected... however still confused because the gawk man page clearly says that "c" should be a command rather than a file/pipe/socket:

man gawk said:
command |& getline [var]
Run command as a co-process piping the output
either into $0 or var, as above. Co-processes
are a gawk extension.

It would make more sense to me if "c" was defined to be something like "cat <> /inet/tcp/0/" host "/80", for example.

Anyway... if zedlan were to use a while loop as you suggested, wouldn't it just wait indefinitely until the connection is closed? I don't think getline will return false just because there is no further input available right now.

zedlan, I just ran your original code on a HP-UX 11.11 system with sendmail 8.9.3 and it worked perfectly, mail received. What OS and MTA are trying with?


Annihilannic.
 
Hi

Annihilannic said:
Anyway... if zedlan were to use a while loop as you suggested, wouldn't it just wait indefinitely until the connection is closed?
Is your turn to be right. Indeed, that will not work. Sorry, it seemed that I did it like that some years ago.


Feherke.
 
Annihilannic,

The systems are freeBSD w/sendmail and openSuse w/postfix.

However, given the new service of connection = "/inet/tcp/0/"smtp"/25", is the local mta relevant?

A successful local test makes it all the more puzzling since the same parameters work via command line/telnet to the remote host. There are no clues in the mail logs.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top