summaryrefslogtreecommitdiff
path: root/Presence/main.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-07-20 21:59:22 -0400
committerjoe <joe@jerkface.net>2013-07-20 21:59:22 -0400
commite57941161715a28543794bdd346110c67f0cf224 (patch)
tree104adef89ce56521aa93100e8fb1138628f82c1c /Presence/main.hs
parent91f6d5730f0ceff2d640360e27be77101b425d3b (diff)
Now honors client's requested status.
Diffstat (limited to 'Presence/main.hs')
-rw-r--r--Presence/main.hs62
1 files changed, 45 insertions, 17 deletions
diff --git a/Presence/main.hs b/Presence/main.hs
index 5de660b0..d7510f94 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -15,6 +15,7 @@ import Data.Maybe
15import Data.Char 15import Data.Char
16import ConfigFiles 16import ConfigFiles
17import Control.Arrow (second) 17import Control.Arrow (second)
18import Data.Traversable (sequenceA)
18 19
19import System.INotify 20import System.INotify
20#ifndef NOUTMP 21#ifndef NOUTMP
@@ -35,7 +36,7 @@ import LocalPeerCred
35import System.Posix.User 36import System.Posix.User
36import Logging 37import Logging
37import qualified Data.Set as Set 38import qualified Data.Set as Set
38import Data.Set as Set (Set,(\\)) 39import Data.Set as Set ((\\))
39import qualified Data.Map as Map 40import qualified Data.Map as Map
40import Data.Map as Map (Map) 41import Data.Map as Map (Map)
41 42
@@ -187,15 +188,26 @@ instance JabberClientSession ClientSession where
187 debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")" 188 debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")"
188 189
189 setPresence s stat = do 190 setPresence s stat = do
190 user <- readIORef (unix_uid s) >>= getJabberUserForId
191 withJust (unix_pid s) $ \client_pid -> do 191 withJust (unix_pid s) $ \client_pid -> do
192 whenJust (readIORef (unix_resource s)) $ \tty -> do 192 whenJust (readIORef (unix_resource s)) $ \tty -> do
193 let au = activeUsers . presence_state $ s 193 user <- readIORef (unix_uid s) >>= getJabberUserForId
194 atomically $ do 194 greedysubs <- atomically $ do
195 let au = activeUsers . presence_state $ s
195 us <- readTVar au 196 us <- readTVar au
196 withJust (Map.lookup (user,tty) us) $ \(ttypid,cs) -> do 197 sequenceA $ Map.lookup (user,tty) us >>= \(ttypid,cs) -> do
197 let entry = (ttypid,Map.insert client_pid (Client {clientShow=stat}) cs) 198 let entry = (ttypid,Map.insert client_pid (Client {clientShow=stat}) cs)
198 writeTVar au (Map.insert (user,tty) entry us) 199 Just $ do
200 writeTVar au (Map.insert (user,tty) entry us)
201 subs <- readTVar $ subscriberMap (presence_state s)
202 greedy <- fmap snd . readTMVar $ localSubscriber (presence_state s)
203 activetty <- readTVar $ currentTTY (presence_state s)
204 usermap <- readTVar $ activeUsers (presence_state s)
205 return (greedy,subs,activetty,usermap)
206 withJust greedysubs $ \(greedy,subs,active_tty,usermap) -> do
207 update_presence (Just greedy)
208 (fmap snd subs)
209 [JID (Just user) (localhost s) (Just tty)]
210 (matchResource usermap active_tty)
199 211
200 getJID s = do 212 getJID s = do
201 let host = localhost s 213 let host = localhost s
@@ -206,12 +218,20 @@ instance JabberClientSession ClientSession where
206 -- debugL $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc) 218 -- debugL $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc)
207 return (JID (Just user) host rsc) 219 return (JID (Just user) host rsc)
208 220
209 closeSession session = do 221 closeSession s = do
210 atomically $ do 222 atomically $ do
211 cs <- readTVar (chans session) 223 cs <- readTVar (chans s)
212 forM_ cs $ \(RefCountedChan c) -> do 224 forM_ cs $ \(RefCountedChan c) -> do
213 unsubscribeToChan c 225 unsubscribeToChan c
214 debugL "CLIENT SESSION: close" 226 debugL "CLIENT SESSION: close"
227 withJust (unix_pid s) $ \client_pid -> do
228 whenJust (readIORef (unix_resource s)) $ \tty -> do
229 user <- readIORef (unix_uid s) >>= getJabberUserForId
230 atomically $ do
231 let au = activeUsers . presence_state $ s
232 us <- readTVar au
233 let remove = second (Map.delete client_pid)
234 writeTVar au (Map.adjust remove (user,tty) us)
215 235
216 subscribe session Nothing = do 236 subscribe session Nothing = do
217 let tmvar = localSubscriber (presence_state session) 237 let tmvar = localSubscriber (presence_state session)
@@ -616,9 +636,15 @@ unrefFromMap tvar key finalizer = do
616subscribeToMap tvar jid = 636subscribeToMap tvar jid =
617 getRefFromMap tvar jid newTChan dupTChan 637 getRefFromMap tvar jid newTChan dupTChan
618 638
619matchResource tty jid = maybe Away (avail . (==tty)) $ resource jid 639matchResource usermap tty jid = maybe Away (avail . (==tty)) $ resource jid
620 where 640 where
621 avail True = Available 641 avail True = case ( name jid >>= \u -> Map.lookup (u,tty) usermap ) of
642 Nothing -> Available
643 Just (pid,clients) ->
644 let stats = map (clientShow . snd) . Map.toList $ clients
645 in if null stats
646 then Available
647 else maximum stats
622 avail False = Away 648 avail False = Away
623 649
624matchResource' tty (_,rsc) = avail (rsc==tty) 650matchResource' tty (_,rsc) = avail (rsc==tty)
@@ -682,32 +708,34 @@ track_login host state e = do
682 . map (\((u,tty),pid)-> ((u,tty),(pid,Map.empty))) 708 . map (\((u,tty),pid)-> ((u,tty),(pid,Map.empty)))
683 $ new_users0 709 $ new_users0
684 (Set.fromList->new_users,_) = unzip new_users0 710 (Set.fromList->new_users,_) = unzip new_users0
685 (tty,known_users,subs,locals_greedy) <- atomically $ do 711 (tty,active_users,subs,locals_greedy) <- atomically $ do
686 tty <- readTVar $ currentTTY state 712 tty <- readTVar $ currentTTY state
687 st <- flip swapTVar new_users' $ activeUsers state 713 st <- flip swapTVar new_users' $ activeUsers state
688 xs <- readTVar $ subscriberMap state 714 xs <- readTVar $ subscriberMap state
689 locals_greedy <- tryReadTMVar $ localSubscriber state 715 locals_greedy <- tryReadTMVar $ localSubscriber state
690 return (tty,Map.keysSet st,fmap snd xs,fmap snd locals_greedy) 716 return (tty,st,fmap snd xs,fmap snd locals_greedy)
717 let known_users = Map.keysSet active_users
691 let arrivals = map tupleToJID . Set.toList $ new_users \\ known_users 718 let arrivals = map tupleToJID . Set.toList $ new_users \\ known_users
692 departures = map tupleToJID . Set.toList $ known_users \\ new_users 719 departures = map tupleToJID . Set.toList $ known_users \\ new_users
693 update_presence locals_greedy subs departures $ const Offline 720 update_presence locals_greedy subs departures $ const Offline
694 update_presence locals_greedy subs arrivals $ matchResource tty 721 update_presence locals_greedy subs arrivals $ matchResource active_users tty
695 forM_ arrivals 722 forM_ arrivals
696 $ sendProbes state 723 $ sendProbes state
697 724
698on_chvt state vtnum = do 725on_chvt state vtnum = do
699 let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum) 726 let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum)
700 debugL $ "VT switch: " <++> tty 727 debugL $ "VT switch: " <++> tty
701 (users,subs,locals_greedy) <- atomically $ do 728 (active_users,subs,locals_greedy) <- atomically $ do
702 us <- readTVar $ activeUsers state 729 us <- readTVar $ activeUsers state
703 subs <- readTVar $ subscriberMap state 730 subs <- readTVar $ subscriberMap state
704 writeTVar (currentTTY state) tty 731 writeTVar (currentTTY state) tty
705 locals_greedy <- tryReadTMVar $ localSubscriber state 732 locals_greedy <- tryReadTMVar $ localSubscriber state
706 return (Map.keysSet us,fmap snd subs,fmap snd locals_greedy) 733 return (us,fmap snd subs,fmap snd locals_greedy)
734 let users = Map.keysSet active_users
707 update_presence locals_greedy 735 update_presence locals_greedy
708 subs 736 subs
709 (map tupleToJID . Set.toList $ users) 737 (map tupleToJID . Set.toList $ users)
710 $ matchResource tty 738 $ matchResource active_users tty
711 739
712-- start 740-- start
713-- 741--