X-Git-Url: http://www.average.org/gitweb/?p=pdns-pipe-nmc.git;a=blobdiff_plain;f=pdns-pipe-nmc.hs;h=1d2563788d0f4fa938ac685322f7d785966ee3f2;hp=ba6289944877d8e464d70afbe55ab2ba6f65a8b6;hb=7d674399abdb34b7f27857d8b3dfe7d467fa1434;hpb=adf1eff6277a0f1fb69f505285a20554a9ecabd6 diff --git a/pdns-pipe-nmc.hs b/pdns-pipe-nmc.hs index ba62899..1d25637 100644 --- a/pdns-pipe-nmc.hs +++ b/pdns-pipe-nmc.hs @@ -2,48 +2,29 @@ module Main where ---import Control.Applicative +import System.IO import Control.Monad -import qualified Data.ByteString.Char8 as C (pack, unpack) -import qualified Data.ByteString.Lazy.Char8 as L (pack, unpack) -import Data.ByteString.Lazy as BS hiding (reverse, putStrLn) -import Data.ConfigFile -import Data.Either.Utils +import Data.ByteString.Lazy hiding (reverse, putStr, putStrLn) +import qualified Data.ByteString.Char8 as C (pack) +import qualified Data.ByteString.Lazy.Char8 as L (pack) +import qualified Data.Text as T (pack) import Data.List.Split import Data.Aeson (encode, decode, Value(..)) import Network.HTTP.Types import Data.Conduit import Network.HTTP.Conduit -import Data.JsonRpcClient + +import JsonRpcClient +import Config import PowerDns -import NmcJson +import NmcRpc +import NmcDom confFile = "/etc/namecoin.conf" --- Config file handling - -data Config = Config { rpcuser :: String - , rpcpassword :: String - , rpchost :: String - , rpcport :: Int - } deriving (Show) - -readConfig :: String -> IO Config -readConfig f = do - cp <- return . forceEither =<< readfile emptyCP f - return (Config { rpcuser = getSetting cp "rpcuser" "" - , rpcpassword = getSetting cp "rpcpassword" "" - , rpchost = getSetting cp "rpchost" "localhost" - , rpcport = getSetting cp "rpcport" 8336 - }) - where - getSetting cp x dfl = case get cp "DEFAULT" x of - Left _ -> dfl - Right x -> x - -- HTTP/JsonRpc interface -qReq :: Config -> ByteString -> ByteString -> Request m +qReq :: Config -> String -> String -> Request m qReq cf q id = applyBasicAuth (C.pack (rpcuser cf)) (C.pack (rpcpassword cf)) $ def { host = (C.pack (rpchost cf)) , port = (rpcport cf) @@ -55,32 +36,33 @@ qReq cf q id = applyBasicAuth (C.pack (rpcuser cf)) (C.pack (rpcpassword cf)) , requestBody = RequestBodyLBS $ encode $ JsonRpcRequest JsonRpcV1 "name_show" - [q] - (String "pdns-nmc") + [L.pack q] + (String (T.pack id)) , checkStatus = \_ _ _ -> Nothing } -qRsp :: Response ByteString -> Either String NmcDom +qRsp :: Response ByteString -> Either String ByteString qRsp rsp = case parseJsonRpc (responseBody rsp) :: Either JsonRpcError NmcRes of - Left jerr -> Left $ "Unparseable response: " ++ (show (responseBody rsp)) - Right jrsp -> - case decode (resValue jrsp) :: Maybe NmcDom of - Nothing -> Left $ "Unparseable value: " ++ (show (resValue jrsp)) - Just dom -> Right dom + Left jerr -> + case (jrpcErrCode jerr) of + -4 -> Right "{}" -- this is how non-existent entry is returned + _ -> Left $ "JsonRpc error response: " ++ (show jerr) + Right jrsp -> Right $ resValue jrsp -- NMC interface -queryNmc :: Manager -> Config -> String -> RRType -> String +queryNmc :: Manager -> Config -> String -> String -> IO (Either String NmcDom) -queryNmc mgr cfg fqdn qtype qid = do +queryNmc mgr cfg qid fqdn = case reverse (splitOn "." fqdn) of - "bit":dn:xs -> do - rsp <- runResourceT $ - httpLbs (qReq cfg (L.pack ("d/" ++ dn)) (L.pack qid)) mgr + "bit":dn:xs -> descendNmcDom queryOp xs $ seedNmcDom dn + _ -> return $ Left "Only \".bit\" domain is supported" + where + queryOp key = do + rsp <- runResourceT $ httpLbs (qReq cfg key qid) mgr + -- print $ qRsp rsp return $ qRsp rsp - _ -> - return $ Left "Only \".bit\" domain is supported" -- Main entry @@ -88,6 +70,8 @@ main = do cfg <- readConfig confFile + hSetBuffering stdin LineBuffering + hSetBuffering stdout LineBuffering ver <- do let loopErr e = forever $ do @@ -105,18 +89,21 @@ main = do putStrLn $ "OK\tDnsNmc ready to serve, protocol v." ++ (show ver) mgr <- newManager def - - print $ qReq cfg "d/nosuchdomain" "query-nmc" - rsp <- runResourceT $ httpLbs (qReq cfg "d/nosuchdomain" "query-nmc") mgr - print $ (statusCode . responseStatus) rsp - putStrLn "===== complete response is:" - print rsp - let rbody = responseBody rsp - putStrLn "===== response body is:" - print rbody - let result = parseJsonRpc rbody :: Either JsonRpcError NmcRes - putStrLn "===== parsed response is:" - print result --- print $ parseJsonRpc (responseBody rsp) - - --forever $ getLine >>= (pdnsOut uri) . (pdnsParse ver) + forever $ do + l <- getLine + case pdnsParse ver l of + Left e -> putStr $ pdnsReport e + Right preq -> do + case preq of + PdnsRequestQ qname qtype id _ _ _ -> + queryNmc mgr cfg id qname >>= putStr . (pdnsOut ver id qname qtype) + PdnsRequestAXFR xfrreq -> + putStr $ pdnsReport ("No support for AXFR " ++ xfrreq) + PdnsRequestPing -> putStrLn "END" + +-- for testing + +ask str = do + cfg <- readConfig confFile + mgr <- newManager def + queryNmc mgr cfg "askid" str >>= putStr . (pdnsOut 1 "askid" str RRTypeANY)