elocrypt-0.3.0: src/cli/Main.hs
module Main where
import Control.Monad
import Data.List
import System.Console.GetOpt
import System.Environment
import System.Exit
import System.IO
import System.Random
import Data.Elocrypt
version = "elocrypt 0.3.0"
main :: IO ()
main = do
args <- getArgs
opts <- elocryptOpts args
gen <- getStdGen
-- TODO: Refactor me
if (optHelp opts) then do
hPutStrLn stderr usage
exitSuccess
else return ()
-- TODO: Refactor me
if (optVersion opts) then do
hPutStrLn stderr version
exitSuccess
else return ()
putStrLn (passwords opts gen)
passwords :: RandomGen g => Options -> g -> String
passwords opts gen = concat . intersperse "\n" . map (concat . intersperse "\t") . group $ ps
where ps = take (optNumber opts) . newPasswords (optLength opts) $ gen
group (p:ps:pss:psss) = [p, ps, pss]:(group psss)
group ps = [ps]
data Options
= Options { optLength :: Int, -- Size of the password(s)
optNumber :: Int, -- Number of passwords to generate
optHelp :: Bool,
optVersion :: Bool }
deriving (Show)
defaultOptions :: Options
defaultOptions = Options { optLength = 8,
optNumber = 42,
optHelp = False,
optVersion = False }
options :: [OptDescr (Options -> Options)]
options = [Option ['n'] ["number"] (ReqArg (\n o -> o {optNumber = read n}) "NUMBER") "The number of passwords to generate (default: 42)",
Option ['h'] ["help"] (NoArg (\o -> o { optHelp = True })) "Show this help",
Option ['v'] ["version"] (NoArg (\o -> o { optVersion = True })) "Show version and exit"]
elocryptOpts :: [String] -> IO Options
elocryptOpts args = do
(opts, nonopts) <- elocryptOpts' args
return $ if (null nonopts)
then opts
else opts { optLength = read (head nonopts) }
elocryptOpts' :: [String] -> IO (Options, [String])
elocryptOpts' args = case getOpt Permute options args of
(opts, nonopts, []) -> return (foldl (flip id) defaultOptions opts, nonopts)
(_ , _ , errs) -> do
-- TODO: Refactor me
hPutStrLn stderr (concat errs)
hPutStrLn stderr usage
exitFailure
usage :: String
usage = usageInfo header options
where header = "Usage: elocrypt [option...] length"