diff --git a/doc/latex/smtp.tex b/doc/latex/smtp.tex index 96d4307..d93de4e 100644 --- a/doc/latex/smtp.tex +++ b/doc/latex/smtp.tex @@ -5,4 +5,370 @@ \item[Name of the package:] smtp \end{description} % -Not implemented yet. + +\subsection{Philosophy} +SMTP protocol procedures tend to return two values: +\begin{description} +\item{\semvar{code}} The integer SMTP reply code returned by server for the transaction. +\item{\semvar{text}} A list of strings -- the text messages tagged by + the code. +\end{description} + +The text strings have the initial code numerals and the terminating +\ex{CR}/\ex{LF}'s stripped. Codes in the range $[1,399]$ are sucess +codes; codes in the range $[400,599]$ are error codes; codes $>= 600$ +are not part of the official SMTP spec. This module uses codes $>= +600$ to indicate extra-protocol errors. There are two of these: + +\begin{description} +\item{600 Server reply could not be parsed.} + The server sent back some sort of incomprehensible garbage reply. +\item{621 Premature EOF while reading server reply.} + The server shut down in the middle of a reply. +\end{description} + +A list of the official protocol return codes can be seen in table +\ref{smtp-reply-codes}. + +\subsection{Procedures} + +\begin{defundesc}{sendmail}{to-list body \ovar{host}}{code text-list} + Mail message \semvar{body} to recipients in list \semvar{to-list}. + Message handed off to server running on \semvar{host}; default is + the local host. Returns two values: \semvar{code} and + \semvar{text-list}, i.e. the code returned by the server and the + text-message, seperated by lines. However, if some recipients were + rejected, sendmail sends to the rest of the recipients, and the + partial-success return is [700 \semvar{loser-alist}] where + \semvar{loser-alist} is a list whose elements are of the form + \ex{(\semvar{loser-recipient} \semvar{code} . \semvar{text})} -- + that is, for each recipient refused by the server, you get the error + data sent back for that guy. The success check is \ex{(< code 400)}. +\end{defundesc} + +\begin{defundesc}{\%sendmail}{from local-host to dest-host + message}{code text} Mail \semvar{message} to recipient \semvar{to} + using \semvar{dest-host}, telling \semvar{from} as your mail-address + and \semvar{local-host} as your system-name. +\end{defundesc} + + +\defun{expn}{name host}{code text} +\defunx{vrfy}{name host}{code text} +\defunx{mail-help}{host \ovar{details}}{code text-list} +\begin{desc} + These three are simple queries of the server as stated in the + RFC~821: \ex{expn} asks the server to confirm that the argument + identifies a mailing list, and if so, to return the membership of + that list. The full name of the users (if known) and the fully + specified mailboxes are returned in a multiline reply. \ex{vrfy} + asks the receiver to confirm that the argument identifies a user. + If it is a user name, the full name of the user (if known) and the + fully specified mailbox are returned. \ex{mail-help} causes the + server to send helpful information. The command may take an argument + (\semvar{details}) (e.g., any command name) and return more specific + information as a response. +\end{desc} + + +\dfn{smtp-transactions}{socket ?transaction1 ...}{code + text-list}{syntax} +\dfnx{smtp-transactions/no-close}{socket ?transaction1 ...}{code + text-list}{syntax} +\begin{desc} + These macros make it easy to do simple sequences of SMTP commands. + + Evaluate a series of expressions \semvar{?transaction1}, + \semvar{?transaction2}, \ldots + \begin{itemize} + \item Each expression should perform an SMTP transaction, and return + two values: \semvar{code} (the integer reply code) and \semvar{text} + (list of strings that came with the reply). + \item If the transaction's reply code is 221 or 421 (meaning the + socket has been closed), then the transaction sequence is is + aborted, and the \ex{smtp\=trans\ob{}actions} form returns the + \semvar{code} and \semvar{text} values for the current transaction. + \item If the reply code is an error code (in the four- or five-hundred + range), the transaction sequence is aborted, and the fatal + transaction's \semvar{code} and \semvar{text} values are returned. + \ex{smtp\=trans\ob{}actions} will additionally close the socket for + you; \ex{smtp-trans\ob{}actions/\ob{}no\=close} will not. + \item If the transaction is the last in the transaction sequence, its + \semvar{code} and \semvar{text} values are returned. + \item Otherwise, we throw away the current \semvar{code} and + \semvar{text} values, and proceed to the next transaction. + \end{itemize} + + Since \ex{smtp-trans\ob{}actions} closes the socket whenever it + aborts a sequence, an \ex{smtp-trans\ob{}actions} form terminated + with an \ex{(smtp/\ob{}quit socket)} transaction will always close + the socket. + + If the socket should be kept open in the case of an abort, use + \ex{smtp-trans\ob{}actions/\ob{}no\=close}. + + We abort sequences if a transaction results in a 400-class error code. + So, a sequence mailing a message to five people, with 5 RCPT's, would + abort if the mailing address for one of these people was wrong, rather + than proceeding to mail the other four. This may not be what you want; + if so, you'll have to roll your own. +\end{desc} + +\defun{smtp/open}{host \ovar{maybe-port}}{socket} +\defunx{smtp/helo}{local-host-name}{code text-list} +\defunx{smtp/mail}{sender-address}{code text-list} +\defunx{smtp/rcpt}{destination-address}{code text-list} +\defunx{smtp/data}{socket message}{code text-list} +\defunx{smtp/send}{sender-address}{code text-list} +\defunx{smtp/soml}{sender-address}{code text-list} +\defunx{smtp/saml}{sender-address}{code text-list} +\defunx{smtp/rset}{}{code text-list} +\defunx{smtp/vrfy}{user}{code text-list} +\defunx{smtp/expn}{user}{code text-list} +\defunx{smtp/help}{details}{code text-list} +\defunx{smtp/noop}{}{code text-list} +\defunx{smtp/quit}{socket}{code text-list} +\defunx{smtp/turn}{}{code text-list} +\begin{desc} + These functions implement the basics of the protocol, i.e. they send + the corresponding command along with the argument(s), if any. A + short look to the code of \ex{\%sendmail} will give you the basics + on how to use the commands. You will obtain further informations in + the RFC~821. \semvar{host}, \semvar{local-host}, + \semvar{sender-address}, \semvar{destination-address}, \semvar{user} + and \semvar{details} are strings, \semvar{message} may be a string + or an input-port. \semvar{socket} is a socket, mostly one returned + by \ex{smtp/\ob{}open}. +\end{desc} + +\begin{defundesc}{handle-smtp-reply}{socket}{code text-list} + Read and handle the reply. Return an integer (the reply + \semvar{code}), and a list of the text lines (\semvar{text-list}) + that came tagged by the reply code. The text lines have the + reply-code prefix (first 4 chars) and the terminating cr/lf's + stripped. +\end{defundesc} + +\begin{defundesc}{read-smtp-reply}{port}{code text-list} + Read a reply from the SMTP server. Returns two values: + \begin{description} + \item{\semvar{code}} Integer. The reply code. + \item{\semvar{text}} String list. A list of the text lines comprising + the reply. Each line of text is stripped of the initial + reply-code numerals (e.g., the first four chars of the reply), + and the trailing cr/lf. We are in fact generous about what we + take to be a line -- the protocol requires cr/lf terminators, but + we'll accept just lf. This appears to true to the spirit of the + "be strict in what you send, and generous in what you accept" + Internet protocol philosphy. + \end{description} +\end{defundesc} + +\begin{defundesc}{parse-smtp-reply}{line}{code rest more?} + Parse a line of SMTP reply. Return three values: + \begin{description} + \item{\semvar{code}} integer -- the reply code that prefixes the + string. + \item{\semvar{rest}} string -- the rest of the line. + \item{\semvar{more?}} boolean -- is there more reply to read (i.e., + was the numeric reply code terminated by a ``\ex{-}'' character?) + \end{description} +\end{defundesc} + +\begin{defundesc}{smtp-stuff}{text pchar}{stuffed-string last-char} + The message body of a piece of email is terminated by the sequence + \ex{ }, i.e. end-of-line, period, + end-of-line. If the message body contains this magic sequence, it + has to be escaped. We do this by mapping the sequence \ex{ + } to \ex{ }; the SMTP receiver undoes + this mapping. + + \semvar{text} is a string to stuff, \semvar{pchar} was the character + read just before \semvar{text} (which matters if it is a line-feed). + If \semvar{text} is the first chunk of the entire msg, then + \semvar{pchar} can be \sharpf. Return two values: the + \semvar{stuffed-string}, and the last char in \semvar{text} (or + \semvar{pchar} if \semvar{text} is empty). The last-char value + returned can be used as the \semvar{pchar} arg for the following + call to \ex{smtp\=stuff}. +\end{defundesc} + +\subsection{Additional information about SMTP} + +\subsubsection*{Reply codes} + +This material is taken from the RFC. The first digits encode categories +of responses: +\begin{description} +\item{\bfseries 1yz Positive Preliminary reply\,} The command has been + accepted, but the requested action is being held in abeyance, + pending confirmation of the information in this reply. The + sender-SMTP should send another command specifying whether to + continue or abort the action. +\begin{leftinset} + Note: SMTP does not have any commands that allow this type of reply, + and so does not have the continue or abort commands. +\end{leftinset} +\item{\bfseries 2yz Positive Completion reply\,} The requested action has + been successfully completed. A new request may be initiated. +\item{\bfseries 3yz Positive Intermediate reply\,} The command has been + accepted, but the requested action is being held in abeyance, + pending receipt of further information. The sender-SMTP should send + another command specifying this information. This reply is used in + command sequence groups. +\item{\bfseries 4yz Transient Negative Completion reply\,} The command was + not accepted and the requested action did not occur. However, the + error condition is temporary and the action may be requested again. + The sender should return to the beginning of the command sequence + (if any). It is difficult to assign a meaning to ``transient'' when + two different sites (receiver- and sender- SMTPs) must agree on the + interpretation. Each reply in this category might have a different + time value, but the sender-SMTP is encouraged to try again. A rule + of thumb to determine if a reply fits into the 4yz or the 5yz + category (see below) is that replies are 4yz if they can be repeated + without any change in command form or in properties of the sender or + receiver. (E.g., the command is repeated identically and the + receiver does not put up a new implementation.) +\item{\bfseries 5yz Permanent Negative Completion reply\,} The command was + not accepted and the requested action did not occur. The + sender-SMTP is discouraged from repeating the exact request (in the + same sequence). Even some ``permanent'' error conditions can be + corrected, so the human user may want to direct the sender-SMTP to + reinitiate the command sequence by direct action at some point in + the future (e.g., after the spelling has been changed, or the user + has altered the account status). +\end{description} + +The second digit encodes responses in specific categories: +\begin{description} +\item{\bfseries x0z Syntax\,} These replies refer to syntax errors, + syntactically correct commands that don't fit any functional + category, and unimplemented or superfluous commands. +\item{\bfseries x1z Information\,} These are replies to requests for + information, such as status or help. +\item{\bfseries x2z Connections\,} These are replies referring to the + transmission channel. +\item{\bfseries x3z\,} Unspecified as yet. +\item{\bfseries x4z\,} Unspecified as yet. +\item{\bfseries x5z Mail system\,} These replies indicate the status of the + receiver mail system vis-a-vis the requested transfer or other mail + system action. +\end{description} + +\begin{table} +\label{smtp-reply-codes} +\begin{tabular}{|lp{10cm}|} +\hline + 500 & Syntax error, command unrecognized \newline + [This may include errors such as command line too long] \\ + 501 & Syntax error in parameters or arguments \\ + 502 & Command not implemented\\ + 503 & Bad sequence of commands\\ + 504 & Command parameter not implemented\\ +\hline + 211 & System status, or system help reply\\ + 214 & Help message \newline + [Information on how to use the receiver or the meaning of a + particular non-standard command; this reply is useful only + to the human user]\\ +\hline + 220 & \semvar{domain} Service ready \\ + 221 & \semvar{domain} Service closing transmission channel\\ + 421 & \semvar{domain} Service not available, + closing transmission channel\newline + [This may be a reply to any command if the service knows it + must shut down]\\ +\hline + 250 & Requested mail action okay, completed\\ + 251 & User not local; will forward to \semvar{forward-path}\\ + 450 & Requested mail action not taken: mailbox unavailable + [E.g., mailbox busy]\\ + 550 & Requested action not taken: mailbox unavailable + [E.g., mailbox not found, no access]\\ + 451 & Requested action aborted: error in processing\\ + 551 & User not local; please try \semvar{forward-path}\\ + 452 & Requested action not taken: insufficient system storage\\ + 552 & Requested mail action aborted: exceeded storage allocation\\ + 553 & Requested action not taken: mailbox name not allowed + [E.g., mailbox syntax incorrect]\\ + 354 & Start mail input; end with \ex{CRLF}.\ex{CRLF}\\ + 554 & Transaction failed\\ +\hline +\end{tabular} +\caption{Complete list of SMPT reply-codes.} +\end{table} + +\begin{table} +\label{smtp-command-reply-codes} +\begin{tabular}{|p{2.3cm}||p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|} +\hline +\bf{What} & \bf{intermediate} & \bf{success} & \bf{failure} & \bf{error}\\ +\hline +\hline +conn. establ. & & + 220 & + 421 &\\ + HELO & & + 250 & & + 500, 501, 504, 421\\ + MAIL & & + 250 & + 552, 451, 452 & + 500, 501, 421\\ + RCPT & & + 250, 251 & + 550, 551, 552, 553, 450, 451, 452 & + 500, 501, 503, 421\\ + DATA & + 354 \verb|->| data & + 250 & + 552, 554, 451, 452 & \\ & otherwise & & + 451, 554 & + 500, 501, 503, 421\\ + RSET & & + 250 & & + 500, 501, 504, 421\\ + SEND & & + 250 & + 552, 451, 452 & + 500, 501, 502, 421\\ + SOML & & + 250 & + 552, 451, 452 & + 500, 501, 502, 421\\ + SAML & & + 250 & + 552, 451, 452 & + 500, 501, 502, 421\\ + VRFY & & + 250, 251 & + 550, 551, 553 & + 500, 501, 502, 504, 421\\ + EXPN & & + 250 & + 550 & + 500, 501, 502, 504, 421\\ + HELP & & + 211, 214 & & + 500, 501, 502, 504, 421\\ + NOOP & & + 250 & & + 500, 421\\ + QUIT & & + 221 & & + 500\\ + TURN & & + 250 & + 502 & + 500, 503\\ +\hline +\end{tabular} +\caption{command--reply sequences.} +\end{table} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: