X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Main.hs;h=78de22fad823e90529f0b5cd0948b33ebbea0dc1;hb=8631d8de8373ec8226d19019ae7cf3a1bf2e44e5;hp=02a4cf4702996013cfdcc6dc07c6646b1d707bb0;hpb=5b25efa958eac431edbcd97194ac51bb05a7c69b;p=Rakka.git diff --git a/Main.hs b/Main.hs index 02a4cf4..78de22f 100644 --- a/Main.hs +++ b/Main.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +import Control.Exception import Control.Monad import Data.List import Data.Maybe @@ -7,6 +8,7 @@ import Network.HTTP.Lucu import OpenSSL import Rakka.Environment import Rakka.Resource.CheckAuth +import Rakka.Resource.DumpRepos import Rakka.Resource.Index import Rakka.Resource.JavaScript import Rakka.Resource.PageEntity @@ -14,17 +16,21 @@ import Rakka.Resource.Object import Rakka.Resource.Render import Rakka.Resource.Search import Rakka.Resource.SystemConfig -import Rakka.Resource.TrackBack +-- import Rakka.Resource.TrackBack +import Rakka.Resource.Users import Rakka.Storage import Subversion import System.Console.GetOpt import System.Directory import System.Environment import System.Exit +import System.FilePath import System.IO import System.Log.Handler.Simple import System.Log.Logger import System.Posix.Files +import System.Posix.IO +import System.Posix.Process import System.Posix.Types import System.Posix.User @@ -39,7 +45,7 @@ data CmdOpt | OptUserName String | OptGroupName String | OptLogLevel Priority - | OptDisableStderrLog + | OptVerbose | OptRebuildIndex | OptHelp deriving (Eq, Show) @@ -83,13 +89,13 @@ options = [ Option ['p'] ["port"] (ReqArg (OptLogLevel . read) "LEVEL") ("The lowest log level to show. (default: " ++ show defaultLogLevel ++ ")") - , Option [] ["disable-stderr-log"] - (NoArg OptDisableStderrLog) - ("Disable logging to stderr.") + , Option ['v'] ["verbose"] + (NoArg OptVerbose) + "Enable logging to stderr." - , Option [] ["rebuild-index"] + , Option ['r'] ["rebuild-index"] (NoArg OptRebuildIndex) - ("Rebuild the index database.") + "Rebuild the index database." , Option ['h'] ["help"] (NoArg OptHelp) @@ -109,7 +115,7 @@ main = withOpenSSL $ withSubversion $ do (opts, nonOpts, errors) <- return . getOpt Permute options =<< getArgs - when (not $ null errors) + unless (null errors) $ do mapM_ putStr errors exitWith $ ExitFailure 1 @@ -117,7 +123,7 @@ main = withOpenSSL $ $ do printUsage exitWith ExitSuccess - when (not $ null nonOpts) + unless (null nonOpts) $ do printUsage exitWith $ ExitFailure 1 @@ -126,24 +132,30 @@ main = withOpenSSL $ gid <- getGroupID opts lsdir <- getLocalStateDir opts + -- Create our localstatedir *before* dropping privileges. createLocalStateDir lsdir uid gid setGroupID gid setUserID uid - setupLogger opts - env <- setupEnv lsdir portNum + -- Now that we have our localstatedir. Let's acquire a lock + -- on the lockfile. Then create other files. + withSystemLock (lsdir "lock") $ + withPidFile (lsdir "pid") $ + do setupLogger opts + env <- setupEnv lsdir portNum - rebuildIndexIfRequested env opts + rebuildIndexIfRequested env opts - infoM logger ("Listening to " ++ show portNum ++ "/tcp...") - runHttpd (envLucuConf env) (resTree env) [fallbackPageEntity env] + infoM logger ("Listening to " ++ show portNum ++ "/tcp...") + runHttpd (envLucuConf env) (resTree env) [fallbackPageEntity env] resTree :: Environment -> ResTree resTree env = mkResTree [ ([] , resIndex env) , (["checkAuth" ], resCheckAuth env) + , (["dumpRepos" ], resDumpRepos env) , (["js" ], javaScript ) , (["object" ], resObject env) , (["render" ], resRender env) @@ -151,7 +163,8 @@ resTree env , (["search.html" ], resSearch env) , (["search.xml" ], resSearch env) , (["systemConfig"], resSystemConfig env) - , (["trackback" ], resTrackBack env) + -- , (["trackback" ], resTrackBack env) + , (["users" ], resUsers env) ] @@ -209,16 +222,16 @@ getLocalStateDir opts 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 + = do let verbose = find (== OptVerbose) opts /= Nothing + logHandlers = if verbose then + [verboseStreamHandler stderr DEBUG] + else + [] -- FIXME: enable file log + 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) @@ -237,3 +250,29 @@ rebuildIndexIfRequested env opts _ -> False) opts when rebuild $ rebuildIndex (envStorage env) + +withSystemLock :: FilePath -> IO a -> IO a +withSystemLock lockfile = bracket lock' unlock' . const + where + lock' :: IO Fd + lock' = do fd <- openFd + lockfile + ReadWrite + (Just 420) -- 0644, -rw-r--r-- + defaultFileFlags + setLock fd (WriteLock, AbsoluteSeek, 0, 0) + return fd + + unlock' :: Fd -> IO () + unlock' = closeFd + +withPidFile :: FilePath -> IO a -> IO a +withPidFile lockfile = bracket_ mkPid' delPid' + where + mkPid' :: IO () + mkPid' = withFile lockfile WriteMode $ \ h -> + do pid <- getProcessID + hPutStrLn h (show pid) + + delPid' :: IO () + delPid' = removeFile lockfile