-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A simple SMTP client library
--   
--   A simple SMTP client library for applications that want to send
--   emails.
@package SMTPClient
@version 1.0.4


-- | A pure SMTP client state machine.
--   
--   Data structures for representing SMTP status codes and email messages
--   are re-exported here from <i>Text.ParserCombinators.Parsec.Rfc2821</i>
--   and <i>Text.ParserCombinators.Parsec.Rfc2822</i> in the <i>hsemail</i>
--   package.
module Network.SMTP.ClientSession

-- | Construct a pure state machine for an SMTP client session. Caller must
--   handle I/O. The message body may use either "\n" or "\r\n" as an
--   end-of-line marker.
smtpClientSession :: String -> [Message] -> SMTPState
data SMTPState
SMTPState :: [String] -> Bool -> Maybe String -> (String -> SMTPState -> SMTPState) -> [Maybe SmtpReply] -> SMTPState

-- | Step 1. Caller must send any lines queued up in this list to the SMTP
--   server. They do not have end-of-line characters, so you must add
--   "\r\n" on the end (both characters are required by RFC2821 - do not
--   just send "\n").
smtpOutQueue :: SMTPState -> [String]

-- | Step 2. Check if this is True, which indicates that the SMTP session
--   has completed successfully and there is no more work to do.
smtpSuccess :: SMTPState -> Bool

-- | Step 3. Check if this is Just err, which indicates that a protocol
--   error has occurred, and that the caller must terminate the session.
smtpFailure :: SMTPState -> Maybe String

-- | Step 4. The caller should wait for a line from the SMTP server, strip
--   the "\r\n" end-of-line characters, and pass the stripped line to this
--   function for processing. Go to step 1.
smtpReceive :: SMTPState -> String -> SMTPState -> SMTPState

-- | A list containing a failure status for each message that has been sent
--   so far, where each element corresponds to one in the list of messages.
--   If the SMTP session does not complete successfully, then this list is
--   likely to be shorter than the input messages list. When smtpSuccess is
--   true, this list is guaranteed to be the same length as the list of
--   input messages. <i>Nothing</i> means success, and <i>Just x</i> is a
--   failure status returned by the SMTP server.
smtpStatuses :: SMTPState -> [Maybe SmtpReply]

-- | 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. <a>show</a> will append an
--   "<tt>\r\n</tt>" end-of-line marker to each entry in that list, so that
--   the resulting string is ready to be sent back to the peer.
--   
--   Here is an example:
--   
--   <pre>
--   *Rfc2821&gt; print $ Reply (Code Success MailSystem 0)
--                       ["worked", "like", "a charm" ]
--   250-worked
--   250-like
--   250 a charm
--   </pre>
--   
--   If the message is <tt>[]</tt>, you'll get a really helpful default
--   text.
data SmtpReply :: *
Reply :: SmtpCode -> [String] -> SmtpReply
data SmtpCode :: *
Code :: SuccessCode -> Category -> Int -> SmtpCode
data SuccessCode :: *
Unused0 :: SuccessCode
PreliminarySuccess :: SuccessCode
Success :: SuccessCode
IntermediateSuccess :: SuccessCode
TransientFailure :: SuccessCode
PermanentFailure :: SuccessCode
data Category :: *
Syntax :: Category
Information :: Category
Connection :: Category
Unspecified3 :: Category
Unspecified4 :: Category
MailSystem :: Category
type Message = GenericMessage String

-- | This data type repesents a parsed Internet Message as defined in this
--   RFC. It consists of an arbitrary number of header lines, represented
--   in the <a>Field</a> data type, and a message body, which may be empty.
data GenericMessage a :: * -> *
Message :: [Field] -> a -> GenericMessage a

-- | This data type represents any of the header fields defined in this
--   RFC. Each of the various instances contains with the return value of
--   the corresponding parser.
data Field :: *
OptionalField :: String -> String -> Field
From :: [NameAddr] -> Field
Sender :: NameAddr -> Field
ReturnPath :: String -> Field
ReplyTo :: [NameAddr] -> Field
To :: [NameAddr] -> Field
Cc :: [NameAddr] -> Field
Bcc :: [NameAddr] -> Field
MessageID :: String -> Field
InReplyTo :: [String] -> Field
References :: [String] -> Field
Subject :: String -> Field
Comments :: String -> Field
Keywords :: [[String]] -> Field
Date :: CalendarTime -> Field
ResentDate :: CalendarTime -> Field
ResentFrom :: [NameAddr] -> Field
ResentSender :: NameAddr -> Field
ResentTo :: [NameAddr] -> Field
ResentCc :: [NameAddr] -> Field
ResentBcc :: [NameAddr] -> Field
ResentMessageID :: String -> Field
ResentReplyTo :: [NameAddr] -> Field
Received :: ([(String, String)], CalendarTime) -> Field
ObsReceived :: [(String, String)] -> Field

-- | A NameAddr is composed of an optional realname a mandatory e-mail
--   <a>address</a>.
data NameAddr :: *
NameAddr :: Maybe String -> String -> NameAddr
nameAddr_name :: NameAddr -> Maybe String
nameAddr_addr :: NameAddr -> String


-- | An SMTP client in the IO Monad.
--   
--   Data structures for representing SMTP status codes and email messages
--   are re-exported here from <i>Text.ParserCombinators.Parsec.Rfc2821</i>
--   and <i>Text.ParserCombinators.Parsec.Rfc2822</i> in the <i>hsemail</i>
--   package.
--   
--   Here's a working example:
--   
--   <pre>
--   import Network.SMTP.ClientSession
--   import Network.SMTP.Client
--   import Network.Socket
--   import System.Time
--   import System.IO
--   import Data.Bits
--   import Data.IORef
--   
--   myDomain = "example.com"
--   smtpHost = "hubert"    -- &lt;-- Your SMTP server here
--   
--   -- This will send the author an email.  I don't mind!
--   main = do
--       now &lt;- getClockTime
--       nowCT &lt;- toCalendarTime now
--       let message = Message [
--                   From [NameAddr (Just "Mr. Nobody") "nobody@example.com"],
--                   To   [NameAddr (Just "Stephen Blackheath") "maxine@hip-to-be-square.com"],
--                   Subject "I'm using SMTPClient!",
--                   Date nowCT
--               ]
--               ("Dear Sir,\n"++
--                "It has come to my attention that this is an email.\n"++
--                "Yours sincerely,\n"++
--                "Mr. Nobody\n")
--       addrs &lt;- getAddrInfo Nothing (Just smtpHost) Nothing
--       let SockAddrInet _ hostAddr = addrAddress (addrs !! 0)
--           sockAddr = SockAddrInet (fromIntegral 25) hostAddr
--       putStrLn $ "connecting to "++show sockAddr
--       sentRef &lt;- newIORef []
--       sendSMTP' (hPutStrLn stderr) (Just sentRef) myDomain
--           sockAddr [message]
--       statuses &lt;- readIORef sentRef
--       -- If no exception was caught, statuses is guaranteed to be
--       -- the same length as the list of input messages, therefore head won't fail here.
--       case head statuses of
--           Nothing     -&gt; putStrLn "Message successfully sent"
--           Just status -&gt; putStrLn $ "Message send failed with status "++show status
--   </pre>
module Network.SMTP.Client

-- | Send a list of email messages to an SMTP server. Throws SMTPException
--   on failure at the communication protocol level, and it can also throw
--   socket-level exceptions.
--   
--   The optional IORef is used to store a list of statuses for messages
--   sent so far, where Nothing means success. The list elements correspond
--   to the elements of the input message list. If the caller catches an
--   exception, this list is likely to be shorter than the input message
--   list: The length of the list indicates how many messages were
--   dispatched. If no exception is caught, the length of the statuses will
--   equal the length of the input messages list.
--   
--   The message body may use either "\n" or "\r\n" as an end-of-line
--   marker and in either case it will be sent correctly to the server.
sendSMTP :: Maybe (IORef [Maybe SmtpReply]) -> String -> SockAddr -> [Message] -> IO ()

-- | Like sendSMTP but takes an additional function for logging all input
--   and output for diagnostic purposes.
sendSMTP' :: (String -> IO ()) -> Maybe (IORef [Maybe SmtpReply]) -> String -> SockAddr -> [Message] -> IO ()

-- | A lower level function that does the I/O processing for an SMTP client
--   session on a handle. Returns when the session has completed, with the
--   handle still open.
processSMTP :: (String -> IO ()) -> Maybe (IORef [Maybe SmtpReply]) -> Handle -> SMTPState -> IO ()

-- | An exception indicating a communications failure at the level of the
--   SMTP protocol.
data SMTPException
SMTPException :: String -> SMTPException

-- | 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. <a>show</a> will append an
--   "<tt>\r\n</tt>" end-of-line marker to each entry in that list, so that
--   the resulting string is ready to be sent back to the peer.
--   
--   Here is an example:
--   
--   <pre>
--   *Rfc2821&gt; print $ Reply (Code Success MailSystem 0)
--                       ["worked", "like", "a charm" ]
--   250-worked
--   250-like
--   250 a charm
--   </pre>
--   
--   If the message is <tt>[]</tt>, you'll get a really helpful default
--   text.
data SmtpReply :: *
Reply :: SmtpCode -> [String] -> SmtpReply
data SmtpCode :: *
Code :: SuccessCode -> Category -> Int -> SmtpCode
data SuccessCode :: *
Unused0 :: SuccessCode
PreliminarySuccess :: SuccessCode
Success :: SuccessCode
IntermediateSuccess :: SuccessCode
TransientFailure :: SuccessCode
PermanentFailure :: SuccessCode
data Category :: *
Syntax :: Category
Information :: Category
Connection :: Category
Unspecified3 :: Category
Unspecified4 :: Category
MailSystem :: Category
type Message = GenericMessage String

-- | This data type repesents a parsed Internet Message as defined in this
--   RFC. It consists of an arbitrary number of header lines, represented
--   in the <a>Field</a> data type, and a message body, which may be empty.
data GenericMessage a :: * -> *
Message :: [Field] -> a -> GenericMessage a

-- | This data type represents any of the header fields defined in this
--   RFC. Each of the various instances contains with the return value of
--   the corresponding parser.
data Field :: *
OptionalField :: String -> String -> Field
From :: [NameAddr] -> Field
Sender :: NameAddr -> Field
ReturnPath :: String -> Field
ReplyTo :: [NameAddr] -> Field
To :: [NameAddr] -> Field
Cc :: [NameAddr] -> Field
Bcc :: [NameAddr] -> Field
MessageID :: String -> Field
InReplyTo :: [String] -> Field
References :: [String] -> Field
Subject :: String -> Field
Comments :: String -> Field
Keywords :: [[String]] -> Field
Date :: CalendarTime -> Field
ResentDate :: CalendarTime -> Field
ResentFrom :: [NameAddr] -> Field
ResentSender :: NameAddr -> Field
ResentTo :: [NameAddr] -> Field
ResentCc :: [NameAddr] -> Field
ResentBcc :: [NameAddr] -> Field
ResentMessageID :: String -> Field
ResentReplyTo :: [NameAddr] -> Field
Received :: ([(String, String)], CalendarTime) -> Field
ObsReceived :: [(String, String)] -> Field

-- | A NameAddr is composed of an optional realname a mandatory e-mail
--   <a>address</a>.
data NameAddr :: *
NameAddr :: Maybe String -> String -> NameAddr
nameAddr_name :: NameAddr -> Maybe String
nameAddr_addr :: NameAddr -> String
instance Typeable SMTPException
instance Eq SMTPException
instance Show SMTPException
instance Exception SMTPException


-- | Mail is a simple library with which you can add email functionality to
--   your application. It assumes you have access to a smarthost which can
--   relay all your mail.
--   
--   As an example:
--   
--   <pre>
--   import Network.SMTP.Simple
--   import System.IO
--   
--   main :: IO ()
--   main = do
--       sendSimpleMessages (hPutStrLn stderr) "10.2.23.11" "example.com" [message]
--       where message = SimpleMessage
--                           [NameAddr (Just "John Doe") "johnd@example.com"]
--                           [NameAddr (Just "Team") "team@exmaple.com"]
--                           "My test email using Network.SMTP.Simple"
--                           "Hi, this is a test email which uses SMTPClient."
--   </pre>
module Network.SMTP.Simple

-- | A NameAddr is composed of an optional realname a mandatory e-mail
--   <a>address</a>.
data NameAddr :: *
NameAddr :: Maybe String -> String -> NameAddr
nameAddr_name :: NameAddr -> Maybe String
nameAddr_addr :: NameAddr -> String
data SimpleMessage
SimpleMessage :: [NameAddr] -> [NameAddr] -> String -> String -> SimpleMessage

-- | The sender(s)
from :: SimpleMessage -> [NameAddr]

-- | The recipient(s)
to :: SimpleMessage -> [NameAddr]

-- | The subject line
subject :: SimpleMessage -> String

-- | The body
body :: SimpleMessage -> String

-- | Use this if you need more control than sendSimpleMessages gives you.
sendRawMessages :: (String -> IO ()) -> SockAddr -> String -> [Message] -> IO ()

-- | Simplest way to send mail. Takes the smarthost ip, the HELO domain,
--   and a list of SimpleMessage.
sendSimpleMessages :: (String -> IO ()) -> String -> String -> [SimpleMessage] -> IO ()
instance Show SimpleMessage
