module Data.Ident where
import Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import Data.ByteString.Char8 as BSC
import Data.ByteString.Builder
import Data.Monoid
data PortPair = PortPair Int Int
data Reply = ReplyError PortPair ErrorType
| ReplyIdent PortPair OpsysField UserID
data ErrorType = InvalidPort
| NoUser
| HiddenUser
| UnknownError
| ErrorToken String
data OpsysField = OpsysField Opsys (Maybe Charset)
data Opsys = Other
| Unix
| Token String
data Charset = USAscii
data UserID = UserID String
parsePortPair :: BS.ByteString -> Maybe PortPair
parsePortPair req =
case (fmap fst . BSC.readInt) <$> (BSC.split ',' req) of
[p1,p2] -> PortPair <$> p1 <*> p2
_ -> Nothing
renderReply :: Reply -> ByteString
renderReply (ReplyError portPair errType) =
BSL.toStrict . toLazyByteString $
renderPortPair portPair
<> string7 " : ERROR : "
<> renderErrorType errType
renderReply (ReplyIdent portPair opsysField userID) =
BSL.toStrict . toLazyByteString $
renderPortPair portPair
<> string7 " : USERID : "
<> renderOpsysField opsysField
<> string7 " : "
<> renderUserId userID
renderPortPair :: PortPair -> Builder
renderPortPair (PortPair i j) =
intDec i
<> string7 ", "
<> intDec j
renderErrorType :: ErrorType -> Builder
renderErrorType InvalidPort = string7 "INVALID-PORT"
renderErrorType NoUser = string7 "NO-USER"
renderErrorType HiddenUser = string7 "HIDDEN-USER"
renderErrorType UnknownError = string7 "UNKNOWN-ERROR"
renderErrorType (ErrorToken err) =
string7 err
renderOpsysField :: OpsysField -> Builder
renderOpsysField (OpsysField opsys charset) =
renderOpsys opsys
<> renderCharset charset
renderUserId :: UserID -> Builder
renderUserId (UserID userID) = string7 userID
renderOpsys :: Opsys -> Builder
renderOpsys Other = string7 "OTHER"
renderOpsys Unix = string7 "UNIX"
renderOpsys (Token tok) = string7 tok
renderCharset :: Maybe Charset -> Builder
renderCharset Nothing = mempty
renderCharset _ = error "Charset not supported"