Minimal Erlang SMTP, POP3 server code

This page is a mirrored copy of an article originally posted on the LShift blog; see the archive index here.

Some seven months ago, I built simple Erlang modules for generic SMTP and POP3 services. The idea is that the programmer should instantiate a service, providing callbacks for user authentication and for service-specific operations like handling deliveries, and scanning and locking mailboxes. Originally, I was planning on providing SMTP-to-AMQP and AMQP-to-POP3 gateways as part of RabbitMQ, but I haven’t had the time to seriously pursue this yet.

A snapshot of the code is available as a zip file (Update: quite outdated now! See github for the latest code), or you can browse the code online or retrieve it using git:

git clone git://github.com/tonyg/erlang-smtp

The current status of the code is:

  • SMTP deliveries from Thunderbird work
  • POP3 retrieval from Thunderbird works, but isn’t very solid, because I haven’t implemented the stateful part of mailboxes yet.
  • The SMTP implementation is somewhat loosely based on RFC 2821. It’s what you might generously call minimally conformant (improving this situation is tedious but not difficult). It doesn’t address RFC 2822 in any serious way (yet)
  • The POP3 implementation is based on RFC 1939.
  • SMTP AUTH is not yet implemented (but is not difficult)
  • I can’t recall the details (seven months!), but I think I might have skimped on something relating to POP3 UIDL.
  • Neither module has pluggable callbacks: the SMTP delivery-handler is currently io:format, and the POP3 mailbox and user authentication database are similarly hard-coded.

Patches, bugfixes, contributions, comments and feedback are all very welcome!

Update: a new post summarises changes since this post, including pluggable callbacks etc.