~jack/libtelnet-haskell

ref: ba46f4705601fdfa0860eefae53bd75a1f005c0e libtelnet-haskell/example/Main.hs -rw-r--r-- 1.4 KiB
ba46f470Jack Kelly Rename: Network.Telnet.LibTelnet.{FFI,Ffi} 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{-# LANGUAGE LambdaCase #-}

{-

This is a minimal telnet server that echoes its input back to the
client:

* All data that arrives on the socket is logged to stdout with a
  "Socket: " prefix and then fed to the state tracker.

* When the event handler is called with a 'Telnet.Received' event, it
  prints the received data to stdout with an "R: " prefix, and sends it
  to the same state tracker.

* This triggers a 'Telnet.Send' event - "you should send this
  over the wire" - so we log it to stdout with an "S: " prefix and
  send it back over the socket.

* All other telnet features (IAC sequences, option negotiation, etc.)
  are ignored.

-}

module Main where

import           Control.Monad.Loops (whileJust_)
import qualified Data.ByteString.Char8 as B8
import           Network.Simple.TCP (HostPreference(..), Socket, recv, send, serve)
import qualified Network.Telnet.LibTelnet as Telnet

telnetH :: Socket -> Telnet.EventHandler
telnetH _ t (Telnet.Received b)
  = putStr "R: " *> B8.putStrLn b *> Telnet.telnetSend t b
telnetH s _ (Telnet.Send b)
  = putStr "S: " *> send s b
telnetH _ _ _ = pure ()

main :: IO ()
main = serve HostAny "4000" (\(s, _) -> handle s) where
  handle s = do
      telnet <- Telnet.telnetInit [] [] (telnetH s)
      whileJust_ (recv s 4096) $ \bs -> do
          putStr "Socket: "
          B8.putStrLn bs
          Telnet.telnetRecv telnet bs