From 0785671863a9dd1d12b8ae3356d0c6eede9e2a94 Mon Sep 17 00:00:00 2001 From: joe Date: Wed, 26 Jun 2013 22:16:27 -0400 Subject: added GetHostByAddr module --- Presence/GetHostByAddr.hs | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Presence/GetHostByAddr.hs diff --git a/Presence/GetHostByAddr.hs b/Presence/GetHostByAddr.hs new file mode 100644 index 00000000..fd01108d --- /dev/null +++ b/Presence/GetHostByAddr.hs @@ -0,0 +1,75 @@ +{-# LINE 1 "Presence/GetHostByAddr.hsc" #-} +{-# LANGUAGE CPP, ForeignFunctionInterface #-} +{-# LINE 2 "Presence/GetHostByAddr.hsc" #-} +#include "Typeable.h" +module GetHostByAddr where + +import Network.BSD +import Foreign.Ptr +import Foreign.C.Types +import Foreign.Storable (Storable(..)) +import Foreign.Marshal.Utils (with) +import Control.Concurrent +import System.IO.Unsafe +import System.IO.Error (ioeSetErrorString, mkIOError) +import Network.Socket +import GHC.IO.Exception +import Network.Socket.Internal + + +throwNoSuchThingIfNull :: String -> String -> IO (Ptr a) -> IO (Ptr a) +throwNoSuchThingIfNull loc desc act = do + ptr <- act + if (ptr == nullPtr) + then ioError (ioeSetErrorString (mkIOError NoSuchThing loc Nothing Nothing) desc) + else return ptr + +{-# NOINLINE lock #-} +lock :: MVar () +lock = unsafePerformIO $ newMVar () + +withLock :: IO a -> IO a +withLock act = withMVar lock (\_ -> act) + +trySysCall :: IO a -> IO a +trySysCall act = act + +{- +-- The locking of gethostbyaddr is similar to gethostbyname. +-- | Get a 'HostEntry' corresponding to the given address and family. +-- Note that only IPv4 is currently supported. +getHostByAddr :: Family -> SockAddr -> IO HostEntry +getHostByAddr family addr = do + withSockAddr addr $ \ ptr_addr len -> withLock $ do + throwNoSuchThingIfNull "getHostByAddr" "no such host entry" + $ trySysCall $ c_gethostbyaddr ptr_addr (fromIntegral len) (packFamily family) + >>= peek +-} + + +-- The locking of gethostbyaddr is similar to gethostbyname. +-- | Get a 'HostEntry' corresponding to the given address and family. +-- Note that only IPv4 is currently supported. +-- getHostByAddr :: Family -> HostAddress -> IO HostEntry +-- getHostByAddr family addr = do +getHostByAddr :: SockAddr -> IO HostEntry +getHostByAddr (SockAddrInet port addr ) = do + let family = AF_INET + with addr $ \ ptr_addr -> withLock $ do + throwNoSuchThingIfNull "getHostByAddr" "no such host entry" + $ trySysCall $ c_gethostbyaddr ptr_addr (fromIntegral (sizeOf addr)) (packFamily family) + >>= peek +getHostByAddr (SockAddrInet6 port flow addr scope) = do + let family = AF_INET6 + with addr $ \ ptr_addr -> withLock $ do + throwNoSuchThingIfNull "getHostByAddr" "no such host entry" + $ trySysCall $ c_gethostbyaddr ptr_addr (fromIntegral (sizeOf addr)) (packFamily family) + >>= peek + + +foreign import ccall safe "gethostbyaddr" + c_gethostbyaddr :: Ptr a -> CInt -> CInt -> IO (Ptr HostEntry) + + + +-- vim:ft=haskell: -- cgit v1.2.3