{-# LINE 1 "src/Network/Telnet/LibTelnet/Ffi.hsc" #-}
module Network.Telnet.LibTelnet.Ffi where
import Network.Telnet.LibTelnet.Iac (Iac(..), iacNull)
import Network.Telnet.LibTelnet.Options (Option(..))
import qualified Network.Telnet.LibTelnet.Types as T
import Control.Exception (throwIO)
import Control.Monad (when)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.List (genericLength)
import Foreign hiding (newForeignPtr)
import Foreign.C (CSize(..), CString, CUChar(..))
import Foreign.Concurrent (newForeignPtr)
telnetInit
:: [T.TelnetTeloptT]
-> TelnetEventHandlerT
-> [T.Flag]
-> IO (ForeignPtr T.TelnetT)
telnetInit options handler flags = do
optionsA <- newArray0 (T.TelnetTeloptT (-1) iacNull iacNull) options
handlerP <- wrapEventHandler handler
let flagsC = foldr ((.|.) . T.unFlag) 0 flags
telnet <- cTelnetInit optionsA handlerP flagsC nullPtr
when (telnet == nullPtr) $ throwIO T.NullTelnetPtr
newForeignPtr telnet $ do
cTelnetFree telnet
freeHaskellFunPtr handlerP
free optionsA
foreign import ccall "libtelnet.h telnet_init"
cTelnetInit
:: Ptr T.TelnetTeloptT
-> FunPtr TelnetEventHandlerT
-> CUChar
-> Ptr ()
-> IO (Ptr T.TelnetT)
foreign import ccall "libtelnet.h telnet_free"
cTelnetFree :: Ptr T.TelnetT -> IO ()
type TelnetEventHandlerT = Ptr T.TelnetT -> Ptr T.EventT -> Ptr () -> IO ()
foreign import ccall "wrapper"
wrapEventHandler :: TelnetEventHandlerT -> IO (FunPtr TelnetEventHandlerT)
telnetRecv :: Ptr T.TelnetT -> ByteString -> IO ()
telnetRecv telnetP bs = B.useAsCStringLen bs $
\(buffer, size) -> cTelnetRecv telnetP buffer $ fromIntegral size
foreign import ccall "libtelnet.h telnet_recv"
cTelnetRecv
:: Ptr T.TelnetT
-> CString
-> CSize
-> IO ()
foreign import ccall "libtelnet.h telnet_iac"
cTelnetIac
:: Ptr T.TelnetT
-> Iac
-> IO ()
foreign import ccall "libtelnet.h telnet_negotiate"
cTelnetNegotiate
:: Ptr T.TelnetT
-> Iac
-> Option
-> IO ()
telnetSend :: Ptr T.TelnetT -> ByteString -> IO ()
telnetSend telnetP bs = B.useAsCStringLen bs $
\(buffer, size) -> cTelnetSend telnetP buffer $ fromIntegral size
foreign import ccall "libtelnet.h telnet_send"
cTelnetSend
:: Ptr T.TelnetT
-> CString
-> CSize
-> IO ()
telnetSubnegotiation :: Ptr T.TelnetT -> Option -> ByteString -> IO ()
telnetSubnegotiation telnetP opt bs = B.useAsCStringLen bs $
\(buffer, size) ->
cTelnetSubnegotiation telnetP opt buffer $ fromIntegral size
foreign import ccall "libtelnet.h telnet_subnegotiation"
cTelnetSubnegotiation
:: Ptr T.TelnetT
-> Option
-> CString
-> CSize
-> IO ()
foreign import ccall "libtelnet.h telnet_begin_compress2"
cTelnetBeginCompress2
:: Ptr T.TelnetT
-> IO ()
foreign import ccall "libtelnet.h telnet_begin_newenviron"
cTelnetBeginNewEnviron
:: Ptr T.TelnetT
-> T.ECmd
-> IO ()
foreign import ccall "libtelnet.h telnet_newenviron_value"
cTelnetNewEnvironValue
:: Ptr T.TelnetT
-> T.EVar
-> CString
-> IO ()
foreign import ccall "libtelnet.h telnet_ttype_send"
cTelnetTTypeSend
:: Ptr T.TelnetT
-> IO ()
foreign import ccall "libtelnet.h telnet_ttype_is"
cTelnetTTypeIs
:: Ptr T.TelnetT
-> CString
-> IO ()
telnetSendZmp :: Ptr T.TelnetT -> [ByteString] -> IO ()
telnetSendZmp telnetP cmd = useAsCStrings cmd $
\cCmd -> cTelnetSendZmp telnetP (genericLength cmd) cCmd
foreign import ccall "libtelnet.h telnet_send_zmp"
cTelnetSendZmp
:: Ptr T.TelnetT
-> CSize
-> Ptr CString
-> IO ()
useAsCStrings :: [ByteString] -> (Ptr CString -> IO a) -> IO a
useAsCStrings list f = go list [] where
go [] css = withArray (reverse css) f
go (bs:bss) css = B.useAsCString bs $ \cs -> go bss (cs:css)