summaryrefslogtreecommitdiff
path: root/xmppServer.hs
blob: 01246f643cd51ef8cbd6c94f3c6df721cf9c5cb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE LambdaCase #-}
import System.Environment
import System.Posix.Signals
import Control.Concurrent (threadDelay,forkIO,forkOS,killThread,throwTo)
import Control.Concurrent.STM
import Control.Concurrent.STM.TMVar
import Control.Monad.Trans.Resource (runResourceT)
import Control.Monad.Trans
import Control.Monad.IO.Class (MonadIO, liftIO)
import Network.Socket ( SockAddr(..) )
import System.Endian (fromBE32)
import Data.List (nub, (\\), intersect, groupBy, sort, sortBy )
import Data.Ord (comparing )
import Data.Monoid ( (<>), Sum(..), getSum )
import qualified Data.Text as Text
import qualified Data.Text.IO as Text
import qualified Data.Text.Encoding as Text
import Control.Monad
import Control.Monad.Fix
import qualified Network.BSD as BSD
import qualified Data.Text as Text
import Data.Text (Text)
import qualified Data.Map as Map
import Data.Map (Map)
import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,ErrorCall(..))
import System.IO.Error (isDoesNotExistError)
import System.Posix.User (getUserEntryForID,userName)
import qualified Data.ByteString.Lazy.Char8 as L
import qualified ConfigFiles
import Data.Maybe (maybeToList,listToMaybe,mapMaybe)
import Data.Bits
import Data.Int (Int8)
import Data.XML.Types (Event)
import System.Posix.Types (UserID,CPid)
import Control.Applicative

import LockedChan (LockedChan)
import TraversableT
import UTmp (ProcessID,users)
import LocalPeerCred
import XMPPServer
import PeerResolve
import ConsoleWriter
import ClientState
import Presence

main :: IO ()
main = runResourceT $ do
    args <- liftIO getArgs
    let verbosity = getSum $ flip foldMap args $ \case
            ('-':xs) -> Sum $ length (filter (=='-') xs)
            _        -> mempty
    cw    <- liftIO newConsoleWriter
    state <- liftIO $ newPresenceState cw
    sv    <- xmppServer (presenceHooks state verbosity)
    liftIO $ do
    atomically $ putTMVar (server state) sv

    quitVar <- newEmptyTMVarIO
    installHandler sigTERM (CatchOnce (atomically $ putTMVar quitVar True)) Nothing
    installHandler sigINT (CatchOnce (atomically $ putTMVar quitVar True)) Nothing

    forkIO $ do
        let console = cwPresenceChan $ consoleWriter state
        fix $ \loop -> do
        what <- atomically
            $ orElse (do (client,stanza) <- takeTMVar console
                         return $ do informClientPresence0 state Nothing client stanza
                                     loop)
                     (do readTMVar quitVar
                         return $ return ())
        what

    quitMessage <- atomically $ takeTMVar quitVar

    putStrLn "goodbye."
    return ()