{--
  Last changed Time-stamp: <2001-12-04 13:50:32 xtof>
  simple daytime client for linux
  compile and link with (ghc-5.02.1):
  ghc  -Wall -syslib net -c -o DaytimeClient.o DaytimeClient.hs
  ghc  -Wall -syslib net -o Daytime DaytimeClient.o
  make sure that daytime service is enabled on hostname or localhost
  usage: Daytime [hostname]
--}
module Main (main) where

-- pull in useful modules (similar to #include in C)
import IO
import System
import SocketPrim
import BSD

-- declare datatype Consts (similar to a typedef struct in C)
data Consts
    = Consts{ address :: String,
	      service :: String }

-- initialize defaults an instance of Consts
defaults :: Consts
defaults
    = Consts { address = "localhost",
	       service = "daytime" }

-- translate symbolic hostname to packed IP address
gethostbyname:: String -> IO HostAddress
gethostbyname hostname
    = do
      hostentry <- getHostByName hostname
      return (hostAddress hostentry)

{--
  look up port number of daytime service in the system service database 
  retrive the value of the TCP protocol number
  convert symbolic hostname into a packt IP address
  create a strem-style Internet-domain socket (local communication endpoint)
  connect to the remote host (remote communication endpoint)
  convert socket to a handle
--}
connectto :: String -> IO (Handle, Socket)
connectto hostname
    = do
      portnum <- getServicePortNumber (service defaults)
      protocolnum <- getProtocolNumber "tcp"
      ipaddress <- gethostbyname hostname
      sock <- socket AF_INET Stream protocolnum
      connect sock (SockAddrInet portnum ipaddress)
      handle <- socketToHandle sock ReadMode
      return (handle, sock)

-- close handle and socket
disconnect :: Handle -> Socket -> IO ()
disconnect handle sock
    = do
      hClose handle
      sClose sock

{--
  if hostname is given on cml return it
  otherwise return hostname from defaults
--}
processCmlArgs :: IO String
processCmlArgs
    = do
      args <- getArgs
      case args of
		([] ) -> return (address defaults)
		(x:_) -> return x

main :: IO ()
main
    = do
      hostname <- processCmlArgs
      (handle, sock) <- connectto hostname
      content <- hGetContents handle
      hPutStr stdout content
      disconnect handle sock

-- End of file