{-# LANGUAGE CPP #-}
import Control.Monad
+import Data.List
import Data.Maybe
import Network
import Network.HTTP.Lucu
import System.Directory
import System.Environment
import System.Exit
+import System.IO
+import System.Log.Handler.Simple
+import System.Log.Logger
import System.Posix.Files
import System.Posix.Types
import System.Posix.User
+logger = "Main"
+
data CmdOpt
= OptPortNum PortNumber
| OptLSDir FilePath
| OptUserName String
| OptGroupName String
+ | OptLogLevel Priority
+ | OptDisableStderrLog
| OptHelp
deriving (Eq, Show)
defaultGroupName = "daemon"
+defaultLogLevel :: Priority
+defaultLogLevel = NOTICE
+
+
options :: [OptDescr CmdOpt]
options = [ Option ['p'] ["port"]
(ReqArg (OptPortNum . fromIntegral . read) "NUM")
(ReqArg OptGroupName "GROUP")
("Which user to setgid. (default: " ++ defaultGroupName ++ ")")
+ , Option ['l'] ["log-level"]
+ (ReqArg (OptLogLevel . read) "LEVEL")
+ ("The lowest log level to show. (default: " ++ show defaultLogLevel ++ ")")
+
+ , Option [] ["disable-stderr-log"]
+ (NoArg OptDisableStderrLog)
+ ("Disable logging to stderr.")
+
, Option ['h'] ["help"]
(NoArg OptHelp)
"Print this message."
setGroupID gid
setUserID uid
- env <- setupEnv lsdir portNum
+ setupLogger opts
+ env <- setupEnv lsdir portNum
+
+ noticeM logger ("Listening to " ++ show portNum ++ "/tcp...")
runHttpd (envLucuConf env) (resTree env) [fallbackRender env]
return path
+setupLogger :: [CmdOpt] -> IO ()
+setupLogger opts
+ = do let disableStderrLog = find (== OptDisableStderrLog) opts /= Nothing
+ logHandlers = if disableStderrLog then
+ []
+ else
+ [verboseStreamHandler stderr DEBUG]
+ logLevel = fromMaybe defaultLogLevel
+ $ do OptLogLevel l <- find (\ x -> case x of
+ OptLogLevel _ -> True
+ _ -> False) opts
+ return l
+
+ logHandlers' <- sequence logHandlers
+ updateGlobalLogger rootLoggerName (setHandlers logHandlers' . setLevel logLevel)
+
+
createLocalStateDir :: FilePath -> UserID -> GroupID -> IO ()
createLocalStateDir path uid gid
= do createDirectoryIfMissing True path
GHC-Options:
-fwarn-unused-imports -fglasgow-exts
Build-Depends:
- Crypto, HUnit, HsSVN, Lucu, base, encoding, filepath, hxt, mtl,
- network, parsec, stm, unix
+ Crypto, HUnit, HsSVN, Lucu, base, encoding, filepath, hslogger,
+ hxt, mtl, network, parsec, stm, unix
Exposed-Modules:
Rakka.Page
Rakka.Storage
import Subversion.Repository
import System.Directory
import System.FilePath
+import System.Log.Logger
+
+logger = "Rakka.Environment"
data Environment = Environment {
reposExist <- doesDirectoryExist reposPath
repos <- if reposExist then
- openRepository reposPath
+ do debugM logger ("Found a subversion repository on " ++ reposPath)
+ openRepository reposPath
else
- createRepository reposPath [] []
+ do noticeM logger ("Creating a subversion repository on " ++ reposPath)
+ createRepository reposPath [] []
sysConf <- mkSystemConfig lucuConf repos
interpTable <- mkInterpTable
import Subversion.FileSystem.Root
import Subversion.Repository
import System.FilePath.Posix
+import System.Log.Logger
+
+logger = "Rakka.SystemConfig"
data SystemConfig = SystemConfig {
getSysConf' :: SystemConfig -> SysConfValue -> IO SysConfValue
getSysConf' sc key
- = do fs <- getRepositoryFS (scRepository sc)
+ = do let path = fromConfPath (sysConfPath key)
+
+ fs <- getRepositoryFS (scRepository sc)
rev <- getYoungestRev fs
value <- withRevision fs rev
- $ do let path = fromConfPath (sysConfPath key)
- exists <- isFile path
+ $ do exists <- isFile path
case exists of
True
-> do str <- getFileContentsLBS path
return $ Just $ chomp $ decodeLazy UTF8 str
False
-> return Nothing
+
case value of
- Just str -> return $ unmarshalSysConf key str
- Nothing -> sysConfDefault sc key
+ Just str
+ -> do let val = unmarshalSysConf key str
+ debugM logger ("Got a config value at `" ++ path ++ "': " ++ show val)
+ return val
+ Nothing
+ -> do val <- sysConfDefault sc key
+ debugM logger ("Got no config value at `" ++ path ++ "'. Defaulting to " ++ show val)
+ return val
getSysConfA :: ArrowIO a => SystemConfig -> SysConfValue -> a b SysConfValue