summaryrefslogtreecommitdiff
path: root/Presence/ConsoleWriter.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-03-15 19:24:15 -0400
committerjoe <joe@jerkface.net>2014-03-15 19:24:15 -0400
commit0a4d745e1f08c7c7a89f8c79ffb90170c13d2c88 (patch)
tree5d514502b1def357bd3b62a959d5955482f202be /Presence/ConsoleWriter.hs
parent600a7f5a562357ea30c51ff52f2c2f950afe47f6 (diff)
notify remote peers of utmp presences
Diffstat (limited to 'Presence/ConsoleWriter.hs')
-rw-r--r--Presence/ConsoleWriter.hs40
1 files changed, 32 insertions, 8 deletions
diff --git a/Presence/ConsoleWriter.hs b/Presence/ConsoleWriter.hs
index 5222258e..3b02dbbc 100644
--- a/Presence/ConsoleWriter.hs
+++ b/Presence/ConsoleWriter.hs
@@ -28,12 +28,14 @@ import qualified Network.BSD as BSD
28import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) 28import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) )
29import FGConsole ( monitorTTY ) 29import FGConsole ( monitorTTY )
30import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType 30import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType
31 , LangSpecificMessage(..), msgLangMap ) 31 , LangSpecificMessage(..), msgLangMap, cloneStanza )
32import ClientState
32 33
33data ConsoleWriter = ConsoleWriter 34data ConsoleWriter = ConsoleWriter
34 { cwPresenceChan :: TChan Stanza 35 { cwPresenceChan :: TChan (ClientState,Stanza)
35 , csActiveTTY :: TVar Word8 36 , csActiveTTY :: TVar Word8
36 , csUtmp :: TVar (Map Text (TVar (Maybe UtmpRecord))) 37 , csUtmp :: TVar (Map Text (TVar (Maybe UtmpRecord)))
38 , cwClients :: TVar (Map Text ClientState)
37 } 39 }
38 40
39tshow x = Text.pack . show $ x 41tshow x = Text.pack . show $ x
@@ -87,9 +89,11 @@ newConsoleWriter = do
87 cs <- atomically $ do 89 cs <- atomically $ do
88 ttyvar <- newTVar 0 90 ttyvar <- newTVar 0
89 utmpvar <- newTVar Map.empty 91 utmpvar <- newTVar Map.empty
92 clients <- newTVar Map.empty
90 return $ ConsoleWriter { cwPresenceChan = chan 93 return $ ConsoleWriter { cwPresenceChan = chan
91 , csActiveTTY = ttyvar 94 , csActiveTTY = ttyvar
92 , csUtmp = utmpvar 95 , csUtmp = utmpvar
96 , cwClients = clients
93 } 97 }
94 outvar <- atomically $ newTMVar () 98 outvar <- atomically $ newTMVar ()
95 let logit outvar s = do 99 let logit outvar s = do
@@ -216,7 +220,22 @@ newCon log cw activeTTY utmp = do
216 else "") 220 else "")
217 <> " session=" <> tshow (utmpSession u) 221 <> " session=" <> tshow (utmpSession u)
218 <> " addr=" <> tshow (utmpRemoteAddr u) 222 <> " addr=" <> tshow (utmpRemoteAddr u)
219 loop tty tu (Just u) 223 let r = resource u
224 stanza <- makePresenceStanza
225 "jabber:client"
226 (Just jid)
227 (jstatus r tty tu)
228 statusv <- atomically $ newTVar (Just stanza)
229 flgs <- atomically $ newTVar 0
230 let client = ClientState { clientResource = r
231 , clientUser = utmpUser u
232 , clientPid = Nothing
233 , clientStatus = statusv
234 , clientFlags = flgs }
235 atomically $ do
236 modifyTVar (cwClients cw) $ Map.insert r client
237 writeTChan (cwPresenceChan cw) (client,stanza)
238 loop client tty tu (Just u)
220 where 239 where
221 bstatus r ttynum mtu 240 bstatus r ttynum mtu
222 = r == ttystr 241 = r == ttystr
@@ -237,7 +256,7 @@ newCon log cw activeTTY utmp = do
237 where 256 where
238 (fst3,rst) = Text.splitAt 3 r 257 (fst3,rst) = Text.splitAt 3 r
239 258
240 loop tty tu u = do 259 loop client tty tu u = do
241 what <- atomically $ foldr1 orElse 260 what <- atomically $ foldr1 orElse
242 [ do (tty',tu') <- retryWhen activeTTY 261 [ do (tty',tu') <- retryWhen activeTTY
243 (\ttyu -> bstatus r tty tu == uncurry (bstatus r) ttyu) 262 (\ttyu -> bstatus r tty tu == uncurry (bstatus r) ttyu)
@@ -255,9 +274,12 @@ newCon log cw activeTTY utmp = do
255 "jabber:client" 274 "jabber:client"
256 (Just jid) 275 (Just jid)
257 (jstatus r tty' tu') 276 (jstatus r tty' tu')
258 atomically $ writeTChan (cwPresenceChan cw) stanza 277 dup <- cloneStanza stanza
278 atomically $ do
279 writeTVar (clientStatus client) $ Just dup
280 writeTChan (cwPresenceChan cw) (client,stanza)
259 log $ status r tty' tu' <> " " <> jid 281 log $ status r tty' tu' <> " " <> jid
260 loop tty' tu' u 282 loop client tty' tu' u
261 283
262 utmpChanged u' = maybe dead changed u' 284 utmpChanged u' = maybe dead changed u'
263 where 285 where
@@ -265,10 +287,12 @@ newCon log cw activeTTY utmp = do
265 jid0 <- maybe (return "") ujid u 287 jid0 <- maybe (return "") ujid u
266 jid <- ujid u' 288 jid <- ujid u'
267 log $ "changed: " <> jid0 <> " --> " <> jid 289 log $ "changed: " <> jid0 <> " --> " <> jid
268 loop tty tu (Just u') 290 loop client tty tu (Just u')
269 dead = do 291 dead = do
270 jid <- maybe (return "") ujid u 292 jid <- maybe (return "") ujid u
271 stanza <- makePresenceStanza "jabber:client" (Just jid) Offline 293 stanza <- makePresenceStanza "jabber:client" (Just jid) Offline
272 atomically $ writeTChan (cwPresenceChan cw) stanza 294 atomically $ do
295 modifyTVar (cwClients cw) $ Map.delete (clientResource client)
296 writeTChan (cwPresenceChan cw) (client,stanza)
273 log $ "Offline " <> jid 297 log $ "Offline " <> jid
274 298