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

I'd like to create a very simple and minimal SMTP server whose only purpose is to log the recipient's email address and the timestamp. That's all! I don't want to use any existing modules. I just want a simple and "raw" way of listening to port 25 and logging all incoming emails.

Does anyone have any ideas on how to get started?

Thank You,

andy

Replies are listed 'Best First'.
Re: SMTP logging server
by cianoz (Friar) on Oct 19, 2000 at 03:14 UTC
    Update! i've just found a "NetServer::SMTP" on CPAN
    maybe this is more usefull than my piece of crap i've just posted.. :)
      thanx

      i'll install NetServer::Generic and try your script out... Although, i'd rather not install the module on other machines.

      thanx a lot

Re: SMTP logging server
by cianoz (Friar) on Oct 19, 2000 at 02:12 UTC
    you should implement a bare bone SMTP server (simple but not trivial... it should understand at least some basic commands - HELO and so on, maybe you can skip ETRN :-) )
    have a look at NetServer::Generic for a very simple way of implementing a TCP sever..

    Update just a question: do you whant to reject or discard incoming mail?

      no, i don't care to reject any mail. I just want to log the addressee and the timestamp. All I really want to do is test another SMTP server ( a real one) by sending test messages to an "email sink" whose only job is logging. Therefore, I want something light and independent--and as simple as possible.

      Do you think I should use forking and/or threading? (I though threads did not work properly in perl). Also, it would be nice if this SMTP daemon could be run on linux AND Windows. I though Perl would be the perfect choice for such a simple endeavor (I just need to figure out how SMPT works).

      Thanx

        i wrote this in 10 minutes
        (here in italy is night and i've got a good bottle of wine in front of me ;)))
        stupid as you whant but fools netscape messanger :)
        I used NetServer::Generic since is too late for me to mess with sockets...
        #!/usr/bin/perl -w use strict; use NetServer::Generic; my $server = new NetServer::Generic; $server->port(25); $server->callback(\&server); $server->timeout(25); ## random... $server->run(); sub server { open LOG, ">>/tmp/smtpd.log" || die "cannot open: $!"; print LOG "\nNew connection\n-------------\n"; print "220 mydomail.com ESMTP CianozMail 0.1 :)\n"; while(<STDIN>) { print LOG "$_"; if($_ =~ /^quit\r\n/i ) { print "221 Bye\n"; close LOG; return; } elsif($_ =~ /^data/i ) { ## read message body here... print "354 End data with <CR><LF>.<CR><LF>\n"; MESSAGE: while(my $line = <STDIN>) { if($line =~ /^\.\r\n/) { print "250 Ok: queued as ....\n"; last MESSAGE; } else { print LOG "$line"; } } } else { print "250 Ok\n"; #who cares? :-) } } }
Re: SMTP logging server
by merlyn (Sage) on Oct 19, 2000 at 02:18 UTC
    You can get started by rethinking your choice to not use modules. {grin} There's a few good generic server modules out there, such as: that would keep you from the drudgery of handling some of the low-level bookkeeping. Check those out first, or at least steal ideas from them.

    Unless you bail quickly, you'll need to either fork, pre-fork, or somehow "little t" thread or "big T" Thread to talk to all the conversations. And doing SMTP is not trivial. I've wanted to do a generic server-side comparable to what Net::Cmd did for client-side for a long time, and that would have helped you. Sorry, still on that overly-long todo list. {grin}

    -- Randal L. Schwartz, Perl hacker

Re: SMTP logging server
by elwarren (Priest) on Oct 19, 2000 at 22:34 UTC
    I know it's not the exact answer you were looking for, but your typical sendmail logfile contains all the info you're asking for, without tweaking. It would be much easier to write a quick script to parse the logfile instead of writing a server. I've seen a few scripts floating around, a few of them are registered on perl.com