packages feed

HaskellNet 0.5.1 → 0.5.2

raw patch · 10 files changed

+140/−26 lines, 10 filesdep +faildep +network-bsddep ~basedep ~bytestringdep ~mime-mailPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: fail, network-bsd

Dependency ranges changed: base, bytestring, mime-mail, network

API changes (from Hackage documentation)

+ Network.HaskellNet.IMAP: UNSEEN :: MailboxStatus
+ Network.HaskellNet.IMAP.Types: UNSEEN :: MailboxStatus
- Network.HaskellNet.IMAP.Types: BAD :: (Maybe StatusCode) -> String -> ServerResponse
+ Network.HaskellNet.IMAP.Types: BAD :: Maybe StatusCode -> String -> ServerResponse
- Network.HaskellNet.IMAP.Types: NO :: (Maybe StatusCode) -> String -> ServerResponse
+ Network.HaskellNet.IMAP.Types: NO :: Maybe StatusCode -> String -> ServerResponse
- Network.HaskellNet.IMAP.Types: OK :: (Maybe StatusCode) -> String -> ServerResponse
+ Network.HaskellNet.IMAP.Types: OK :: Maybe StatusCode -> String -> ServerResponse
- Network.HaskellNet.IMAP.Types: PREAUTH :: (Maybe StatusCode) -> String -> ServerResponse
+ Network.HaskellNet.IMAP.Types: PREAUTH :: Maybe StatusCode -> String -> ServerResponse
- Network.HaskellNet.POP3.Types: LIST :: (Maybe Int) -> Command
+ Network.HaskellNet.POP3.Types: LIST :: Maybe Int -> Command
- Network.HaskellNet.POP3.Types: UIDL :: (Maybe Int) -> Command
+ Network.HaskellNet.POP3.Types: UIDL :: Maybe Int -> Command

Files

CHANGELOG view
@@ -1,3 +1,19 @@+0.5.2 (2020-03-19)+------------------++ - Improved Monad failure messages from sendCommmand (thanks Scott+   Fleischman)+ - Fixed IMAP append (thanks Keijo Kapp)+ - Added support for GHC 8.8.1 (thanks Oleg Grenrus)+ - Added support for network-3 (thanks Oleg Grenrus)+ - Increased upper bound on mime-mail to include 0.5 (thanks Marek+   Suchánek)+ - Improved failure message for AUTH failures (thanks Tom McLaughlin)+ - Avoided unsafe use of unsafe bytestring length functions in+   getResponse (thanks Javran Cheng)+ - Added support for UNSEEN in STATUS commands (thanks Dominik Xaver+   Hörl)+ 0.5.1 (2016-05-05) ------------------ 
HaskellNet.cabal view
@@ -4,7 +4,7 @@                 SMTP, and IMAP protocols.  NOTE: this package will be                 split into smaller, protocol-specific packages in the                 future.-Version:        0.5.1+Version:        0.5.2 Copyright:      (c) 2006 Jun Mukai Author:         Jun Mukai Maintainer:     Jonathan Daugherty <cygnus@foobox.com>,@@ -13,8 +13,20 @@ License-file:   LICENSE Category:       Network Homepage:       https://github.com/jtdaugherty/HaskellNet-Cabal-version:  >=1.6+Cabal-version:  >=1.8 Build-type:     Simple+Tested-with:+  GHC ==7.0.4+   || ==7.2.2+   || ==7.4.2+   || ==7.6.3+   || ==7.8.4+   || ==7.10.3+   || ==8.0.2+   || ==8.2.2+   || ==8.4.4+   || ==8.6.5+   || ==8.8.1  Extra-Source-Files:   CHANGELOG@@ -25,6 +37,11 @@   type:     git   location: git://github.com/jtdaugherty/HaskellNet.git +Flag network-bsd+ description: Use network-bsd+ manual:      False+ default:     True+ Library   Hs-Source-Dirs: src   GHC-Options: -Wall -fno-warn-unused-do-bind@@ -43,18 +60,28 @@     Network.HaskellNet.Debug    Other-modules:+    Network.Compat     Text.Packrat.Pos     Text.Packrat.Parse    Build-Depends:-    base >= 4 && < 5,-    network,+    base >= 4.3 && < 4.14,+    network >= 2.6.3.1 && < 3.2,     mtl,-    bytestring,+    bytestring >=0.10.2,     pretty,     array,-    cryptohash,+    cryptohash >=0.6,     base64-string,     old-time,-    mime-mail >= 0.4.7 && < 0.5,+    mime-mail >= 0.4.7 && < 0.6,     text++  if !impl(ghc >= 8.0)+    Build-depends: fail >= 4.9.0.0 && <4.10++  if flag(network-bsd)+    Build-Depends: network-bsd >=2.7 && <2.9,+                   network >=2.7+  else+    Build-Depends: network <2.7
README.md view
@@ -3,6 +3,8 @@  [![Build Status](https://travis-ci.org/lemol/HaskellNet.svg)](https://travis-ci.org/lemol/HaskellNet) +**NOTE: I am seeking a maintainer for this package. If you are interested, let me know!**+ This package provides client support for the E-mail protocols POP3, SMTP, and IMAP. 
+ src/Network/Compat.hs view
@@ -0,0 +1,53 @@+module Network.Compat where++import Network.Socket+import Network.BSD (getProtocolNumber)+import System.IO (Handle, IOMode (..))++import qualified Control.Exception as Exception++connectTo :: String             -- Hostname+          -> PortNumber         -- Port Identifier+          -> IO Handle          -- Connected Socket+connectTo host port = do+    proto <- getProtocolNumber "tcp"+    let hints = defaultHints { addrFlags = [AI_ADDRCONFIG]+                             , addrProtocol = proto+                             , addrSocketType = Stream }+    addrs <- getAddrInfo (Just hints) (Just host) (Just serv)+    firstSuccessful "connectTo" $ map tryToConnect addrs+  where+  serv = show port++  tryToConnect addr =+    Exception.bracketOnError+        (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))+        close  -- only done if there's an error+        (\sock -> do+          connect sock (addrAddress addr)+          socketToHandle sock ReadWriteMode+        )++-- Returns the first action from a list which does not throw an exception.+-- If all the actions throw exceptions (and the list of actions is not empty),+-- the last exception is thrown.+-- The operations are run outside of the catchIO cleanup handler because+-- catchIO masks asynchronous exceptions in the cleanup handler.+-- In the case of complete failure, the last exception is actually thrown.+firstSuccessful :: String -> [IO a] -> IO a+firstSuccessful caller = go Nothing+  where+  -- Attempt the next operation, remember exception on failure+  go _ (p:ps) =+    do r <- tryIO p+       case r of+         Right x -> return x+         Left  e -> go (Just e) ps++  -- All operations failed, throw error if one exists+  go Nothing  [] = ioError $ userError $ caller ++ ": firstSuccessful: empty list"+  go (Just e) [] = Exception.throwIO e++-- Version of try implemented in terms of the locally defined catchIO+tryIO :: IO a -> IO (Either Exception.IOException a)+tryIO m = Exception.catch (fmap Right m) (return . Left)
src/Network/HaskellNet/IMAP.hs view
@@ -23,7 +23,8 @@     ) where -import Network+import Network.Socket (PortNumber)+import Network.Compat import Network.HaskellNet.BSStream import Network.HaskellNet.IMAP.Connection import Network.HaskellNet.IMAP.Types@@ -33,7 +34,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS -import Control.Applicative ((<$>))+import Control.Applicative ((<$>), (<*>)) import Control.Monad  import System.Time@@ -116,7 +117,7 @@  connectIMAPPort :: String -> PortNumber -> IO IMAPConnection connectIMAPPort hostname port =-    handleToStream <$> connectTo hostname (PortNumber port)+    handleToStream <$> connectTo hostname port     >>= connectStream  connectIMAP :: String -> IO IMAPConnection@@ -165,7 +166,8 @@           getLs =               do l <- strip <$> bsGetLine s                  case () of-                   _ | isLiteral l ->  do l' <- getLiteral l (getLitLen l)+                   _ | BS.null l -> return [l]+                     | isLiteral l ->  do l' <- getLiteral l (getLitLen l)                                           ls <- getLs                                           return (l' : ls)                      | isTagged l -> (l:) <$> getLs@@ -313,17 +315,18 @@     in sendCommand conn cmd pStatus  append :: IMAPConnection -> MailboxName -> ByteString -> IO ()-append conn mbox mailData = appendFull conn mbox mailData [] Nothing+append conn mbox mailData = appendFull conn mbox mailData Nothing Nothing  appendFull :: IMAPConnection -> MailboxName -> ByteString-           -> [Flag] -> Maybe CalendarTime -> IO ()+           -> Maybe [Flag] -> Maybe CalendarTime -> IO () appendFull conn mbox mailData flags' time =     do (buf, num) <- sendCommand' conn-                (unwords ["APPEND", mbox-                         , fstr, tstr,  "{" ++ show len ++ "}"])-       unless (BS.null buf || (BS.head buf /= '+')) $+                (concat ["APPEND ", mbox+                        , fstr, tstr, " {" ++ show len ++ "}"])+       when (BS.null buf || (BS.head buf /= '+')) $               fail "illegal server response"        mapM_ (bsPutCrLf $ stream conn) mailLines+       bsPutCrLf (stream conn) BS.empty        buf2 <- getResponse $ stream conn        let (resp, mboxUp, ()) = eval pNone (show6 num) buf2        case resp of@@ -333,8 +336,8 @@          PREAUTH _ msg -> fail ("PREAUTH: "++msg)     where mailLines = BS.lines mailData           len       = sum $ map ((2+) . BS.length) mailLines-          tstr      = maybe "" show time-          fstr      = unwords $ map show flags'+          tstr      = maybe "" ((" "++) . show) time+          fstr      = maybe "" ((" ("++) . (++")") . unwords . map show) flags'  check :: IMAPConnection -> IO () check conn = sendCommand conn "CHECK" pNone
src/Network/HaskellNet/IMAP/Parsers.hs view
@@ -268,6 +268,7 @@                                 , string "RECENT"      >>= return . read                                 , string "UIDNEXT"     >>= return . read                                 , string "UIDVALIDITY" >>= return . read+                                , string "UNSEEN"      >>= return . read                                 ]                  space                  num <- many1 digit >>= return . read
src/Network/HaskellNet/IMAP/Types.hs view
@@ -97,6 +97,7 @@                    | RECENT       -- ^ the number of messages with the \Recent flag set                    | UIDNEXT      -- ^ the next unique identifier value of the mailbox                    | UIDVALIDITY  -- ^ the unique identifier validity value of the mailbox+                   | UNSEEN       -- ^ the number of messages with the \Unseen flag set                      deriving (Show, Read, Eq)  
src/Network/HaskellNet/POP3.hs view
@@ -31,7 +31,8 @@     where  import Network.HaskellNet.BSStream-import Network+import Network.Socket+import Network.Compat import qualified Network.HaskellNet.Auth as A  import Data.ByteString (ByteString)@@ -74,7 +75,7 @@ -- number connectPop3Port :: String -> PortNumber -> IO POP3Connection connectPop3Port hostname port =-    handleToStream <$> (connectTo hostname (PortNumber port))+    handleToStream <$> (connectTo hostname port)     >>= connectStream  -- | connecting to the pop3 server specified by the hostname. 110 is
src/Network/HaskellNet/SMTP.hs view
@@ -74,7 +74,8 @@ import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as BS import Network.BSD (getHostName)-import Network+import Network.Socket+import Network.Compat  import Control.Applicative ((<$>)) import Control.Exception@@ -140,7 +141,7 @@                 -> PortNumber -- ^ port number                 -> IO SMTPConnection connectSMTPPort hostname port =-    (handleToStream <$> connectTo hostname (PortNumber port))+    (handleToStream <$> connectTo hostname port)     >>= connectStream  -- | connecting SMTP server with the specified name and port 25.@@ -190,8 +191,8 @@ sendCommand :: SMTPConnection -> Command -> IO (ReplyCode, ByteString) sendCommand (SMTPC conn _) (DATA dat) =     do bsPutCrLf conn $ BS.pack "DATA"-       (code, _) <- parseResponse conn-       unless (code == 354) $ fail "this server cannot accept any data."+       (code, msg) <- parseResponse conn+       unless (code == 354) $ fail $ "this server cannot accept any data. code: " ++ show code ++ ", msg: " ++ BS.unpack msg        mapM_ (sendLine . stripCR) $ BS.lines dat ++ [BS.pack "."]        parseResponse conn     where sendLine = bsPutCrLf conn@@ -210,7 +211,7 @@ sendCommand (SMTPC conn _) (AUTH at username password) =     do bsPutCrLf conn command        (code, msg) <- parseResponse conn-       unless (code == 334) $ fail "authentication failed."+       unless (code == 334) $ fail $ "authentication failed. code: " ++ show code ++ ", msg: " ++ BS.unpack msg        bsPutCrLf conn $ BS.pack $ auth at (BS.unpack msg) username password        parseResponse conn     where command = BS.pack $ unwords ["AUTH", show at]@@ -359,7 +360,7 @@ -- haskellNet uses strict bytestrings -- TODO: look at making haskellnet lazy lazyToStrict :: B.ByteString -> S.ByteString-lazyToStrict = S.concat . B.toChunks+lazyToStrict = B.toStrict  crlf :: BS.ByteString crlf = BS.pack "\r\n"
src/Text/Packrat/Parse.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} -- | Packrat parsing: Simple, Powerful, Lazy, Linear time by Bryan -- Ford.  This module achieves monadic parsing library similar to -- Parsec.@@ -14,6 +15,8 @@ import           Control.Applicative (Applicative(..)) import qualified Control.Applicative as A +import qualified Control.Monad.Fail as Fail+ -- Data types  data Message = Expected String@@ -62,6 +65,12 @@               second err1 (NoParse err) =                   NoParse (joinErrors err1 err)     return = pure++#if !(MIN_VERSION_base(4,13,0))+    fail = Fail.fail+#endif++instance Derivs d => Fail.MonadFail (Parser d) where     fail msg = Parser (\dvs -> NoParse (msgError (dvPos dvs) msg))  instance Derivs d => A.Alternative (Parser d) where