diff options
-rw-r--r-- | Presence/XMPP.hs | 92 | ||||
-rw-r--r-- | Presence/XMPPTypes.hs | 9 | ||||
-rw-r--r-- | Presence/main.hs | 83 |
3 files changed, 144 insertions, 40 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index 7d69e126..c2ae2fe2 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -457,6 +457,8 @@ fromClient session cmdChan = doNestingXML $ do | |||
457 | -> clientRequestsSubscription session cmdChan stanza | 457 | -> clientRequestsSubscription session cmdChan stanza |
458 | _ | stanza `isClientPresenceOf` presenceTypeSubscribed | 458 | _ | stanza `isClientPresenceOf` presenceTypeSubscribed |
459 | -> clientApprovesSubscription session stanza | 459 | -> clientApprovesSubscription session stanza |
460 | _ | stanza `isClientPresenceOf` presenceTypeUnsubscribed | ||
461 | -> clientRejectsSubscription session stanza | ||
460 | _ | otherwise -> unhandledStanza | 462 | _ | otherwise -> unhandledStanza |
461 | 463 | ||
462 | awaitCloser stanza_lvl | 464 | awaitCloser stanza_lvl |
@@ -544,6 +546,29 @@ toClient session pchan cmdChan rchan = toClient' False False | |||
544 | [attr "subscription" subscription] | 546 | [attr "subscription" subscription] |
545 | send r | 547 | send r |
546 | loop | 548 | loop |
549 | RChan (RemovedBuddy who contact) -> do | ||
550 | liftIO . putStrLn $ "Roster push: RemovedBuddy "++show (isInterested,who,contact) | ||
551 | (jid,me) <- liftIO $ do | ||
552 | jid <- getJID session | ||
553 | me <- asHostNameJID jid | ||
554 | return (jid,me) | ||
555 | withJust me $ \me -> do | ||
556 | when (isInterested && Just who==name jid) $ do | ||
557 | send [ EventBeginElement "{jabber:client}presence" | ||
558 | [ attrbs "from" contact | ||
559 | , attrbs "to" me | ||
560 | , attr "type" "unsubscribed" | ||
561 | ] | ||
562 | , EventEndElement "{jabber:client}presence" ] | ||
563 | let f True = "from" | ||
564 | f False = "none" | ||
565 | subscription <- fmap f (liftIO $ isSubscribed session contact) | ||
566 | r <- liftIO . handleIO (\e -> putStrLn ("Roster RemovedBuddy error: "++show e) >> return []) $ do | ||
567 | rosterPush jid | ||
568 | (toStrict . L.decodeUtf8 $ contact) | ||
569 | [attr "subscription" subscription] | ||
570 | send r | ||
571 | loop | ||
547 | RChan (NewSubscriber who contact) -> do | 572 | RChan (NewSubscriber who contact) -> do |
548 | liftIO . putStrLn $ "Roster push: NewSubscriber "++show (isInterested,who,contact) | 573 | liftIO . putStrLn $ "Roster push: NewSubscriber "++show (isInterested,who,contact) |
549 | (jid,me) <- liftIO $ do | 574 | (jid,me) <- liftIO $ do |
@@ -561,6 +586,23 @@ toClient session pchan cmdChan rchan = toClient' False False | |||
561 | [attr "subscription" subscription] | 586 | [attr "subscription" subscription] |
562 | send r | 587 | send r |
563 | loop | 588 | loop |
589 | RChan (RejectSubscriber who contact) -> do | ||
590 | liftIO . putStrLn $ "Roster push: RejectSubscriber "++show (isInterested,who,contact) | ||
591 | (jid,me) <- liftIO $ do | ||
592 | jid <- getJID session | ||
593 | me <- asHostNameJID jid | ||
594 | return (jid,me) | ||
595 | withJust me $ \me -> do | ||
596 | when (isInterested && Just who==name jid) $ do | ||
597 | let f True = "to" | ||
598 | f False = "none" | ||
599 | subscription <- fmap f (liftIO $ isBuddy session contact) | ||
600 | r <- liftIO . handleIO (\e -> putStrLn ("Roster RejectSubscriber error: "++show e) >> return []) $ do | ||
601 | rosterPush jid | ||
602 | (toStrict . L.decodeUtf8 $ contact) | ||
603 | [attr "subscription" subscription] | ||
604 | send r | ||
605 | loop | ||
564 | RChan (PendingSubscriber who contact) -> do | 606 | RChan (PendingSubscriber who contact) -> do |
565 | liftIO . putStrLn $ "Roster: Pending buddy "++show (isInterested,who,contact) | 607 | liftIO . putStrLn $ "Roster: Pending buddy "++show (isInterested,who,contact) |
566 | (jid,me) <- liftIO $ do | 608 | (jid,me) <- liftIO $ do |
@@ -709,11 +751,12 @@ matchAttribMaybe name Nothing attrs | |||
709 | | otherwise | 751 | | otherwise |
710 | = False | 752 | = False |
711 | 753 | ||
712 | presenceTypeOffline = Just "unavailable" | 754 | presenceTypeOffline = Just "unavailable" |
713 | presenceTypeOnline = Nothing | 755 | presenceTypeOnline = Nothing |
714 | presenceTypeProbe = Just "probe" | 756 | presenceTypeProbe = Just "probe" |
715 | presenceTypeSubscribe = Just "subscribe" | 757 | presenceTypeSubscribe = Just "subscribe" |
716 | presenceTypeSubscribed = Just "subscribed" | 758 | presenceTypeSubscribed = Just "subscribed" |
759 | presenceTypeUnsubscribed = Just "unsubscribed" | ||
717 | 760 | ||
718 | isPresenceOf (EventBeginElement name attrs) testType | 761 | isPresenceOf (EventBeginElement name attrs) testType |
719 | | name=="{jabber:server}presence" | 762 | | name=="{jabber:server}presence" |
@@ -854,6 +897,11 @@ clientApprovesSubscription session stanza = do | |||
854 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do | 897 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do |
855 | liftIO $ approveSubscriber session (textToByteString to_str) | 898 | liftIO $ approveSubscriber session (textToByteString to_str) |
856 | 899 | ||
900 | clientRejectsSubscription session stanza = do | ||
901 | liftIO $ putStrLn $ "CLIENT REJECTS SUBSCRIPTION" | ||
902 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do | ||
903 | liftIO $ rejectSubscriber session (textToByteString to_str) | ||
904 | |||
857 | peerApprovesSubscription session stanza = do | 905 | peerApprovesSubscription session stanza = do |
858 | liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" | 906 | liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" |
859 | whenJust (liftIO . handleIO (\e -> putStrLn ("peerApprovesSubscription: "++show e) >> return Nothing) | 907 | whenJust (liftIO . handleIO (\e -> putStrLn ("peerApprovesSubscription: "++show e) >> return Nothing) |
@@ -861,6 +909,13 @@ peerApprovesSubscription session stanza = do | |||
861 | withJust (name tojid) $ \user -> do | 909 | withJust (name tojid) $ \user -> do |
862 | liftIO $ processApproval session user fromjid | 910 | liftIO $ processApproval session user fromjid |
863 | 911 | ||
912 | peerRejectsSubscription session stanza = do | ||
913 | liftIO $ putStrLn $ "PEER REJECTS SUBSCRIPTION" | ||
914 | whenJust (liftIO . handleIO (\e -> putStrLn ("peerRejectsSubscription: "++show e) >> return Nothing) | ||
915 | $ stanzaFromTo session stanza) $ \(fromjid,tojid) -> do | ||
916 | withJust (name tojid) $ \user -> do | ||
917 | liftIO $ processRejection session user fromjid | ||
918 | |||
864 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => | 919 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => |
865 | session -> Sink XML.Event m () | 920 | session -> Sink XML.Event m () |
866 | fromPeer session = doNestingXML $ do | 921 | fromPeer session = doNestingXML $ do |
@@ -891,6 +946,8 @@ fromPeer session = doNestingXML $ do | |||
891 | -> peerRequestsSubsription session stanza | 946 | -> peerRequestsSubsription session stanza |
892 | _ | stanza `isPresenceOf` presenceTypeSubscribed | 947 | _ | stanza `isPresenceOf` presenceTypeSubscribed |
893 | -> peerApprovesSubscription session stanza | 948 | -> peerApprovesSubscription session stanza |
949 | _ | stanza `isPresenceOf` presenceTypeUnsubscribed | ||
950 | -> peerRejectsSubscription session stanza | ||
894 | _ -> unhandledStanza | 951 | _ -> unhandledStanza |
895 | 952 | ||
896 | awaitCloser stanza_lvl | 953 | awaitCloser stanza_lvl |
@@ -908,7 +965,7 @@ newServerConnections = newTVar Map.empty | |||
908 | data CachedMessages = CachedMessages | 965 | data CachedMessages = CachedMessages |
909 | { presences :: Map JID JabberShow | 966 | { presences :: Map JID JabberShow |
910 | , probes :: Map JID (Set (Bool,JID)) -- False means solicitation rather than probe | 967 | , probes :: Map JID (Set (Bool,JID)) -- False means solicitation rather than probe |
911 | , approvals :: Map JID (Set JID) | 968 | , approvals :: Map JID (Set (Bool,JID) ) -- False means rejection rather than approval |
912 | } | 969 | } |
913 | newCache = CachedMessages Map.empty Map.empty Map.empty | 970 | newCache = CachedMessages Map.empty Map.empty Map.empty |
914 | 971 | ||
@@ -938,7 +995,11 @@ connect_to_server chan peer = (>> return ()) . runMaybeT $ do | |||
938 | writeIORef cached (cache { probes=probes' }) | 995 | writeIORef cached (cache { probes=probes' }) |
939 | cacheCmd (Approval from to) cached = do | 996 | cacheCmd (Approval from to) cached = do |
940 | cache <- readIORef cached | 997 | cache <- readIORef cached |
941 | let approvals' = mmInsert from to $ approvals cache | 998 | let approvals' = mmInsert (True,from) to $ approvals cache |
999 | writeIORef cached (cache { approvals=approvals' }) | ||
1000 | cacheCmd (Rejection from to) cached = do | ||
1001 | cache <- readIORef cached | ||
1002 | let approvals' = mmInsert (False,from) to $ approvals cache | ||
942 | writeIORef cached (cache { approvals=approvals' }) | 1003 | writeIORef cached (cache { approvals=approvals' }) |
943 | 1004 | ||
944 | fix $ \sendmsgs -> do | 1005 | fix $ \sendmsgs -> do |
@@ -1038,16 +1099,18 @@ toPeer sock cache chan fail = do | |||
1038 | sendSolicitation from to = | 1099 | sendSolicitation from to = |
1039 | sendOrFail (presenceStanza sock from to "subscribe") | 1100 | sendOrFail (presenceStanza sock from to "subscribe") |
1040 | (Solicitation from to) | 1101 | (Solicitation from to) |
1041 | sendApproval from to = | 1102 | sendApproval approve from to = |
1042 | sendOrFail (presenceStanza sock from to "subscribed") | 1103 | sendOrFail (presenceStanza sock from to |
1043 | (Approval from to) | 1104 | (if approve then "subscribed" else "unsubscribed")) |
1105 | (if approve then Approval from to | ||
1106 | else Rejection from to) | ||
1044 | 1107 | ||
1045 | 1108 | ||
1046 | send greetPeer | 1109 | send greetPeer |
1047 | forM_ (Map.assocs . approvals $ cache) $ \(to,froms) -> do | 1110 | forM_ (Map.assocs . approvals $ cache) $ \(to,froms) -> do |
1048 | forM_ (Set.toList froms) $ \from -> do | 1111 | forM_ (Set.toList froms) $ \(approve,from) -> do |
1049 | liftIO $ L.putStrLn "sending cached approval..." | 1112 | liftIO $ L.putStrLn "sending cached approval..." |
1050 | sendApproval from to | 1113 | sendApproval approve from to |
1051 | forM_ (Map.assocs . presences $ cache) $ \(jid,st) -> do | 1114 | forM_ (Map.assocs . presences $ cache) $ \(jid,st) -> do |
1052 | sendPresence (Presence jid st) | 1115 | sendPresence (Presence jid st) |
1053 | forM_ (Map.assocs . probes $ cache) $ \(to,froms) -> do | 1116 | forM_ (Map.assocs . probes $ cache) $ \(to,froms) -> do |
@@ -1073,7 +1136,10 @@ toPeer sock cache chan fail = do | |||
1073 | sendSolicitation from to | 1136 | sendSolicitation from to |
1074 | Approval from to -> do | 1137 | Approval from to -> do |
1075 | liftIO . L.putStrLn $ "sending approval "<++>bshow (from,to) | 1138 | liftIO . L.putStrLn $ "sending approval "<++>bshow (from,to) |
1076 | sendApproval from to | 1139 | sendApproval True from to |
1140 | Rejection from to -> do | ||
1141 | liftIO . L.putStrLn $ "sending rejection "<++>bshow (from,to) | ||
1142 | sendApproval False from to | ||
1077 | loop | 1143 | loop |
1078 | send goodbyePeer | 1144 | send goodbyePeer |
1079 | 1145 | ||
diff --git a/Presence/XMPPTypes.hs b/Presence/XMPPTypes.hs index 0e98a77b..4507f5bf 100644 --- a/Presence/XMPPTypes.hs +++ b/Presence/XMPPTypes.hs | |||
@@ -59,6 +59,7 @@ class JabberClientSession session where | |||
59 | isSubscribed :: session -> ByteString -> IO Bool | 59 | isSubscribed :: session -> ByteString -> IO Bool |
60 | isBuddy :: session -> ByteString -> IO Bool | 60 | isBuddy :: session -> ByteString -> IO Bool |
61 | approveSubscriber :: session -> ByteString -> IO () | 61 | approveSubscriber :: session -> ByteString -> IO () |
62 | rejectSubscriber :: session -> ByteString -> IO () | ||
62 | 63 | ||
63 | class JabberPeerSession session where | 64 | class JabberPeerSession session where |
64 | data XMPPPeerClass session | 65 | data XMPPPeerClass session |
@@ -72,6 +73,7 @@ class JabberPeerSession session where | |||
72 | getBuddies :: XMPPPeerClass session -> ByteString -> IO [ByteString] | 73 | getBuddies :: XMPPPeerClass session -> ByteString -> IO [ByteString] |
73 | getSubscribers :: XMPPPeerClass session -> ByteString -> IO [ByteString] | 74 | getSubscribers :: XMPPPeerClass session -> ByteString -> IO [ByteString] |
74 | processApproval :: session -> ByteString -> JID -> IO () | 75 | processApproval :: session -> ByteString -> JID -> IO () |
76 | processRejection :: session -> ByteString -> JID -> IO () | ||
75 | processRequest :: session -> ByteString -> JID -> IO () | 77 | processRequest :: session -> ByteString -> JID -> IO () |
76 | 78 | ||
77 | -- | Jabber ID (JID) datatype | 79 | -- | Jabber ID (JID) datatype |
@@ -95,12 +97,18 @@ data RosterEvent = RequestedSubscription | |||
95 | | NewBuddy | 97 | | NewBuddy |
96 | {- user: -} ByteString | 98 | {- user: -} ByteString |
97 | {- contact: -} ByteString | 99 | {- contact: -} ByteString |
100 | | RemovedBuddy | ||
101 | {- user: -} ByteString | ||
102 | {- contact: -} ByteString | ||
98 | | PendingSubscriber | 103 | | PendingSubscriber |
99 | {- user: -} ByteString | 104 | {- user: -} ByteString |
100 | {- contact: -} ByteString | 105 | {- contact: -} ByteString |
101 | | NewSubscriber | 106 | | NewSubscriber |
102 | {- user: -} ByteString | 107 | {- user: -} ByteString |
103 | {- contact: -} ByteString | 108 | {- contact: -} ByteString |
109 | | RejectSubscriber | ||
110 | {- user: -} ByteString | ||
111 | {- contact: -} ByteString | ||
104 | deriving Prelude.Show | 112 | deriving Prelude.Show |
105 | 113 | ||
106 | data Peer = LocalHost | RemotePeer SockAddr | 114 | data Peer = LocalHost | RemotePeer SockAddr |
@@ -220,6 +228,7 @@ data OutBoundMessage = OutBoundPresence Presence | |||
220 | | PresenceProbe JID JID | 228 | | PresenceProbe JID JID |
221 | | Solicitation JID JID | 229 | | Solicitation JID JID |
222 | | Approval JID JID | 230 | | Approval JID JID |
231 | | Rejection JID JID | ||
223 | deriving Prelude.Show | 232 | deriving Prelude.Show |
224 | 233 | ||
225 | getNamesForPeer :: Peer -> IO [S.ByteString] | 234 | getNamesForPeer :: Peer -> IO [S.ByteString] |
diff --git a/Presence/main.hs b/Presence/main.hs index 702b98d5..781b87fa 100644 --- a/Presence/main.hs +++ b/Presence/main.hs | |||
@@ -87,6 +87,14 @@ data PresenceState = PresenceState | |||
87 | } | 87 | } |
88 | 88 | ||
89 | 89 | ||
90 | rosterPush msg state = do | ||
91 | let rchan = rosterChannel state | ||
92 | atomically $ do | ||
93 | isempty <- isEmptyTMVar rchan | ||
94 | when (not isempty) $ do | ||
95 | (_,ch) <- readTMVar rchan | ||
96 | writeTChan ch msg | ||
97 | |||
90 | getJabberUserForId muid = | 98 | getJabberUserForId muid = |
91 | maybe (return "nobody") | 99 | maybe (return "nobody") |
92 | (\(uid,_) -> | 100 | (\(uid,_) -> |
@@ -157,7 +165,7 @@ instance JabberClientSession ClientSession where | |||
157 | 165 | ||
158 | rsc <- readIORef (unix_resource s) | 166 | rsc <- readIORef (unix_resource s) |
159 | -- let jid = user <++> "@" <++> host <++?> "/" <++$> rsc | 167 | -- let jid = user <++> "@" <++> host <++?> "/" <++$> rsc |
160 | L.putStrLn $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc) | 168 | -- L.putStrLn $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc) |
161 | return (JID (Just user) host rsc) | 169 | return (JID (Just user) host rsc) |
162 | 170 | ||
163 | closeSession session = do | 171 | closeSession session = do |
@@ -228,12 +236,9 @@ instance JabberClientSession ClientSession where | |||
228 | me <- getJID s | 236 | me <- getJID s |
229 | withJust (name me) $ \user -> do | 237 | withJust (name me) $ \user -> do |
230 | addRawJid ConfigFiles.modifySolicited user jid_str | 238 | addRawJid ConfigFiles.modifySolicited user jid_str |
231 | let rchan = rosterChannel . presence_state $ s | 239 | |
232 | atomically $ do | 240 | rosterPush (RequestedSubscription user jid_str) (presence_state s) |
233 | isempty <- isEmptyTMVar rchan | 241 | |
234 | when (not isempty) $ do | ||
235 | (_,ch) <- readTMVar rchan | ||
236 | writeTChan ch (RequestedSubscription user jid_str) | ||
237 | sendMessage (outGoingConnections . presence_state $ s) | 242 | sendMessage (outGoingConnections . presence_state $ s) |
238 | (Solicitation me jid) | 243 | (Solicitation me jid) |
239 | (peer jid) | 244 | (peer jid) |
@@ -278,17 +283,14 @@ instance JabberClientSession ClientSession where | |||
278 | user <- readIORef (unix_uid s) >>= getJabberUserForId | 283 | user <- readIORef (unix_uid s) >>= getJabberUserForId |
279 | cjid <- parseHostNameJID contact | 284 | cjid <- parseHostNameJID contact |
280 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing | 285 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing |
286 | |||
287 | -- update config files | ||
281 | addRawJid ConfigFiles.modifySubscribers user contact -- add subscribers | 288 | addRawJid ConfigFiles.modifySubscribers user contact -- add subscribers |
282 | rmjid ConfigFiles.modifyPending user cjid | 289 | rmjid ConfigFiles.modifyPending user cjid |
283 | rmjid ConfigFiles.modifyOthers user cjid | 290 | rmjid ConfigFiles.modifyOthers user cjid |
284 | 291 | ||
285 | -- roster push | 292 | -- roster push |
286 | let rchan = rosterChannel . presence_state $ s | 293 | rosterPush (NewSubscriber user contact) (presence_state s) |
287 | atomically $ do | ||
288 | isempty <- isEmptyTMVar rchan | ||
289 | when (not isempty) $ do | ||
290 | (_,ch) <- readTMVar rchan | ||
291 | writeTChan ch (NewSubscriber user contact) | ||
292 | 294 | ||
293 | -- notify peer | 295 | -- notify peer |
294 | sendMessage (outGoingConnections . presence_state $ s) | 296 | sendMessage (outGoingConnections . presence_state $ s) |
@@ -300,6 +302,33 @@ instance JabberClientSession ClientSession where | |||
300 | forM_ presence $ \p -> sendMessage cons (OutBoundPresence p) (peer cjid) | 302 | forM_ presence $ \p -> sendMessage cons (OutBoundPresence p) (peer cjid) |
301 | return () | 303 | return () |
302 | 304 | ||
305 | rejectSubscriber s contact = do | ||
306 | user <- readIORef (unix_uid s) >>= getJabberUserForId | ||
307 | cjid <- parseHostNameJID contact | ||
308 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing | ||
309 | |||
310 | -- update config files | ||
311 | was_pending <- rmjid ConfigFiles.modifyPending user cjid | ||
312 | was_subscribed <- rmjid ConfigFiles.modifySubscribers user cjid | ||
313 | addRawJid ConfigFiles.modifyOthers user contact | ||
314 | |||
315 | -- roster push | ||
316 | rosterPush (RejectSubscriber user contact) (presence_state s) | ||
317 | |||
318 | -- notify peer | ||
319 | when (was_pending || was_subscribed) $ do | ||
320 | let cons = outGoingConnections . presence_state $ s | ||
321 | isonline (Presence _ Offline) = False | ||
322 | isonline _ = True | ||
323 | presence <- fmap (filter isonline) $ getUserStatus (presence_state s) user | ||
324 | me <- getJID s | ||
325 | when (not (null presence)) $ | ||
326 | sendMessage cons (OutBoundPresence . Presence me $ Offline) (peer cjid) | ||
327 | sendMessage (outGoingConnections . presence_state $ s) | ||
328 | (Rejection (JID (Just user) LocalHost Nothing) | ||
329 | cjid) | ||
330 | (peer cjid) | ||
331 | return () | ||
303 | 332 | ||
304 | tupleToJID (user,tty,pid) = jid user LocalHost tty | 333 | tupleToJID (user,tty,pid) = jid user LocalHost tty |
305 | 334 | ||
@@ -375,19 +404,24 @@ instance JabberPeerSession PeerSession where | |||
375 | solicited <- ConfigFiles.getSolicited user | 404 | solicited <- ConfigFiles.getSolicited user |
376 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing | 405 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing |
377 | was_sol <- rmjid ConfigFiles.modifySolicited user buddy | 406 | was_sol <- rmjid ConfigFiles.modifySolicited user buddy |
378 | putStrLn $ "was_sol = "<++>bshow was_sol | ||
379 | when was_sol $ do -- if buddy ∈ solicited: | 407 | when was_sol $ do -- if buddy ∈ solicited: |
380 | addJid ConfigFiles.modifyBuddies user buddy -- add buddies | 408 | addJid ConfigFiles.modifyBuddies user buddy -- add buddies |
381 | rmjid ConfigFiles.modifyOthers user buddy -- remove others | 409 | rmjid ConfigFiles.modifyOthers user buddy -- remove others |
382 | let rchan = rosterChannel . peer_global $ session | ||
383 | mbuddy <- asHostNameJID buddy | 410 | mbuddy <- asHostNameJID buddy |
384 | withJust mbuddy $ \buddy -> do | 411 | withJust mbuddy $ \buddy -> do |
385 | atomically $ do | 412 | rosterPush (NewBuddy user buddy) (peer_global session) |
386 | isempty <- isEmptyTMVar rchan | 413 | |
387 | when (not isempty) $ do | 414 | processRejection session user buddy = do |
388 | (_,ch) <- readTMVar rchan | 415 | solicited <- ConfigFiles.getSolicited user |
389 | writeTChan ch (NewBuddy user buddy) | 416 | let rmjid modify user buddy = modify user (cmpJID buddy) Nothing |
390 | return () | 417 | was_sol <- rmjid ConfigFiles.modifySolicited user buddy |
418 | when was_sol $ do -- if buddy ∈ solicited: | ||
419 | rmjid ConfigFiles.modifyBuddies user buddy -- remove buddies | ||
420 | addJid ConfigFiles.modifyOthers user buddy -- add others | ||
421 | mbuddy <- asHostNameJID buddy | ||
422 | withJust mbuddy $ \buddy -> do | ||
423 | rosterPush (RemovedBuddy user buddy) (peer_global session) | ||
424 | |||
391 | processRequest session user buddy = do | 425 | processRequest session user buddy = do |
392 | let addjid modify user buddy = do | 426 | let addjid modify user buddy = do |
393 | hbuddy <- asHostNameJID buddy | 427 | hbuddy <- asHostNameJID buddy |
@@ -403,14 +437,9 @@ instance JabberPeerSession PeerSession where | |||
403 | -- contact ∉ subscribers & contact ∈ pending --> SHOULD NOT | 437 | -- contact ∉ subscribers & contact ∈ pending --> SHOULD NOT |
404 | -- contact ∉ subscribers & contact ∉ pending --> MUST | 438 | -- contact ∉ subscribers & contact ∉ pending --> MUST |
405 | when (not was_pending) $ do | 439 | when (not was_pending) $ do |
406 | let rchan = rosterChannel . peer_global $ session | ||
407 | mbuddy <- asHostNameJID buddy | 440 | mbuddy <- asHostNameJID buddy |
408 | withJust mbuddy $ \buddy -> do | 441 | withJust mbuddy $ \buddy -> do |
409 | atomically $ do | 442 | rosterPush (PendingSubscriber user buddy) (peer_global session) |
410 | isempty <- isEmptyTMVar rchan | ||
411 | when (not isempty) $ do | ||
412 | (_,ch) <- readTMVar rchan | ||
413 | writeTChan ch (PendingSubscriber user buddy) | ||
414 | 443 | ||
415 | 444 | ||
416 | data RefCountedChan = forall a. RefCountedChan (TMVar (RefCount,TChan a)) | 445 | data RefCountedChan = forall a. RefCountedChan (TMVar (RefCount,TChan a)) |