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


-- | FTP Client and Server Library
--   
--   ftphs provides a Haskell library to implement a FTP client and a FTP
--   server.
--   
--   ftphs has a number of features:
--   
--   <ul>
--   <li>Easy to use operation</li>
--   <li>Full support of text and binary transfers</li>
--   <li>Optional lazy interaction</li>
--   <li>Server can serve up a real or a virtual filesystem tree</li>
--   <li>Standards compliant</li>
--   </ul>
@package ftphs
@version 1.0.9.1


-- | This module provides a parser that is used internally by
--   <a>Network.FTP.Client</a>. You almost certainly do not want to use
--   this module directly. Use <a>Network.FTP.Client</a> instead.
--   
--   Written by John Goerzen, jgoerzen@complete.org
module Network.FTP.Client.Parser

-- | Parse a FTP reply. Returns a (result code, text) pair.
parseReply :: String -> FTPResult

-- | Parse a FTP reply. Returns a (result code, text) pair. If the result
--   code indicates an error, raise an exception instead of just passing it
--   back.
parseGoodReply :: String -> IO FTPResult

-- | Converts a socket address to a string suitable for a PORT command.
--   
--   Example:
--   
--   <pre>
--   toPortString (SockAddrInet (PortNum 0x1234) (0xaabbccdd)) -&gt;
--                                "170,187,204,221,18,52"
--   </pre>
toPortString :: SockAddr -> IO String

-- | Converts a port string to a socket address. This is the inverse
--   calculation of <a>toPortString</a>.
fromPortString :: String -> IO SockAddr

-- | Parse a FTP reply. Logs debug messages.
debugParseGoodReply :: String -> IO FTPResult

-- | Converts a response code to a socket address
respToSockAddr :: FTPResult -> IO SockAddr
type FTPResult = (Int, [String])
unexpectedresp :: Show a => [Char] -> a -> [Char]
isxresp :: (Num a, Ord a) => a -> (a, t) -> Bool
forcexresp :: (Show t, Show a, Ord a, Num a) => a -> (a, t) -> (a, t)
forceioresp :: Int -> FTPResult -> IO ()
parseDirName :: FTPResult -> Maybe String


-- | This module provides a parser that is used internally by
--   <a>Network.FTP.Server</a>. You almost certainly do not want to use
--   this module directly. Use <a>Network.FTP.Server</a> instead.
--   
--   Written by John Goerzen, jgoerzen@complete.org
module Network.FTP.Server.Parser
parseCommand :: Handle -> IO (Either ParseError (String, String))


-- | This module provides a server-side interface to the File Transfer
--   Protocol as defined by:
--   
--   <ul>
--   <li>RFC959, basic protocol</li>
--   <li>RFC1123, clarifications</li>
--   <li>RFC1579, passive mode discussion</li>
--   </ul>
--   
--   Written by John Goerzen, jgoerzen@complete.org
--   
--   This is a modular FTP server implementation in pure Haskell. It is
--   highly adaptable to many different tasks, and can serve up not only
--   real files and directories, but also virtually any data structure you
--   could represent as a filesystem. It does this by using the
--   <a>System.IO.HVFS</a> and <a>System.IO.HVIO</a> modules.
--   
--   In addition, basic networking and multitasking configuration is
--   handled via <a>Network.SocketServer</a> and logging via
--   <a>System.Log.Logger</a>.
--   
--   This module is believed to be secure, but it not believed to be robust
--   enough for use on a public FTP server. In particular, it may be
--   vulnerable to denial of service attacks due to no timeouts or
--   restrictions on data size, and error catching is not yet completely
--   pervasive. These will be fixed in time. Your patches would also be
--   welcomed.
--   
--   Here is an example server that serves up the entire local filesystem
--   in a read-only manner:
--   
--   <pre>
--   import Network.FTP.Server
--   import Network.SocketServer
--   import System.Log.Logger
--   import System.IO.HVFS
--   import System.IO.HVFS.Combinators
--   
--   main = do
--          updateGlobalLogger "" (setLevel DEBUG)
--          updateGlobalLogger "Network.FTP.Server" (setLevel DEBUG)
--          let opts = (simpleTCPOptions 12345) {reuse = True}
--          serveTCPforever opts $
--               threadedHandler $
--               loggingHandler "" INFO $
--               handleHandler $
--               anonFtpHandler (HVFSReadOnly SystemFS)
--   </pre>
--   
--   Hint: if you wantto serve up only part of a filesystem, see
--   <a>newHVFSChroot</a>.
module Network.FTP.Server

-- | Main FTP handler; pass the result of applying this to one argument to
--   <a>handleHandler</a>
anonFtpHandler :: forall a. HVFSOpenable a => a -> Handle -> SockAddr -> SockAddr -> IO ()
instance GHC.Show.Show Network.FTP.Server.AuthState
instance GHC.Classes.Eq Network.FTP.Server.AuthState
instance GHC.Show.Show Network.FTP.Server.DataType
instance GHC.Classes.Eq Network.FTP.Server.DataType
instance GHC.Classes.Eq Network.FTP.Server.Command
instance GHC.Classes.Ord Network.FTP.Server.Command


-- | This module provides a client-side interface to the File Transfer
--   Protocol as defined by RFC959 and RFC1123.
--   
--   Written by John Goerzen, jgoerzen@complete.org
--   
--   Welcome to the FTP module for Haskell.
--   
--   Here is a quick usage example to get you started. This is a log of a
--   real session with ghci:
--   
--   (This would be similar in a <tt>do</tt> block. You could also save it
--   to a file and run that with Hugs.)
--   
--   <pre>
--   Prelude&gt; :l Network.FTP.Client
--   ...
--   </pre>
--   
--   The above loads the module.
--   
--   Next, we enable the debugging. This will turn on all the <tt>FTP
--   sent</tt> and <tt>FTP received</tt> messages you'll see.
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; enableFTPDebugging
--   </pre>
--   
--   Now, connect to the server on <tt>ftp.kernel.org</tt>.
--   
--   <pre>
--   *Network.FTP.Client&gt; h &lt;- easyConnectFTP "ftp.kernel.org"
--   FTP received: 220 Welcome to ftp.kernel.org.
--   </pre>
--   
--   And log in anonymously.
--   
--   <pre>
--   *Network.FTP.Client&gt; loginAnon h
--   FTP sent: USER anonymous
--   FTP received: 331 Please specify the password.
--   FTP sent: PASS anonymous@
--   ...
--   FTP received: 230 Login successful.
--   </pre>
--   
--   Change the directory...
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; cwd h "/pub/linux/kernel/Historic"
--   FTP sent: CWD /pub/linux/kernel/Historic
--   FTP received: 250 Directory successfully changed.
--   </pre>
--   
--   Let's look at the directory. <a>nlst</a> returns a list of strings,
--   each string corresponding to a filename. Here, <tt>putStrLn .
--   unlines</tt> will simply print them out, one per line.
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; nlst h Nothing &gt;&gt;= putStrLn . unlines
--   FTP sent: TYPE A
--   FTP received: 200 Switching to ASCII mode.
--   FTP sent: PASV
--   FTP received: 227 Entering Passive Mode (204,152,189,116,130,143)
--   FTP sent: NLST
--   FTP received: 150 Here comes the directory listing.
--   linux-0.01.tar.bz2
--   linux-0.01.tar.bz2.sign
--   linux-0.01.tar.gz
--   linux-0.01.tar.gz.sign
--   linux-0.01.tar.sign
--   old-versions
--   v0.99
--   FTP received: 226 Directory send OK.
--   </pre>
--   
--   Let's try downloading something and print it to the screen. Again, we
--   use <tt>putStrLn</tt>. We use <tt>fst</tt> here because
--   <a>getbinary</a> returns a tuple consisting of a string representing
--   the data and a <a>FTPResult</a> code.
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; getbinary h "linux-0.01.tar.gz.sign" &gt;&gt;= putStrLn . fst
--   FTP sent: TYPE I
--   FTP received: 200 Switching to Binary mode.
--   FTP sent: PASV
--   FTP received: 227 Entering Passive Mode (204,152,189,116,121,121)
--   FTP sent: RETR linux-0.01.tar.gz.sign
--   FTP received: 150 Opening BINARY mode data connection for linux-0.01.tar.gz.sign (248 bytes).
--   -----BEGIN PGP SIGNATURE-----
--   Version: GnuPG v1.0.0 (GNU/Linux)
--   Comment: See http://www.kernel.org/signature.html for info
--   
--   iD8DBQA54rf0yGugalF9Dw4RAqelAJ9lafFni4f/QyJ2IqDXzW2nz/ZIogCfRPtg
--   uYpWffOhkyByfhUt8Lcelec=
--   =KnLA
--   -----END PGP SIGNATURE-----
--   FTP received: 226 File send OK.
--   </pre>
--   
--   Here's an example showing you what the result code looks like.
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; getbinary h "linux-0.01.tar.gz.sign" &gt;&gt;= print . snd
--   ...
--   (226,["File send OK."])
--   </pre>
--   
--   The first component of the <a>FTPResult</a> object is the numeric
--   status code from the server. The second component is a list of message
--   lines from the server.
--   
--   Now, let's get a more detailed directory listing:
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; dir h Nothing &gt;&gt;= putStrLn . unlines
--   ...
--   -r--r--r--    1 536      536         63362 Oct 30  1993 linux-0.01.tar.bz2
--   -r--r--r--    1 536      536           248 Oct 30  1993 linux-0.01.tar.bz2.sign
--   -r--r--r--    1 536      536         73091 Oct 30  1993 linux-0.01.tar.gz
--   -r--r--r--    1 536      536           248 Oct 30  1993 linux-0.01.tar.gz.sign
--   -r--r--r--    1 536      536           248 Oct 30  1993 linux-0.01.tar.sign
--   drwxrwsr-x    5 536      536          4096 Mar 20  2003 old-versions
--   drwxrwsr-x    2 536      536          4096 Mar 20  2003 v0.99
--   FTP received: 226 Directory send OK.
--   </pre>
--   
--   And finally, log out:
--   
--   <pre>
--   Prelude Network.FTP.Client&gt; quit h
--   FTP sent: QUIT
--   FTP received: 221 Goodbye.
--   </pre>
--   
--   Here is one big important caution:
--   
--   /You MUST consume all data from commands that return file data before
--   you issue any other FTP commands./
--   
--   That's due to the lazy nature of Haskell. This means that, for
--   instance, you can't just iterate over the items <a>nlst</a> returns,
--   trying to <a>getbinary</a> each one of them -- the system is still
--   transferring <a>nlst</a> data while you are trying that, and confusion
--   will ensue. Either open two FTP connections or make sure you consume
--   the <a>nlst</a> data first.
--   
--   Here is a partial list of commands effected: <a>nlst</a>, <a>dir</a>,
--   <a>getbinary</a>, <a>getlines</a>, <a>downloadbinary</a>.
--   
--   The <a>seqList</a> function could be quite helpful here. For instance:
--   
--   <pre>
--   x &lt;- nlst h Nothing
--   map (\fn -&gt; ...download files from FTP... ) (seqList x)
--   </pre>
--   
--   If you omit the call to <a>seqList</a>, commands to download files
--   will be issued before the entire directory listing is read. FTP cannot
--   handle this.
--   
--   The corrolary is:
--   
--   /Actions that yield lazy data for data uploading must not issue FTP
--   commands themselves./
--   
--   This will be fairly rare. Just be aware of this.
--   
--   This module logs messages under <tt>Network.FTP.Client</tt> for
--   outgoing traffic and <tt>Network.FTP.Client.Parser</tt> for incoming
--   traffic, all with the <a>DEBUG</a> priority, so by default, no log
--   messages are seen. The <a>enableFTPDebugging</a> function will adjust
--   the priorities of these two handlers so debug messages are seen. Only
--   control channel conversations are logged. Data channel conversations
--   are never logged.
--   
--   All exceptions raised by this module have a string beginning with
--   <tt>"FTP: "</tt>. Most errors will be IO userErrors. In a few
--   extremely rare cases, errors may be raised by the Prelude error
--   function, though these will also have a string beginning with
--   <tt>"FTP: "</tt>. Exceptions raised by the underlying networking code
--   will be passed on to you unmodified.
--   
--   Useful standards:
--   
--   <ul>
--   <li>RFC959,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc0959.html</a></li>
--   <li>Passive mode, RFC1579,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc1579.html</a></li>
--   <li>Extended passive mode, IPv6, RFC2428
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc2428.html</a></li>
--   <li>Feature negotiation, RFC2389,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc2389.html</a></li>
--   <li>Internationalization of FTP, RFC2640,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc2640.html</a></li>
--   <li>FTP security considerations, RFC2577,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc2577.html</a></li>
--   <li>FTP URLs, RFC1738,
--   <a>http://www.cse.ohio-state.edu/cgi-bin/rfc/rfc1738.html</a></li>
--   </ul>
module Network.FTP.Client

-- | Connect to the remote FTP server and read but discard the welcome.
--   Assumes default FTP port, 21, on remote.
easyConnectFTP :: HostName -> IO FTPConnection

-- | Connect to remote FTP server and read the welcome.
connectFTP :: HostName -> PortNumber -> IO (FTPConnection, FTPResult)

-- | Log in anonymously.
loginAnon :: FTPConnection -> IO FTPResult

-- | Log in to an FTP account.
login :: FTPConnection -> String -> Maybe String -> Maybe String -> IO FTPResult

-- | Log off the server and quit.
quit :: FTPConnection -> IO FTPResult

-- | Sets whether passive mode is used (returns new connection object
--   reflecting this)
setPassive :: FTPConnection -> Bool -> FTPConnection
isPassive :: FTPConnection -> Bool

-- | Enable logging of FTP messages through <a>Logger</a>. This sets the
--   log levels of <tt>Network.FTP.Client.Parser</tt> and
--   <tt>Network.FTP.Client</tt> to DEBUG. By default, this means that full
--   protocol dumps will be sent to stderr.
--   
--   The effect is global and persists until changed.
enableFTPDebugging :: IO ()

-- | Retrieves a list of files in the given directory.
--   
--   FIXME: should this take a list of dirs?
nlst :: FTPConnection -> Maybe String -> IO [String]

-- | Retrieve the system-specific long form of a directory list.
--   
--   FIXME: should this take a list of dirs?
dir :: FTPConnection -> Maybe String -> IO [String]

-- | Retrieves the specified file in text mode.
getlines :: FTPConnection -> String -> IO ([String], FTPResult)

-- | Retrieves the specified file in binary mode.
getbinary :: FTPConnection -> String -> IO (String, FTPResult)

-- | Downloads a file from remote and saves to disk in binary mode. Note:
--   filename is used for both local and remote.
downloadbinary :: FTPConnection -> String -> IO FTPResult

-- | Puts data in the specified file in text mode. The first string is the
--   filename.
putlines :: FTPConnection -> String -> [String] -> IO FTPResult

-- | Puts data in the specified file in binary. The first string is the
--   filename.
putbinary :: FTPConnection -> String -> String -> IO FTPResult

-- | Uploads a file from disk in binary mode. Note: filename is used for
--   both local and remote.
uploadbinary :: FTPConnection -> String -> IO FTPResult

-- | Rename or move a file.
rename :: FTPConnection -> String -> String -> IO FTPResult

-- | Delete (unlink) a file.
delete :: FTPConnection -> String -> IO FTPResult

-- | Get the size of a file.
--   
--   This command is non-standard and may possibly fail.
size :: (Num a, Read a) => FTPConnection -> String -> IO a

-- | Change the working directory.
cwd :: FTPConnection -> String -> IO FTPResult

-- | Make new directory. Returns the absolute name of the new directory if
--   possible.
mkdir :: FTPConnection -> String -> IO (Maybe String, FTPResult)

-- | Remove a directory.
rmdir :: FTPConnection -> String -> IO FTPResult

-- | Print the current working directory. The first component of the result
--   is the parsed directory name, if the servers response was parsable.
pwd :: FTPConnection -> IO (Maybe String, FTPResult)
data FTPConnection

-- | Returns the socket part from calling <a>ntransfercmd</a>.
transfercmd :: FTPConnection -> String -> IO Handle

-- | Establishes a connection to the remote.
--   
--   FIXME: need support for rest
ntransfercmd :: FTPConnection -> String -> IO (Handle, Maybe Integer)

-- | Retrieves lines of data from the remote. The string gives the command
--   to issue.
retrlines :: FTPConnection -> String -> IO ([String], FTPResult)

-- | Stores the lines of data to the remote. The string gives the commands
--   to issue.
storlines :: FTPConnection -> String -> [String] -> IO FTPResult
sendcmd :: FTPConnection -> [Char] -> IO FTPResult
