summaryrefslogtreecommitdiff
path: root/Presence/XMPP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r--Presence/XMPP.hs83
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)
76import Data.Text.Encoding as S (decodeUtf8,encodeUtf8) 76import Data.Text.Encoding as S (decodeUtf8,encodeUtf8)
77import Data.Text.Lazy.Encoding as L (decodeUtf8,encodeUtf8) 77import Data.Text.Lazy.Encoding as L (decodeUtf8,encodeUtf8)
78import Data.Text.Lazy (toStrict) 78import Data.Text.Lazy (toStrict)
79import GetHostByAddr
80import Data.Monoid 79import Data.Monoid
81import qualified Data.Sequence as Seq 80import qualified Data.Sequence as Seq
82import Data.Foldable (toList) 81import Data.Foldable (toList)
@@ -106,13 +105,6 @@ data Commands =
106 | QuitThread 105 | QuitThread
107 deriving Prelude.Show 106 deriving Prelude.Show
108 107
109getNamesForPeer :: Peer -> IO [ByteString]
110getNamesForPeer LocalHost = fmap ((:[]) . S.pack) getHostName
111getNamesForPeer 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
117xmlifyPresenceForClient :: Presence -> IO [XML.Event] 109xmlifyPresenceForClient :: Presence -> IO [XML.Event]
118xmlifyPresenceForClient (Presence jid stat) = do 110xmlifyPresenceForClient (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
346attr name value = (name,[ContentText value]) 338attr name value = (name,[ContentText value])
339attrbs name value = (name,[ContentText (toStrict . L.decodeUtf8 $ value)])
340
347 341
348getRoster session iqid = do 342getRoster 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
769stanzaFromTo ::
770 JabberPeerSession session =>
771 session -> Event -> IO (Maybe (JID, JID))
772stanzaFromTo 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
755peerRequestsSubsription session stanza = do 786peerRequestsSubsription 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
797peerApprovesSubscription session stanza = do 824peerApprovesSubscription 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
806fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => 831fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) =>
807 session -> Sink XML.Event m () 832 session -> Sink XML.Event m ()