diff options
author | joe <joe@jerkface.net> | 2014-03-15 19:24:15 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-03-15 19:24:15 -0400 |
commit | 0a4d745e1f08c7c7a89f8c79ffb90170c13d2c88 (patch) | |
tree | 5d514502b1def357bd3b62a959d5955482f202be /Presence/ConsoleWriter.hs | |
parent | 600a7f5a562357ea30c51ff52f2c2f950afe47f6 (diff) |
notify remote peers of utmp presences
Diffstat (limited to 'Presence/ConsoleWriter.hs')
-rw-r--r-- | Presence/ConsoleWriter.hs | 40 |
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 | |||
28 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) | 28 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) |
29 | import FGConsole ( monitorTTY ) | 29 | import FGConsole ( monitorTTY ) |
30 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType | 30 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType |
31 | , LangSpecificMessage(..), msgLangMap ) | 31 | , LangSpecificMessage(..), msgLangMap, cloneStanza ) |
32 | import ClientState | ||
32 | 33 | ||
33 | data ConsoleWriter = ConsoleWriter | 34 | data 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 | ||
39 | tshow x = Text.pack . show $ x | 41 | tshow 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 | ||