hsemail-2: Parsec parsers for the RFC2822 Internet Message format

Copyright(c) 2013 Peter Simons
LicenseBSD3
Maintainersimons@cryp.to
Stabilityprovisional
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Text.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.

Synopsis

ESMTP State Machine

data Event Source #

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

Turn, Send, Soml, Saml, Vrfy, and Expn.

ResetState 
SayOK

Triggered in case of Noop or when Rset is used before we even have a state.

SeeksHelp String

The parameter may be [].

Shutdown 
SyntaxErrorIn String 
Unrecognized String 

Instances

Eq Event Source # 

Methods

(==) :: Event -> Event -> Bool #

(/=) :: Event -> Event -> Bool #

Show Event Source # 

Methods

showsPrec :: Int -> Event -> ShowS #

show :: Event -> String #

showList :: [Event] -> ShowS #

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 #

For those who want to parse the SmtpCmd themselves. Calling this function in HaveQuit or HaveData will fail an assertion. If assert is disabled, it will return respectively Shutdown and StartData again.

Data Types for SMTP Commands

data SmtpCmd Source #

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 nullPath.

RcptTo Mailbox

Might be postmaster.

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 String contains the name of the command (in all upper-case) and the ParseError is, obviously, the error description.

Instances

data Mailbox Source #

The most general e-mail address has the form: <[@route,...:]user@domain>. This type, too, supports show and read. Note that a "shown" address is always enclosed in angular brackets. When comparing two mailboxes for equality, the hostname is case-insensitive.

Constructors

Mailbox [String] String String 

nullPath :: Mailbox Source #

nullPath = Mailbox [] "" "" = "<>"

postmaster :: Mailbox Source #

postmaster = Mailbox [] "postmaster" "" = "<postmaster>"

Data Types for SMTP Replies

data SmtpReply Source #

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"

Constructors

Reply SmtpCode [String] 

reply :: Int -> Int -> Int -> [String] -> SmtpReply Source #

Construct a Reply. Fails assert if invalid numbers are given.

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

smtpCmd :: Stream s m Char => ParsecT s u m SmtpCmd Source #

The SMTP parsers defined here correspond to the commands specified in RFC2821, so I won't document them individually.

This parser recognizes any of the SMTP commands defined below. Note that all command parsers expect their input to be terminated with crlf.

smtpData :: Stream s m Char => ParsecT s u m SmtpCmd Source #

The parser name "data" was taken.

noop :: Stream s m Char => ParsecT s u m SmtpCmd Source #

May have an optional word argument, but it is ignored.

Argument Parsers

a_d_l :: Stream s m Char => ParsecT s u m [String] Source #

address_literal :: Stream s m Char => ParsecT s u m String Source #

TODO: Add IPv6 address and general literals

word :: Stream s m Char => ParsecT s u m String Source #

This is a useful addition: The parser accepts an atom or a quoted_string.

Helper Functions

fixCRLF :: String -> String Source #

Make the string crlf terminated no matter what. '\n' is expanded, otherwise crlf is appended. Note that if the string was terminated incorrectly before, it still is. This function is useful when reading input with hGetLine which removes the end-of-line delimiter.

mkCmd0 :: Stream s m Char => String -> a -> ParsecT s u m a Source #

Construct a parser for a command without arguments. Expects crlf!

mkCmd1 :: Stream s m Char => String -> (a -> SmtpCmd) -> ParsecT s u m a -> ParsecT s u m 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!