htalkat-0.1.2: Opts.hs
-- This file is part of htalkat
-- Copyright (C) 2021 Martin Bays <mbays@sdf.org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of version 3 of the GNU General Public License as
-- published by the Free Software Foundation, or any later version.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see http://www.gnu.org/licenses/.
{-# LANGUAGE Safe #-}
module Opts (globalHelp, localHelp, parseGlobal, parseLocal, Opt(..)) where
import System.Console.GetOpt
import qualified Command as C
data Opt
-- global:
= DataDir FilePath
| SocksHost String
| SocksPort String
| Help
| Version
-- local:
| Port String
| Host String
| BlockUnnamed
| AcceptUnnamed
| ListPending
| SpawnInteractive FilePath
| DumbClient
| CursesClient
| LocalTop
| LocalBottom
| Log
| NoLog
deriving (Eq, Ord, Show)
globalOptions :: [OptDescr Opt]
globalOptions =
[ Option ['d'] ["datadir"] (ReqArg DataDir "PATH") "default: ~/.htalkat, or $HTALKAT_DIR if set"
, Option ['S'] ["socks-host"] (ReqArg SocksHost "HOST") "use SOCKS5 proxy"
, Option ['P'] ["socks-port"] (ReqArg SocksPort "PORT") "port for SOCKS5 proxy (default: 1080)"
, Option ['v'] ["version"] (NoArg Version) "show version information"
, Option ['h'] ["help"] (NoArg Help) "show usage information"
]
localOptions :: C.Command -> [OptDescr Opt]
localOptions com =
Option ['h'] ["help"] (NoArg Help) "show usage information" :
case com of
C.Listen ->
[ Option ['p'] ["port"] (ReqArg Port "PORT") "Port to listen on (default: 5518)"
, Option ['H'] ["host"] (ReqArg Host "HOST") "Host to listen on (empty means bind all available)"
, Option ['b'] ["block-unnamed"] (NoArg BlockUnnamed) "Reject connections from unnamed users"
, Option ['a'] ["accept-unnamed"] (NoArg AcceptUnnamed) "Accept connections from unnamed users (default)"
]
C.Answer ->
[ Option ['l'] ["list"] (NoArg ListPending) "List unanswered incoming connections"
, Option ['i'] ["interactive-client"] (ReqArg SpawnInteractive "SOCKET_PATH") "Directly invoke interactive client"
] <> interactiveClientOptions
C.Connect -> interactiveClientOptions
_ -> []
where interactiveClientOptions =
[ Option ['d'] ["dumb"] (NoArg DumbClient) "Use dumb line-based client"
, Option ['c'] ["curses"] (NoArg CursesClient) "Use curses client (default)"
, Option ['t'] ["top"] (NoArg LocalTop) "Put you on top in curses client"
, Option ['b'] ["bottom"] (NoArg LocalBottom) "Put you on bottom in curses client (default)"
, Option ['L'] ["log"] (NoArg Log) "Log conversation"
, Option ['N'] ["no-log"] (NoArg NoLog) "Don't log conversation (default)"
]
globalHelp :: String -> String
globalHelp = (`usageInfo` globalOptions)
localHelp :: C.Command -> String -> String
localHelp c = (`usageInfo` localOptions c)
parseArgs :: [OptDescr Opt] -> [String] -> IO ([Opt],[String])
parseArgs opts argv =
case getOpt RequireOrder opts argv of
(o,n,[]) -> return (o,n)
(_,_,errs) -> ioError . userError $ concat errs
parseGlobal :: [String] -> IO ([Opt],[String])
parseGlobal = parseArgs globalOptions
parseLocal :: C.Command -> [String] -> IO ([Opt],[String])
parseLocal = parseArgs . localOptions