Mail: the xmail family
A letter from construction to delivery and back: xmail lays the foundation (MIME parsing and building) while SMTP/POP3/IMAP field three clients that share transport and SASL.
Overview
build.bat xsmtp (or xpop3 / ximap — xmail comes along automatically). TCP/TLS discipline carries over from ch. 23/24; SASL credential discipline from ch. 44's trust layers.36.1 Family map
Four libraries divide the work: xmail (89 symbols) is the MIME base — codecs, charsets, address/date/parameter parsing, multipart, the message tree, builders, wire format (dot-stuffing) and the shared transport; xsmtp (44) / xpop3 (48) / ximap (102) are the three protocol clients. The registry's requires carries xmail with any protocol — and in combined builds xmail compiles exactly once.
36.2 The MIME layer
Shared by send and receive: xrtMailTreeParse parses raw mail into a limits-checked message tree (defending against malicious nesting), and the xrtMailBuilder family streams multipart construction. Codecs (QP/Base64), charset-to-UTF-8, and canonical formatting of addresses and dates are standalone functions — format conversion alone needs no protocol client.
36.3 Sending via SMTP
Session-style API: xrtSmtpClientOpen connects (plaintext/STARTTLS/SSL), Capabilities negotiates, Auth runs SASL, and Mail/Rcpt/Data or BDAT chunks deliver; the higher-level xrtSmtpSubmit posts a whole letter in one step. The command and reply parsers are exposed separately — test and gateway scenarios work offline.
36.4 POP3 / IMAP retrieval
POP3 is direct: Stat/List/Uidl take inventory, Retr/Top fetch (RetrTree returns the message tree directly). IMAP is full-featured: Select picks a mailbox, BeginSearch/BeginFetch stream retrieval, BeginStore edits flags, Append archives, BeginIdle waits for push, Compress compresses the session — the data-item parsers (imap_data) are independently testable.
36.5 Contract and choosing
| Concern | Key points |
|---|---|
| Ownership | client handles are library-allocated: Close disconnects, Destroy frees; parse results are borrowed views — copy before leaving the function |
| Credentials | SASL secrets go through env/Custom (ch. 44 discipline), never into source |
| Variants | three independently selectable protocols; scripts can probe at runtime with xsExtensionEnabled("xsmtp") |
| Choosing | poll-only retrieval: POP3; multi-box/search/flags/push: IMAP; sending: SMTP |
Common mistakes
- Symptom
- Storing the message tree pointer from Retr and touching it later crashes.
- Cause
- Protocol replies are borrowed views that die on the next exchange — copy anything you keep with the MIME layer's Write/Bytes family.
- Symptom
- Mail and credentials travel the network unencrypted.
- Cause
- Security mode unconfigured — production must use STARTTLS or SSL; the connection layer comes from xrt TLS with certificate verification on by default. Don't turn it off for convenience.
Exercises
Parse a multipart sample with the MIME layer, rebuild it with the Builder, and compare bytes.
Run an SMTP session against a local test server (or debug gateway), Submit a letter, fetch it back with POP3 Retr.
Wrap send/receive as HTTP routes (POST /mail/send, GET /mail/inbox), with IMAP Idle pushing over WS.
Summary
| Point | Conclusion |
|---|---|
| Structure | xmail base + three protocol clients; requires carries it automatically |
| MIME | limits-checked tree parsing + streaming Builder, usable standalone |
| Sending | session-style SMTP API + one-step Submit |
| Retrieval | POP3 polling / full-featured IMAP (search/flags/Idle/compress) |
| Discipline | views are borrow-only; credentials via env; TLS on by default |
- xrt · tls — the encryption base under mail transport