| Copyright | (c) 2013 Peter Simons |
|---|---|
| License | BSD3 |
| Maintainer | simons@cryp.to |
| Stability | provisional |
| Portability | portable |
| Safe Haskell | Safe |
| Language | Haskell98 |
Text.ParserCombinators.Parsec.Rfc2821
Contents
Description
This module exports parser combinators for the grammar described in RFC2821, "Simple Mail Transfer Protocol", http://www.faqs.org/rfcs/rfc2821.html.
- data SessionState
- data Event
- = Greeting
- | SayHelo String
- | SayHeloAgain String
- | SayEhlo String
- | SayEhloAgain String
- | SetMailFrom Mailbox
- | AddRcptTo Mailbox
- | StartData
- | Deliver
- | NeedHeloFirst
- | NeedMailFromFirst
- | NeedRcptToFirst
- | NotImplemened
- | ResetState
- | SayOK
- | SeeksHelp String
- | Shutdown
- | SyntaxErrorIn String
- | Unrecognized String
- type SmtpdFSM = State SessionState Event
- smtpdFSM :: String -> SmtpdFSM
- handleSmtpCmd :: SmtpCmd -> SmtpdFSM
- data SmtpCmd
- data Mailbox = Mailbox [String] String String
- nullPath :: Mailbox
- postmaster :: Mailbox
- data SmtpReply = Reply SmtpCode [String]
- data SmtpCode = Code SuccessCode Category Int
- data SuccessCode
- data Category
- reply :: Int -> Int -> Int -> [String] -> SmtpReply
- isSuccess :: SmtpReply -> Bool
- isFailure :: SmtpReply -> Bool
- isShutdown :: SmtpReply -> Bool
- type SmtpParser st = CharParser st SmtpCmd
- smtpCmd :: SmtpParser st
- smtpData :: SmtpParser st
- rset :: SmtpParser st
- quit :: SmtpParser st
- turn :: SmtpParser st
- helo :: SmtpParser st
- ehlo :: SmtpParser st
- mail :: SmtpParser st
- rcpt :: SmtpParser st
- send :: SmtpParser st
- soml :: SmtpParser st
- saml :: SmtpParser st
- vrfy :: SmtpParser st
- expn :: SmtpParser st
- help :: SmtpParser st
- noop :: SmtpParser st
- from_path :: CharParser st Mailbox
- to_path :: CharParser st Mailbox
- path :: CharParser st Mailbox
- mailbox :: CharParser st Mailbox
- local_part :: CharParser st String
- domain :: CharParser st String
- a_d_l :: CharParser st [String]
- at_domain :: CharParser st String
- address_literal :: CharParser st String
- ipv4_literal :: CharParser st String
- ipv4addr :: CharParser st String
- subdomain :: CharParser st String
- dot_string :: CharParser st String
- atom :: CharParser a String
- snum :: CharParser st String
- number :: CharParser st String
- word :: CharParser st String
- fixCRLF :: String -> String
- mkCmd0 :: String -> a -> CharParser st a
- mkCmd1 :: String -> (a -> SmtpCmd) -> CharParser st a -> CharParser st SmtpCmd
- tokenList :: CharParser st String -> Char -> CharParser st String
ESMTP State Machine
data SessionState Source
Constructors
| Unknown | |
| HaveHelo | |
| HaveMailFrom | |
| HaveRcptTo | |
| HaveData | |
| HaveQuit |
Constructors
| Greeting | reserved for the user |
| SayHelo String | |
| SayHeloAgain String | |
| SayEhlo String | |
| SayEhloAgain String | |
| SetMailFrom Mailbox | |
| AddRcptTo Mailbox | |
| StartData | |
| Deliver | reserved for the user |
| NeedHeloFirst | |
| NeedMailFromFirst | |
| NeedRcptToFirst | |
| NotImplemened | |
| ResetState | |
| SayOK | Triggered in case of |
| SeeksHelp String | The parameter may be |
| Shutdown | |
| SyntaxErrorIn String | |
| Unrecognized String |
type SmtpdFSM = State SessionState Event Source
smtpdFSM :: String -> SmtpdFSM Source
Parse a line of SMTP dialogue and run handleSmtpCmd to
determine the Event. In case of syntax errors,
SyntaxErrorIn or Unrecognized will be returned.
Inputs must be terminated with crlf. See fixCRLF.
handleSmtpCmd :: SmtpCmd -> SmtpdFSM Source
Data Types for SMTP Commands
The smtpCmd parser will create this data type from a
string. Note that all command parsers expect their
input to be terminated with crlf.
Constructors
| Helo String | |
| Ehlo String | |
| MailFrom Mailbox | Might be |
| RcptTo Mailbox | Might be |
| Data | |
| Rset | |
| Send Mailbox | |
| Soml Mailbox | |
| Saml Mailbox | |
| Vrfy String | |
| Expn String | |
| Help String | Might be |
| Noop | Optional argument ignored. |
| Quit | |
| Turn | |
| WrongArg String ParseError | When a valid command has been recognized, but the
argument parser fails, then this type will be
returned. The |
postmaster = Mailbox [] "postmaster" "" = "<postmaster>"
Data Types for SMTP Replies
An SMTP reply is a three-digit return code plus some waste of
bandwidth called "comments". This is what the list of strings is
for; one string per line in the reply. show will append an
"\r\n" end-of-line marker to each entry in that list, so that
the resulting string is ready to be sent back to the peer. For
example:
>>>show $ Reply (Code Success MailSystem 0) ["worked", "like", "a charm" ]"250-worked\r\n250-like\r\n250 a charm\r\n"
If the message is an empty list [], a default text will be constructed:
>>>show $ Reply (Code Success MailSystem 0) []"250 Success in category MailSystem\r\n"
data SuccessCode Source
Constructors
| Syntax | |
| Information | |
| Connection | |
| Unspecified3 | |
| Unspecified4 | |
| MailSystem |
isSuccess :: SmtpReply -> Bool Source
A reply constitutes "success" if the status code is
any of PreliminarySuccess, Success, or
IntermediateSuccess.
isFailure :: SmtpReply -> Bool Source
A reply constitutes "failure" if the status code is
either PermanentFailure or TransientFailure.
isShutdown :: SmtpReply -> Bool Source
The replies 221 and 421 signify Shutdown.
Command Parsers
type SmtpParser st = CharParser st SmtpCmd Source
The SMTP parsers defined here correspond to the commands specified in RFC2821, so I won't document them individually.
smtpCmd :: SmtpParser st Source
This parser recognizes any of the SMTP commands defined
below. Note that all command parsers expect their input
to be terminated with crlf.
smtpData :: SmtpParser st Source
The parser name "data" was taken.
rset :: SmtpParser st Source
quit :: SmtpParser st Source
turn :: SmtpParser st Source
helo :: SmtpParser st Source
ehlo :: SmtpParser st Source
mail :: SmtpParser st Source
rcpt :: SmtpParser st Source
send :: SmtpParser st Source
soml :: SmtpParser st Source
saml :: SmtpParser st Source
vrfy :: SmtpParser st Source
expn :: SmtpParser st Source
help :: SmtpParser st Source
noop :: SmtpParser st Source
May have an optional word argument, but it is ignored.
Argument Parsers
from_path :: CharParser st Mailbox Source
to_path :: CharParser st Mailbox Source
path :: CharParser st Mailbox Source
mailbox :: CharParser st Mailbox Source
local_part :: CharParser st String Source
domain :: CharParser st String Source
a_d_l :: CharParser st [String] Source
at_domain :: CharParser st String Source
address_literal :: CharParser st String Source
TODO: Add IPv6 address and general literals
ipv4_literal :: CharParser st String Source
ipv4addr :: CharParser st String Source
subdomain :: CharParser st String Source
dot_string :: CharParser st String Source
atom :: CharParser a String Source
snum :: CharParser st String Source
number :: CharParser st String Source
word :: CharParser st String Source
This is a useful addition: The parser accepts an atom
or a quoted_string.
Helper Functions
mkCmd0 :: String -> a -> CharParser st a Source
Construct a parser for a command without arguments.
Expects crlf!
mkCmd1 :: String -> (a -> SmtpCmd) -> CharParser st a -> CharParser st SmtpCmd Source
Construct a parser for a command with an argument, which
the given parser will handle. The result of the argument
parser will be applied to the type constructor before it
is returned. Expects crlf!
tokenList :: CharParser st String -> Char -> CharParser st String Source