diff options
-rw-r--r-- | Presence/ControlMaybe.hs | 4 | ||||
-rw-r--r-- | Presence/XMPP.hs | 67 | ||||
-rw-r--r-- | Presence/XMPPTypes.hs | 1 | ||||
-rw-r--r-- | Presence/main.hs | 4 |
4 files changed, 65 insertions, 11 deletions
diff --git a/Presence/ControlMaybe.hs b/Presence/ControlMaybe.hs index 37f6f93c..69a38f71 100644 --- a/Presence/ControlMaybe.hs +++ b/Presence/ControlMaybe.hs | |||
@@ -15,5 +15,9 @@ whenJust acn f = do | |||
15 | catchIO_ :: IO a -> IO a -> IO a | 15 | catchIO_ :: IO a -> IO a -> IO a |
16 | catchIO_ a h = Exception.catch a (\(_ :: IOException) -> h) | 16 | catchIO_ a h = Exception.catch a (\(_ :: IOException) -> h) |
17 | 17 | ||
18 | catchIO :: IO a -> (IOException -> IO a) -> IO a | ||
19 | catchIO body handler = Exception.catch body handler | ||
20 | |||
18 | handleIO_ = flip catchIO_ | 21 | handleIO_ = flip catchIO_ |
22 | handleIO = flip catchIO | ||
19 | 23 | ||
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index 7b01711e..1520839e 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -62,6 +62,7 @@ import Control.Exception | |||
62 | , finally | 62 | , finally |
63 | , bracketOnError ) | 63 | , bracketOnError ) |
64 | import GHC.IO.Exception (IOException(..)) | 64 | import GHC.IO.Exception (IOException(..)) |
65 | import System.IO.Error (isDoesNotExistError) | ||
65 | import Control.Monad.IO.Class | 66 | import Control.Monad.IO.Class |
66 | import Control.Monad.Trans.Class | 67 | import Control.Monad.Trans.Class |
67 | import Control.Monad.Trans.Maybe | 68 | import Control.Monad.Trans.Maybe |
@@ -93,7 +94,11 @@ import GHC.Conc | |||
93 | , ThreadId | 94 | , ThreadId |
94 | ) | 95 | ) |
95 | 96 | ||
96 | data Commands = Send [XML.Event] | QuitThread | 97 | data Commands = |
98 | Send [XML.Event] | ||
99 | | BoundToResource | ||
100 | | InterestedInRoster | ||
101 | | QuitThread | ||
97 | deriving Prelude.Show | 102 | deriving Prelude.Show |
98 | 103 | ||
99 | getNamesForPeer :: Peer -> IO [ByteString] | 104 | getNamesForPeer :: Peer -> IO [ByteString] |
@@ -260,7 +265,9 @@ handleIQSetBind session cmdChan stanza_id = do | |||
260 | L.putStrLn $ "iq-set-bind-resource " <++> rsc | 265 | L.putStrLn $ "iq-set-bind-resource " <++> rsc |
261 | setResource session rsc | 266 | setResource session rsc |
262 | jid <- getJID session | 267 | jid <- getJID session |
263 | atomically $ writeTChan cmdChan (Send $ iq_bind_reply stanza_id (toStrict $ L.decodeUtf8 $ L.show jid) ) | 268 | atomically $ do |
269 | writeTChan cmdChan (Send $ iq_bind_reply stanza_id (toStrict $ L.decodeUtf8 $ L.show jid) ) | ||
270 | writeTChan cmdChan BoundToResource | ||
264 | forCachedPresence session $ \presence -> do | 271 | forCachedPresence session $ \presence -> do |
265 | xs <- xmlifyPresenceForClient presence | 272 | xs <- xmlifyPresenceForClient presence |
266 | atomically . writeTChan cmdChan . Send $ xs | 273 | atomically . writeTChan cmdChan . Send $ xs |
@@ -410,7 +417,9 @@ handleIQGet session cmdChan tag = do | |||
410 | -- ,(Name {nameLocalName = "type", nameNamespace = Nothing, namePrefix = Nothing}, | 417 | -- ,(Name {nameLocalName = "type", nameNamespace = Nothing, namePrefix = Nothing}, |
411 | -- [ContentText "get"])] | 418 | -- [ContentText "get"])] |
412 | roster <- getRoster session stanza_id | 419 | roster <- getRoster session stanza_id |
413 | atomically . writeTChan cmdChan . Send $ roster | 420 | atomically $ do |
421 | writeTChan cmdChan InterestedInRoster | ||
422 | writeTChan cmdChan . Send $ roster | ||
414 | req -> unhandledGet req | 423 | req -> unhandledGet req |
415 | 424 | ||
416 | 425 | ||
@@ -436,15 +445,17 @@ fromClient session cmdChan = doNestingXML $ do | |||
436 | whenJust nextElement $ \stanza -> do | 445 | whenJust nextElement $ \stanza -> do |
437 | stanza_lvl <- nesting | 446 | stanza_lvl <- nesting |
438 | 447 | ||
448 | liftIO . putStrLn $ "stanza: "++show stanza | ||
449 | |||
439 | let unhandledStanza = do | 450 | let unhandledStanza = do |
440 | xs <- gatherElement stanza Seq.empty | 451 | xs <- gatherElement stanza Seq.empty |
441 | prettyPrint "unhandled-C: " (toList xs) | 452 | prettyPrint "unhandled-C: " (toList xs) |
442 | case () of | 453 | case () of |
443 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza | 454 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza |
444 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza | 455 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza |
445 | _ | stanza `isPresenceOf` presenceTypeSubscribe | 456 | _ | stanza `isClientPresenceOf` presenceTypeSubscribe |
446 | -> clientRequestsSubscription session stanza | 457 | -> clientRequestsSubscription session cmdChan stanza |
447 | _ | stanza `isPresenceOf` presenceTypeSubscribed | 458 | _ | stanza `isClientPresenceOf` presenceTypeSubscribed |
448 | -> clientApprovesSubscription session stanza | 459 | -> clientApprovesSubscription session stanza |
449 | _ | otherwise -> unhandledStanza | 460 | _ | otherwise -> unhandledStanza |
450 | 461 | ||
@@ -468,6 +479,7 @@ toClient pchan cmdChan = fix $ \loop -> do | |||
468 | case event of | 479 | case event of |
469 | Right QuitThread -> return () | 480 | Right QuitThread -> return () |
470 | Right (Send xs) -> send xs >> loop | 481 | Right (Send xs) -> send xs >> loop |
482 | Right cmd -> liftIO (putStrLn $ "unhandled event: "++show cmd) >> loop | ||
471 | Left presence -> do | 483 | Left presence -> do |
472 | xs <- liftIO $ xmlifyPresenceForClient presence | 484 | xs <- liftIO $ xmlifyPresenceForClient presence |
473 | send xs | 485 | send xs |
@@ -610,6 +622,12 @@ isPresenceOf (EventBeginElement name attrs) testType | |||
610 | = True | 622 | = True |
611 | isPresenceOf _ _ = False | 623 | isPresenceOf _ _ = False |
612 | 624 | ||
625 | isClientPresenceOf (EventBeginElement name attrs) testType | ||
626 | | name=="{jabber:client}presence" | ||
627 | && matchAttribMaybe "type" testType attrs | ||
628 | = True | ||
629 | isClientPresenceOf _ _ = False | ||
630 | |||
613 | handlePresenceProbe session stanza = do | 631 | handlePresenceProbe session stanza = do |
614 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do | 632 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do |
615 | -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do | 633 | -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do |
@@ -638,7 +656,22 @@ subscribeToPresence subscribers peer_jid user = do | |||
638 | 656 | ||
639 | bare (JID n host _) = JID n host Nothing | 657 | bare (JID n host _) = JID n host Nothing |
640 | 658 | ||
641 | clientRequestsSubscription session stanza = do | 659 | presenceErrorRemoteNotFound iqid from to = return |
660 | [ EventBeginElement "{stream:client}presence" | ||
661 | ( case iqid of { Nothing -> id; Just iqid -> ( attr "id" iqid :) } | ||
662 | $ [ attr "from" to | ||
663 | , attr "type" "error" | ||
664 | ] ) | ||
665 | , EventBeginElement "{stream:client}error" | ||
666 | [ attr "type" "modify"] | ||
667 | , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-stanzas}remote-server-not-found" | ||
668 | [] | ||
669 | , EventEndElement "{urn:ietf:params:xml:ns:xmpp-stanzas}remote-server-not-found" | ||
670 | , EventEndElement "{stream:client}error" | ||
671 | , EventEndElement "{stream:client}presence" | ||
672 | ] | ||
673 | |||
674 | clientRequestsSubscription session cmdChan stanza = do | ||
642 | -- make bare jid | 675 | -- make bare jid |
643 | -- check local server and obey rules 3.1.3 of rfc 6121 | 676 | -- check local server and obey rules 3.1.3 of rfc 6121 |
644 | -- or forward to remote peer | 677 | -- or forward to remote peer |
@@ -646,10 +679,22 @@ clientRequestsSubscription session stanza = do | |||
646 | -- if not bailed, | 679 | -- if not bailed, |
647 | -- add to solicited | 680 | -- add to solicited |
648 | -- do roster push with subscription=none ask=subscribe | 681 | -- do roster push with subscription=none ask=subscribe |
649 | liftIO $ putStrLn $ "CLIENT PRESENCE SUBSCRIBE " ++ show stanza | 682 | liftIO $ do |
650 | -- add solicited | 683 | putStrLn $ "CLIENT PRESENCE SUBSCRIBE " ++ show stanza |
651 | -- notify other clients | 684 | withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do |
652 | -- notify peer | 685 | let from = lookupAttrib "from" (tagAttrs stanza) |
686 | iqid = lookupAttrib "id" (tagAttrs stanza) | ||
687 | let handleError e | isDoesNotExistError e = do | ||
688 | putStrLn $ "remote-server-not-found" | ||
689 | r <- presenceErrorRemoteNotFound iqid from to_str | ||
690 | atomically $ writeTChan cmdChan (Send r) | ||
691 | handleError e = do | ||
692 | putStrLn $ "ERROR: "++ show e | ||
693 | handleIO handleError $ do | ||
694 | to_jid <- parseHostNameJID (L.fromChunks [S.encodeUtf8 to_str]) | ||
695 | addSolicited session (L.fromChunks [S.encodeUtf8 to_str]) -- jid | ||
696 | putStrLn $ "added to solicited: " ++ show to_jid | ||
697 | -- TODO: create roster item and push to interested clients | ||
653 | return () | 698 | return () |
654 | 699 | ||
655 | peerRequestsSubsription session stanza = do | 700 | peerRequestsSubsription session stanza = do |
diff --git a/Presence/XMPPTypes.hs b/Presence/XMPPTypes.hs index 747ceb0e..301f19fd 100644 --- a/Presence/XMPPTypes.hs +++ b/Presence/XMPPTypes.hs | |||
@@ -44,6 +44,7 @@ class JabberClientSession session where | |||
44 | getMyOthers :: session -> IO [ByteString] | 44 | getMyOthers :: session -> IO [ByteString] |
45 | getMyPending :: session -> IO [ByteString] | 45 | getMyPending :: session -> IO [ByteString] |
46 | getMySolicited :: session -> IO [ByteString] | 46 | getMySolicited :: session -> IO [ByteString] |
47 | addSolicited :: session -> ByteString -> IO () | ||
47 | 48 | ||
48 | class JabberPeerSession session where | 49 | class JabberPeerSession session where |
49 | data XMPPPeerClass session | 50 | data XMPPPeerClass session |
diff --git a/Presence/main.hs b/Presence/main.hs index 0eae8677..bf4809a8 100644 --- a/Presence/main.hs +++ b/Presence/main.hs | |||
@@ -168,6 +168,10 @@ instance JabberClientSession ClientSession where | |||
168 | L.putStrLn $ "cached presence: " <++> bshow p | 168 | L.putStrLn $ "cached presence: " <++> bshow p |
169 | action p | 169 | action p |
170 | 170 | ||
171 | addSolicited s jid = do | ||
172 | user <- readIORef (unix_uid s) >>= getJabberUserForId | ||
173 | ConfigFiles.addSolicited user jid -- (L.show jid) | ||
174 | |||
171 | getMyBuddies s = do | 175 | getMyBuddies s = do |
172 | user <- readIORef (unix_uid s) >>= getJabberUserForId | 176 | user <- readIORef (unix_uid s) >>= getJabberUserForId |
173 | ConfigFiles.getBuddies user | 177 | ConfigFiles.getBuddies user |