module NmcJson ( NmcRes(..)
, NmcDom(..)
, emptyNmcDom
+ , descendNmc
) where
import Data.ByteString.Lazy (ByteString)
-import Data.Map (Map)
+import Data.Map as M (Map, lookup)
import Control.Applicative ((<$>), (<*>), empty)
import Data.Aeson
, srvW2 :: Int
, srvPort :: Int
, srvHost :: [String]
- } deriving (Show)
+ } deriving (Show, Eq)
instance FromJSON NmcRRService where
parseJSON (Object o) = NmcRRService
{ i2pDestination :: String
, i2pName :: String
, i2pB32 :: String
- } deriving (Show)
+ } deriving (Show, Eq)
instance FromJSON NmcRRI2p where
parseJSON (Object o) = NmcRRI2p
, domTls :: Maybe (Map String
(Map String [[String]]))
, domDs :: Maybe [[String]]
- } deriving (Show)
+ } deriving (Show, Eq)
instance FromJSON NmcDom where
parseJSON (Object o) = NmcDom
<*> o .: "address"
<*> o .: "expires_in"
parseJSON _ = empty
+
+descendNmc :: [String] -> NmcDom -> NmcDom
+descendNmc subdom dom = case subdom of
+ [] ->
+ case domMap dom of
+ Nothing -> dom
+ Just map ->
+ case M.lookup "" map of -- Stupid, but "" is allowed in the map
+ Nothing -> dom -- Try to merge it with the root data
+ Just sub -> mergeNmc sub dom
+ d:ds ->
+ case domMap dom of
+ Nothing -> emptyNmcDom
+ Just map ->
+ case M.lookup d map of
+ Nothing -> emptyNmcDom
+ Just sub -> descendNmc ds sub
+
+-- FIXME -- I hope there exists a better way to merge records!
+mergeNmc :: NmcDom -> NmcDom -> NmcDom
+mergeNmc sub dom = dom { domService = choose dom domService sub
+ , domIp = choose dom domIp sub
+ , domIp6 = choose dom domIp6 sub
+ , domTor = choose dom domTor sub
+ , domI2p = choose dom domI2p sub
+ , domFreenet = choose dom domFreenet sub
+ , domAlias = choose dom domAlias sub
+ , domTranslate = choose dom domTranslate sub
+ , domEmail = choose dom domEmail sub
+ , domLoc = choose dom domLoc sub
+ , domInfo = choose dom domInfo sub
+ , domNs = choose dom domNs sub
+ , domDelegate = choose dom domDelegate sub
+ , domImport = choose dom domImport sub
+ , domFingerprint = choose dom domFingerprint sub
+ , domTls = choose dom domTls sub
+ , domDs = choose dom domDs sub
+ }
+ where
+ choose :: NmcDom -> (NmcDom -> Maybe a) -> NmcDom -> Maybe a
+ choose sub t dom = case t dom of
+ Nothing -> t sub
+ Just x -> Just x
nmc2pdns name RRTypeCNAME dom = takejust name "CNAME" $ domAlias dom
nmc2pdns name RRTypeDNAME dom = takejust name "DNAME" $ domTranslate dom
nmc2pdns name RRTypeSOA dom =
- let
- email = case domEmail dom of
- Nothing -> "hostmaster." ++ name
- Just addr ->
- let (aname, adom) = break (== '@') addr
- in case adom of
- "" -> aname
- _ -> aname ++ "." ++ (tail adom)
- in
- [(name, "SOA", email ++ " 99999999 10800 3600 604800 86400")]
+ if dom == emptyNmcDom then []
+ else
+ let
+ email = case domEmail dom of
+ Nothing -> "hostmaster." ++ name
+ Just addr ->
+ let (aname, adom) = break (== '@') addr
+ in case adom of
+ "" -> aname
+ _ -> aname ++ "." ++ (tail adom)
+ in [(name, "SOA", email ++ " 99999999 10800 3600 604800 86400")]
nmc2pdns name RRTypeRP dom = [] --FIXME
nmc2pdns name RRTypeLOC dom = takejust name "LOC" $ domLoc dom
nmc2pdns name RRTypeNS dom = mapto name "NS" $ domNs dom
-- NMC interface
-descend subdom dom = dom --FIXME
-
queryNmc :: Manager -> Config -> String -> String
-> IO (Either String NmcDom)
queryNmc mgr cfg fqdn qid = do
httpLbs (qReq cfg (L.pack ("d/" ++ dn)) (L.pack qid)) mgr
return $ case qRsp rsp of
Left err -> Left err
- Right dom -> Right $ descend xs dom
+ Right dom -> Right $ descendNmc xs dom
_ ->
return $ Left "Only \".bit\" domain is supported"