5 import System.Console.GetOpt
6 import System.Environment
8 import System.Posix.Types
9 import System.Posix.User
12 = OptPortNum PortNumber
20 defaultPort :: PortNumber
21 defaultPort = fromIntegral 8080
23 defaultUserName :: String
24 defaultUserName = "daemon"
26 defaultGroupName :: String
27 defaultGroupName = "daemon"
30 options :: [OptDescr CmdOpt]
31 options = [ Option ['p'] ["port"]
32 (ReqArg (OptPortNum . fromIntegral . read) "NUM")
33 ("Port number to listen. (default: " ++ show defaultPort ++ ")")
35 , Option ['d'] ["localstatedir"]
36 (ReqArg OptLSDir "DIR")
37 ("Path to the database directory. (default: " ++ LOCALSTATEDIR ++ ")")
39 , Option ['u'] ["user"]
40 (ReqArg OptUserName "USER")
41 ("Which user to setuid. (default: " ++ defaultUserName ++ ")")
43 , Option ['g'] ["group"]
44 (ReqArg OptGroupName "GROUP")
45 ("Which user to setgid. (default: " ++ defaultGroupName ++ ")")
47 , Option ['h'] ["help"]
54 printUsage = do putStrLn "Usage:"
55 putStrLn " rakka [OPTIONS...]"
57 putStr $ usageInfo "Options:" options
61 main = do (opts, nonOpts, errors) <- return . getOpt Permute options =<< getArgs
63 when (not $ null errors)
64 $ do mapM_ putStr errors
65 exitWith $ ExitFailure 1
67 when (any (\ x -> x == OptHelp) opts)
71 when (not $ null nonOpts)
73 exitWith $ ExitFailure 1
75 portNum <- getPortNum opts
82 getPortNum :: [CmdOpt] -> IO PortNumber
84 = do let xs = mapMaybe (\ x -> case x of
85 OptPortNum n -> Just n
88 [] -> return defaultPort
90 _ -> error "too many --port options."
93 getUserID :: [CmdOpt] -> IO UserID
95 = do let xs = mapMaybe (\ x -> case x of
96 OptUserName n -> Just n
101 _ -> error "too many --user options."
103 userEnt <- getUserEntryForName name
104 return $ userID userEnt