{-# OPTIONS -fffi #-} module Curl ( copyUrl, Cachable(Cachable, Uncachable, MaxAge) ) where import IO import Foreign.C.Types ( CInt ) #ifdef HAVE_CURL import Foreign.C.String ( withCString, CString ) import Monad ( when ) import System.Environment (getEnv) import Autoconf (darcs_version) #endif data Cachable = Cachable | Uncachable | MaxAge !CInt copyUrl :: String -> String -> Cachable -> IO () #ifdef HAVE_CURL copyUrl u f cache = withCString darcs_version $ \vstr -> withCString u $ \ustr -> withCString f $ \fstr -> do ppwd <- getProxyUserPwd withCString ppwd $ \pstr -> do err <- get_curl vstr pstr fstr ustr (cachableToInt cache) when (err /= 0) $ fail $ "Failed to download URL "++ u ++ " : " ++ curl_e err where curl_e 1 = "unsupported protocol" curl_e 3 = "malformed URL" curl_e 5 = "couldn't resolve proxy" curl_e 6 = "couldn't resolve host" curl_e 7 = "couldn't connect to host" curl_e 22 = "HTTP error (404?)" curl_e 23 = "libcurl write error" curl_e 46 = "bad password" curl_e err = "libcurl error code: "++show err #else copyUrl _ _ _ = fail "There is no libcurl!" #endif #ifdef HAVE_CURL cachableToInt :: Cachable -> CInt cachableToInt Cachable = -1 cachableToInt Uncachable = 0 cachableToInt (MaxAge n) = n foreign import ccall "hscurl.h get_curl" get_curl :: CString -> CString -> CString -> CString -> CInt -> IO CInt getProxyUserPwd :: IO String getProxyUserPwd = do getEnv "DARCS_PROXYUSERPWD" `catch` (\_ -> return "") #endif