summaryrefslogtreecommitdiff
path: root/xmppServer.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-02-17 09:53:04 -0500
committerjoe <joe@jerkface.net>2014-02-17 09:53:04 -0500
commit24f0f7a50653223ea72c846a56817760a0bd63b9 (patch)
treefc23e2e6447aaace62f47fe977021e0017c01db3 /xmppServer.hs
parentb17536990b17f646d800be2b014d917c0cd78c26 (diff)
Get username and tty for jid
Diffstat (limited to 'xmppServer.hs')
-rw-r--r--xmppServer.hs102
1 files changed, 96 insertions, 6 deletions
diff --git a/xmppServer.hs b/xmppServer.hs
index 3a16aca5..ec3a618d 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -13,21 +13,111 @@ import Network.Socket
13import Data.Monoid ( (<>) ) 13import Data.Monoid ( (<>) )
14import qualified Data.Text as Text 14import qualified Data.Text as Text
15import qualified Data.Text.IO as Text 15import qualified Data.Text.IO as Text
16import qualified Data.Text.Encoding as Text
16import Control.Monad 17import Control.Monad
17import qualified Network.BSD as BSD 18import qualified Network.BSD as BSD
19import qualified Data.Text as Text
20import Data.Text (Text)
21import qualified Data.Map as Map
22import Data.Map (Map)
23import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,ErrorCall(..))
24import System.Posix.User (getUserEntryForID,userName)
25import qualified Data.ByteString.Lazy.Char8 as L
18 26
19 27import UTmp (ProcessID,users)
28import LocalPeerCred
20import XMPPServer 29import XMPPServer
21import Server 30import Server
22 31
32textHostName = fmap Text.pack BSD.getHostName
33
34localJID user resource = do
35 hostname <- textHostName
36 return $ user <> "@" <> hostname <> "/" <> resource
37
38data ClientState = ClientState
39 { clientResource :: Text
40 , clientUser :: Text
41 , clientPid :: Maybe ProcessID
42 }
43
44data PresenceState = PresenceState
45 { clients :: TVar (Map ConnectionKey ClientState)
46 }
47
48getConsolePids :: PresenceState -> IO [(Text,ProcessID)]
49getConsolePids state = do -- return [("tty7", 23)] -- todo
50 us <- UTmp.users
51 return $ map (\(_,tty,pid)->(lazyByteStringToText tty,pid)) us
52
53lazyByteStringToText = (foldr1 (<>) . map Text.decodeUtf8 . L.toChunks)
54
55identifyTTY' ttypids uid inode = ttypid
56 where ttypids' = map (\(tty,pid)->(L.fromChunks [Text.encodeUtf8 tty], pid)) ttypids
57 ttypid = fmap textify $ identifyTTY ttypids' uid inode
58 textify (tty,pid) = (fmap lazyByteStringToText tty, pid)
59
60chooseResourceName state k addr desired = do
61 muid <- getLocalPeerCred' addr
62 (mtty,pid) <- getTTYandPID muid
63 user <- getJabberUserForId muid
64 let client = ClientState { clientResource = maybe "fallback" id mtty
65 , clientUser = user
66 , clientPid = pid }
67
68 atomically $
69 modifyTVar' (clients state) $ Map.insert k client
70 localJID (clientUser client) (clientResource client)
71
72 where
73 getTTYandPID muid = do
74 -- us <- fmap (map (second fst) . Map.toList) . readTVarIO $ activeUsers state
75 ttypids <- getConsolePids state
76 -- let tailOf3 ((_,a),b) = (a,b)
77 (t,pid) <- case muid of
78 Just (uid,inode) -> identifyTTY' ttypids uid inode
79 Nothing -> return (Nothing,Nothing)
80 let rsc = t `mplus` fmap ( ("pid."<>) . Text.pack . show ) pid
81 return (rsc,pid)
82
83 getJabberUserForId muid =
84 maybe (return "nobody")
85 (\(uid,_) ->
86 handle (\(SomeException _) ->
87 return . (<> "uid.") . Text.pack . show $ uid)
88 $ do
89 user <- fmap userName $ getUserEntryForID uid
90 return (Text.pack user)
91 )
92 muid
93
94forClient state k fallback f = do
95 mclient <- atomically $ do
96 cs <- readTVar (clients state)
97 return $ Map.lookup k cs
98 maybe (fallback k) (flip f k) mclient
99
100tellClientHisName state k = forClient state k fallback go
101 where
102 fallback k = localJID "nobody" "fallback"
103 go client k = localJID (clientUser client) (clientResource client)
104
105
23main = runResourceT $ do 106main = runResourceT $ do
24 hostname <- fmap Text.pack $ liftIO BSD.getHostName 107 -- us <- liftIO UTmp.users
108 -- liftIO $ putStrLn (show us)
109 hostname <- liftIO textHostName
110 state <- do
111 clients <- liftIO . atomically $ newTVar Map.empty
112 return PresenceState
113 { clients = clients
114 }
25 sv <- xmppServer 115 sv <- xmppServer
26 XMPPServerParameters 116 XMPPServerParameters
27 { xmppChooseResourceName = \k sock desired -> return $ "nobody@" <> hostname <> "/tty666" 117 { xmppChooseResourceName = chooseResourceName state
28 , xmppTellMyNameToClient = return hostname 118 , xmppTellClientHisName = tellClientHisName state
119 , xmppTellMyNameToClient = textHostName
29 , xmppTellMyNameToPeer = \addr -> return $ addrToText addr 120 , xmppTellMyNameToPeer = \addr -> return $ addrToText addr
30 , xmppTellClientHisName = \k -> return $ "nobody@" <> hostname <> "/tty666"
31 , xmppTellPeerHisName = return . peerKeyToText 121 , xmppTellPeerHisName = return . peerKeyToText
32 , xmppNewConnection = \k outchan -> return () 122 , xmppNewConnection = \k outchan -> return ()
33 , xmppEOF = \k -> return () 123 , xmppEOF = \k -> return ()
@@ -37,7 +127,7 @@ main = runResourceT $ do
37 , xmppRosterOthers = \k -> return [] 127 , xmppRosterOthers = \k -> return []
38 , xmppSubscribeToRoster = \k -> return () 128 , xmppSubscribeToRoster = \k -> return ()
39 , xmppLookupPeerName = \k -> return "localhost" 129 , xmppLookupPeerName = \k -> return "localhost"
40 , xmppLookupClientJID = \k -> return $ "nobody@" <> hostname <> "/tty666" 130 -- , xmppLookupClientJID = \k -> return $ "nobody@" <> hostname <> "/tty666"
41 , xmppDeliverMessage = \fail msg -> do 131 , xmppDeliverMessage = \fail msg -> do
42 let msgs = msgLangMap (stanzaType msg) 132 let msgs = msgLangMap (stanzaType msg)
43 body = fmap (maybe "" id . msgBody . snd) $ take 1 msgs 133 body = fmap (maybe "" id . msgBody . snd) $ take 1 msgs