summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
Diffstat (limited to 'Presence')
-rw-r--r--Presence/main.hs65
1 files changed, 42 insertions, 23 deletions
diff --git a/Presence/main.hs b/Presence/main.hs
index 9c11baae..f17b8340 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -57,28 +57,26 @@ import qualified Text.Show.ByteString as L
57import Network.Socket (Family(AF_INET,AF_INET6)) 57import Network.Socket (Family(AF_INET,AF_INET6))
58 58
59 59
60data UnixSession = UnixSession { 60data ClientSession = ClientSession {
61 localhost :: Peer, -- ByteString, 61 localhost :: Peer, -- ByteString,
62 unix_uid :: (IORef (Maybe UserID)), 62 unix_uid :: (IORef (Maybe UserID)),
63 unix_resource :: (IORef (Maybe L.ByteString)), 63 unix_resource :: (IORef (Maybe L.ByteString)),
64 announced :: TVar (Set JID),
65 presence_state :: PresenceState 64 presence_state :: PresenceState
66} 65}
67 66
68instance XMPPSession UnixSession where 67instance XMPPSession ClientSession where
69 data XMPPClass UnixSession = UnixSessions PresenceState 68 data XMPPClass ClientSession = ClientSessions PresenceState
70 69
71 newSession (UnixSessions state) sock = do 70 newSession (ClientSessions state) sock = do
72 muid <- getLocalPeerCred sock 71 muid <- getLocalPeerCred sock
73 L.putStrLn $ "SESSION: open " <++> bshow muid 72 L.putStrLn $ "CLIENT SESSION: open " <++> bshow muid
74 uid_ref <- newIORef muid 73 uid_ref <- newIORef muid
75 res_ref <- newIORef Nothing 74 res_ref <- newIORef Nothing
76 jids <- newTVarIO Set.empty 75 return $ ClientSession (hostname state) uid_ref res_ref state
77 return $ UnixSession (hostname state) uid_ref res_ref jids state
78 76
79 setResource s resource = do 77 setResource s resource = do
80 writeIORef (unix_resource s) (Just resource) 78 writeIORef (unix_resource s) (Just resource)
81 L.putStrLn $ "SESSION: resource " <++> resource 79 L.putStrLn $ "CLIENT SESSION: resource " <++> resource
82 80
83 getJID s = do 81 getJID s = do
84 let host = localhost s 82 let host = localhost s
@@ -94,14 +92,11 @@ instance XMPPSession UnixSession where
94 muid 92 muid
95 rsc <- readIORef (unix_resource s) 93 rsc <- readIORef (unix_resource s)
96 -- let jid = user <++> "@" <++> host <++?> "/" <++$> rsc 94 -- let jid = user <++> "@" <++> host <++?> "/" <++$> rsc
97 L.putStrLn $ "SESSION: jid " <++> L.show (JID (Just user) host rsc) 95 L.putStrLn $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc)
98 return (JID (Just user) host rsc) 96 return (JID (Just user) host rsc)
99 97
100 closeSession session = do 98 closeSession session = do
101 L.putStrLn "SESSION: close" 99 L.putStrLn "CLIENT SESSION: close"
102 js <- fmap Set.toList (readTVarIO . announced $ session)
103 let offline jid = Presence jid Offline
104 forM_ js $ announcePresence session . offline
105 100
106 subscribe session Nothing = do 101 subscribe session Nothing = do
107 let tmvar = localSubscriber (presence_state session) 102 let tmvar = localSubscriber (presence_state session)
@@ -110,10 +105,35 @@ instance XMPPSession UnixSession where
110 let tvar = subscriberMap (presence_state session) 105 let tvar = subscriberMap (presence_state session)
111 atomically $ subscribeToMap tvar jid 106 atomically $ subscribeToMap tvar jid
112 107
108 announcePresence _ _ = error "announcePresence on client session?"
109
110
111data PeerSession = PeerSession {
112 announced :: TVar (Set JID),
113 peer_global :: PresenceState
114}
115instance XMPPSession PeerSession where
116 data XMPPClass PeerSession = PeerSessions PresenceState
117
118 setResource _ _ = error "setResource on peer session?"
119 getJID _ = error "getJID on peer session?"
120 subscribe _ _ = error "subscribe on peer session?"
121
122 newSession (PeerSessions state) sock = do
123 L.putStrLn $ "PEER SESSION: open"
124 jids <- newTVarIO Set.empty
125 return $ PeerSession jids state
126
127 closeSession session = do
128 L.putStrLn "PEER SESSION: close"
129 js <- fmap Set.toList (readTVarIO . announced $ session)
130 let offline jid = Presence jid Offline
131 forM_ js $ announcePresence session . offline
132
113 announcePresence session (Presence jid status) = do 133 announcePresence session (Presence jid status) = do
114 (greedy,subs) <- atomically $ do 134 (greedy,subs) <- atomically $ do
115 subs <- readTVar $ subscriberMap (presence_state session) 135 subs <- readTVar $ subscriberMap (peer_global session)
116 greedy <- fmap snd $ readTMVar $ localSubscriber (presence_state session) 136 greedy <- fmap snd $ readTMVar $ localSubscriber (peer_global session)
117 return (greedy,subs) 137 return (greedy,subs)
118 update_presence (Just greedy) (fmap snd subs) (Set.singleton jid) (const status) 138 update_presence (Just greedy) (fmap snd subs) (Set.singleton jid) (const status)
119 liftIO . atomically $ do 139 liftIO . atomically $ do
@@ -123,7 +143,6 @@ instance XMPPSession UnixSession where
123 Offline -> Set.delete jid jids 143 Offline -> Set.delete jid jids
124 _ -> Set.insert jid jids 144 _ -> Set.insert jid jids
125 145
126
127subscribeToChan tmvar = 146subscribeToChan tmvar =
128 (do (cnt,chan) <- takeTMVar tmvar 147 (do (cnt,chan) <- takeTMVar tmvar
129 putTMVar tmvar (cnt+1,chan) 148 putTMVar tmvar (cnt+1,chan)
@@ -229,16 +248,16 @@ instance XMPPConfig UnixConfig where
229start :: Network.Socket.Family -> IO () 248start :: Network.Socket.Family -> IO ()
230start ip4or6 = do 249start ip4or6 = do
231 let host = LocalHost 250 let host = LocalHost
232 tracked <- newPresenceState host 251 global_state <- newPresenceState host
233 let dologin e = track_login host tracked e 252 let dologin e = track_login host global_state e
234 dologin :: t -> IO () 253 dologin :: t -> IO ()
235 254
236 chan <- atomically $ subscribeToChan (localSubscriber tracked) 255 chan <- atomically $ subscribeToChan (localSubscriber global_state)
237 remotes <- forkIO $ seekRemotePeers UnixConfig chan 256 remotes <- forkIO $ seekRemotePeers UnixConfig chan
238 257
239 installHandler sigUSR1 (Catch (dologin (userError "signaled"))) Nothing 258 installHandler sigUSR1 (Catch (dologin (userError "signaled"))) Nothing
240 -- installHandler sigTERM (CatchOnce (dologin (userError "term signaled"))) Nothing 259 -- installHandler sigTERM (CatchOnce (dologin (userError "term signaled"))) Nothing
241 mtty <- monitorTTY (on_chvt tracked) 260 mtty <- monitorTTY (on_chvt global_state)
242 inotify <- initINotify 261 inotify <- initINotify
243#ifndef NOUTMP 262#ifndef NOUTMP
244 wd <- addWatch 263 wd <- addWatch
@@ -247,8 +266,8 @@ start ip4or6 = do
247 utmp_file 266 utmp_file
248 dologin 267 dologin
249#endif 268#endif
250 clients <- listenForXmppClients ip4or6 (UnixSessions tracked) 5222 HNil 269 clients <- listenForXmppClients ip4or6 (ClientSessions global_state) 5222 HNil
251 peers <- listenForRemotePeers ip4or6 (UnixSessions tracked) 5269 HNil 270 peers <- listenForRemotePeers ip4or6 (PeerSessions global_state) 5269 HNil
252 271
253 threadDelay 1000 -- wait a moment to obtain current tty 272 threadDelay 1000 -- wait a moment to obtain current tty
254 dologin () 273 dologin ()