diff options
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r-- | Presence/XMPP.hs | 83 |
1 files changed, 54 insertions, 29 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index e4f60712..9190ee3c 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -76,7 +76,6 @@ import qualified Data.Text as S (takeWhile) | |||
76 | import Data.Text.Encoding as S (decodeUtf8,encodeUtf8) | 76 | import Data.Text.Encoding as S (decodeUtf8,encodeUtf8) |
77 | import Data.Text.Lazy.Encoding as L (decodeUtf8,encodeUtf8) | 77 | import Data.Text.Lazy.Encoding as L (decodeUtf8,encodeUtf8) |
78 | import Data.Text.Lazy (toStrict) | 78 | import Data.Text.Lazy (toStrict) |
79 | import GetHostByAddr | ||
80 | import Data.Monoid | 79 | import Data.Monoid |
81 | import qualified Data.Sequence as Seq | 80 | import qualified Data.Sequence as Seq |
82 | import Data.Foldable (toList) | 81 | import Data.Foldable (toList) |
@@ -106,13 +105,6 @@ data Commands = | |||
106 | | QuitThread | 105 | | QuitThread |
107 | deriving Prelude.Show | 106 | deriving Prelude.Show |
108 | 107 | ||
109 | getNamesForPeer :: Peer -> IO [ByteString] | ||
110 | getNamesForPeer LocalHost = fmap ((:[]) . S.pack) getHostName | ||
111 | getNamesForPeer peer@(RemotePeer addr) = do | ||
112 | ent <- getHostByAddr addr -- AF_UNSPEC addr | ||
113 | let names = hostName ent : hostAliases ent | ||
114 | return . map S.pack $ names | ||
115 | |||
116 | 108 | ||
117 | xmlifyPresenceForClient :: Presence -> IO [XML.Event] | 109 | xmlifyPresenceForClient :: Presence -> IO [XML.Event] |
118 | xmlifyPresenceForClient (Presence jid stat) = do | 110 | xmlifyPresenceForClient (Presence jid stat) = do |
@@ -343,7 +335,9 @@ iq_service_unavailable host iq_id mjid req = | |||
343 | , EventEndElement "{jabber:client}iq" | 335 | , EventEndElement "{jabber:client}iq" |
344 | ] | 336 | ] |
345 | 337 | ||
346 | attr name value = (name,[ContentText value]) | 338 | attr name value = (name,[ContentText value]) |
339 | attrbs name value = (name,[ContentText (toStrict . L.decodeUtf8 $ value)]) | ||
340 | |||
347 | 341 | ||
348 | getRoster session iqid = do | 342 | getRoster session iqid = do |
349 | let getlist f = do | 343 | let getlist f = do |
@@ -524,6 +518,25 @@ toClient session pchan cmdChan rchan = toClient' False False | |||
524 | r <- liftIO $ rosterPush jid (toStrict . L.decodeUtf8 $ contact) [attr "ask" "subscribe"] | 518 | r <- liftIO $ rosterPush jid (toStrict . L.decodeUtf8 $ contact) [attr "ask" "subscribe"] |
525 | send r | 519 | send r |
526 | loop | 520 | loop |
521 | RChan (NewBuddy who contact) -> do | ||
522 | liftIO . putStrLn $ "Roster push: NewBuddy "++show (isInterested,who,contact) | ||
523 | jid <- liftIO $ getJID session | ||
524 | when (isInterested && Just who==name jid) $ do | ||
525 | send [ EventBeginElement "{jabber:client}presence" | ||
526 | [ attrbs "from" contact | ||
527 | , attrbs "to" (L.show jid) | ||
528 | , attr "type" "subscribed" | ||
529 | ] | ||
530 | , EventEndElement "{jabber:client}presence" ] | ||
531 | let f True = "from" | ||
532 | f False = "to" | ||
533 | subscription <- fmap f (liftIO $ isSubscribed session contact) | ||
534 | r <- liftIO . handleIO (\e -> putStrLn ("Roster NewBuddy error: "++show e) >> return []) $ do | ||
535 | rosterPush jid | ||
536 | (toStrict . L.decodeUtf8 $ contact) | ||
537 | [attr "subscription" subscription] | ||
538 | send r | ||
539 | loop | ||
527 | PChan presence -> do | 540 | PChan presence -> do |
528 | when isBound $ do | 541 | when isBound $ do |
529 | xs <- liftIO $ xmlifyPresenceForClient presence | 542 | xs <- liftIO $ xmlifyPresenceForClient presence |
@@ -552,7 +565,7 @@ handleClient st src snk = do | |||
552 | =$= discardFlush | 565 | =$= discardFlush |
553 | =$ snk ) | 566 | =$ snk ) |
554 | #else | 567 | #else |
555 | writer <- async ( toClient pchan cmdChan $$ renderChunks =$ snk ) | 568 | writer <- async ( toClient session pchan cmdChan rchan $$ renderChunks =$ snk ) |
556 | #endif | 569 | #endif |
557 | finally ( src $= parseBytes def $$ fromClient session cmdChan ) | 570 | finally ( src $= parseBytes def $$ fromClient session cmdChan ) |
558 | $ do | 571 | $ do |
@@ -752,31 +765,45 @@ clientRequestsSubscription session cmdChan stanza = do | |||
752 | atomically $ writeTChan cmdChan (Send r) | 765 | atomically $ writeTChan cmdChan (Send r) |
753 | return () | 766 | return () |
754 | 767 | ||
768 | |||
769 | stanzaFromTo :: | ||
770 | JabberPeerSession session => | ||
771 | session -> Event -> IO (Maybe (JID, JID)) | ||
772 | stanzaFromTo session stanza = | ||
773 | let lookup key = fmap textToByteString (lookupAttrib key (tagAttrs stanza)) | ||
774 | parse jidstr = handleIO_ (return Nothing) (fmap Just $ parseAddressJID jidstr) | ||
775 | in case liftM2 (,) (lookup "from") (lookup "to") of | ||
776 | Nothing -> return Nothing | ||
777 | Just (from,to) -> do | ||
778 | mfrom <- parse from | ||
779 | mto <- parse to | ||
780 | case liftM2 (,) mfrom mto of | ||
781 | Nothing -> return Nothing | ||
782 | Just (from,to) -> do | ||
783 | let fromjid = JID (name from) (peerAddress session) Nothing | ||
784 | return $ Just (fromjid,to) | ||
785 | |||
755 | peerRequestsSubsription session stanza = do | 786 | peerRequestsSubsription session stanza = do |
756 | liftIO $ putStrLn $ "PEER PRESENCE SUBSCRIBE " ++ show stanza | 787 | liftIO $ putStrLn $ "PEER PRESENCE SUBSCRIBE " ++ show stanza |
757 | withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from0-> do | 788 | |
758 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to0 -> do | 789 | whenJust (liftIO . handleIO (\e -> putStrLn ("peerRequestsSubsription: "++show e) >> return Nothing) |
759 | let to = textToByteString to0 | 790 | $ stanzaFromTo session stanza) $ \(fromjid,tojid) -> do |
760 | from = textToByteString from0 | ||
761 | factory = peerSessionFactory session | ||
762 | mjid <- liftIO $ handleIO_ (return Nothing) (fmap Just $ parseAddressJID to) | ||
763 | mfrom <- liftIO $ handleIO_ (return Nothing) (fmap Just $ parseAddressJID from) | ||
764 | withJust (mfrom >>= name) $ \from -> do | ||
765 | withJust mjid $ \tojid -> do | ||
766 | withJust (name tojid) $ \user -> do | 791 | withJust (name tojid) $ \user -> do |
792 | |||
767 | subs <- liftIO $ do | 793 | subs <- liftIO $ do |
768 | subs <- getSubscribers factory user | 794 | subs <- getSubscribers (peerSessionFactory session) user |
769 | msubs <- flip mapM subs $ \str -> do | 795 | msubs <- flip mapM subs $ \str -> do |
770 | handleIO_ (return Nothing) | 796 | handleIO_ (return Nothing) |
771 | (fmap Just $ parseHostNameJID str) | 797 | (fmap Just $ parseHostNameJID str) |
772 | return (catMaybes msubs) | 798 | return (catMaybes msubs) |
773 | let peer = peerAddress session | ||
774 | fromjid = JID (Just from) peer Nothing | ||
775 | if elem fromjid subs | 799 | if elem fromjid subs |
776 | then do | 800 | then do |
777 | liftIO . L.putStrLn $ bshow fromjid <++> " already subscribed to " <++> user | 801 | liftIO . L.putStrLn $ bshow fromjid <++> " already subscribed to " <++> user |
778 | -- if already subscribed, reply | 802 | -- if already subscribed, reply |
779 | liftIO $ sendPeerMessage session (Approval tojid fromjid) | 803 | liftIO $ do |
804 | sendPeerMessage session (Approval tojid fromjid) | ||
805 | ps <- userStatus session user | ||
806 | mapM_ (announcePresence session) ps | ||
780 | else | 807 | else |
781 | -- TODO | 808 | -- TODO |
782 | -- if no client: | 809 | -- if no client: |
@@ -796,12 +823,10 @@ clientApprovesSubscription session stanza = do | |||
796 | 823 | ||
797 | peerApprovesSubscription session stanza = do | 824 | peerApprovesSubscription session stanza = do |
798 | liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" | 825 | liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" |
799 | -- if solicited: | 826 | whenJust (liftIO . handleIO (\e -> putStrLn ("peerApprovesSubscription: "++show e) >> return Nothing) |
800 | -- add buddies | 827 | $ stanzaFromTo session stanza) $ \(fromjid,tojid) -> do |
801 | -- remove others | 828 | withJust (name tojid) $ \user -> do |
802 | -- remove solicited | 829 | liftIO $ processApproval session user fromjid |
803 | -- notify client | ||
804 | return () | ||
805 | 830 | ||
806 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => | 831 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => |
807 | session -> Sink XML.Event m () | 832 | session -> Sink XML.Event m () |