diff options
Diffstat (limited to 'xmppServer.hs')
-rw-r--r-- | xmppServer.hs | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/xmppServer.hs b/xmppServer.hs index 8f13e2d8..69b6cec5 100644 --- a/xmppServer.hs +++ b/xmppServer.hs | |||
@@ -28,12 +28,17 @@ import Control.Exception ({-evaluate,-}handle,SomeException(..),bracketOnError,E | |||
28 | import System.Posix.User (getUserEntryForID,userName) | 28 | import System.Posix.User (getUserEntryForID,userName) |
29 | import qualified Data.ByteString.Lazy.Char8 as L | 29 | import qualified Data.ByteString.Lazy.Char8 as L |
30 | import qualified ConfigFiles | 30 | import qualified ConfigFiles |
31 | import Data.Maybe (listToMaybe) | ||
31 | 32 | ||
32 | import UTmp (ProcessID,users) | 33 | import UTmp (ProcessID,users) |
33 | import LocalPeerCred | 34 | import LocalPeerCred |
34 | import XMPPServer | 35 | import XMPPServer |
35 | -- import Server | 36 | -- import Server |
36 | 37 | ||
38 | unsplitJID (n,h,r) = jid | ||
39 | where | ||
40 | jid0 = maybe h (\n->n<>"@"<>h) n | ||
41 | jid = maybe jid0 (\r->jid0<>"/"<>r) r | ||
37 | 42 | ||
38 | splitJID :: Text -> (Maybe Text,Text,Maybe Text) | 43 | splitJID :: Text -> (Maybe Text,Text,Maybe Text) |
39 | splitJID bjid = | 44 | splitJID bjid = |
@@ -68,6 +73,7 @@ data PresenceState = PresenceState | |||
68 | { clients :: TVar (Map ConnectionKey ClientState) | 73 | { clients :: TVar (Map ConnectionKey ClientState) |
69 | , associatedPeers :: TVar (Map SockAddr ()) | 74 | , associatedPeers :: TVar (Map SockAddr ()) |
70 | , server :: TMVar XMPPServer | 75 | , server :: TMVar XMPPServer |
76 | , writeTos :: TVar (Map ConnectionKey (TChan Stanza)) | ||
71 | } | 77 | } |
72 | 78 | ||
73 | 79 | ||
@@ -83,7 +89,7 @@ resolvePeer addrtext = do | |||
83 | 89 | ||
84 | 90 | ||
85 | getConsolePids :: PresenceState -> IO [(Text,ProcessID)] | 91 | getConsolePids :: PresenceState -> IO [(Text,ProcessID)] |
86 | getConsolePids state = do -- return [("tty7", 23)] -- todo | 92 | getConsolePids state = do |
87 | us <- UTmp.users | 93 | us <- UTmp.users |
88 | return $ map (\(_,tty,pid)->(lazyByteStringToText tty,pid)) us | 94 | return $ map (\(_,tty,pid)->(lazyByteStringToText tty,pid)) us |
89 | 95 | ||
@@ -168,15 +174,44 @@ rosterGetSolicited = rosterGetStuff ConfigFiles.getSolicited | |||
168 | rosterGetOthers = rosterGetStuff ConfigFiles.getOthers | 174 | rosterGetOthers = rosterGetStuff ConfigFiles.getOthers |
169 | rosterGetSubscribers = rosterGetStuff ConfigFiles.getSubscribers | 175 | rosterGetSubscribers = rosterGetStuff ConfigFiles.getSubscribers |
170 | 176 | ||
177 | newConn state k outchan = | ||
178 | atomically $ modifyTVar' (writeTos state) $ Map.insert k outchan | ||
179 | |||
180 | eofConn state k = atomically $ modifyTVar' (writeTos state) $ Map.delete k | ||
181 | |||
182 | rewriteJIDForPeer :: Text -> IO (Maybe (Text,SockAddr)) | ||
183 | rewriteJIDForPeer jid = do | ||
184 | let (n,h,r) = splitJID jid | ||
185 | maddr <- fmap listToMaybe $ resolvePeer h | ||
186 | return $ flip fmap maddr $ \addr -> | ||
187 | let h' = addrToText addr | ||
188 | to' = unsplitJID (n,h',r) | ||
189 | in (to',addr) | ||
190 | |||
191 | deliverMessage state fail msg = do | ||
192 | mto <- do | ||
193 | flip (maybe $ return Nothing) (stanzaTo msg) $ \to -> do | ||
194 | rewriteJIDForPeer to | ||
195 | flip (maybe fail) mto $ \(to',addr) -> do | ||
196 | from' <- do | ||
197 | flip (maybe $ return Nothing) (stanzaFrom msg) $ \from -> do | ||
198 | m <- rewriteJIDForPeer from | ||
199 | return $ fmap fst m | ||
200 | let k = PeerKey addr | ||
201 | chans <- atomically $ readTVar (writeTos state) | ||
202 | flip (maybe fail) (Map.lookup k chans) $ \chan -> do | ||
203 | sendModifiedStanzaToPeer (msg { stanzaTo=Just to', stanzaFrom=from' }) chan | ||
171 | 204 | ||
172 | main = runResourceT $ do | 205 | main = runResourceT $ do |
173 | state <- liftIO . atomically $ do | 206 | state <- liftIO . atomically $ do |
174 | clients <- newTVar Map.empty | 207 | clients <- newTVar Map.empty |
175 | associatedPeers <- newTVar Map.empty | 208 | associatedPeers <- newTVar Map.empty |
176 | xmpp <- newEmptyTMVar | 209 | xmpp <- newEmptyTMVar |
210 | writeTos <- newTVar Map.empty | ||
177 | return PresenceState | 211 | return PresenceState |
178 | { clients = clients | 212 | { clients = clients |
179 | , associatedPeers = associatedPeers | 213 | , associatedPeers = associatedPeers |
214 | , writeTos = writeTos | ||
180 | , server = xmpp | 215 | , server = xmpp |
181 | } | 216 | } |
182 | sv <- xmppServer | 217 | sv <- xmppServer |
@@ -187,20 +222,22 @@ main = runResourceT $ do | |||
187 | , xmppTellMyNameToPeer = \addr -> return $ addrToText addr | 222 | , xmppTellMyNameToPeer = \addr -> return $ addrToText addr |
188 | , xmppTellPeerHisName = return . peerKeyToText | 223 | , xmppTellPeerHisName = return . peerKeyToText |
189 | , xmppTellClientNameOfPeer = peerKeyToResolvedName | 224 | , xmppTellClientNameOfPeer = peerKeyToResolvedName |
190 | , xmppNewConnection = \k outchan -> return () | 225 | , xmppNewConnection = newConn state |
191 | , xmppEOF = \k -> return () | 226 | , xmppEOF = eofConn state |
192 | , xmppRosterBuddies = rosterGetBuddies state | 227 | , xmppRosterBuddies = rosterGetBuddies state |
193 | , xmppRosterSubscribers = rosterGetSubscribers state | 228 | , xmppRosterSubscribers = rosterGetSubscribers state |
194 | , xmppRosterSolicited = rosterGetSolicited state | 229 | , xmppRosterSolicited = rosterGetSolicited state |
195 | , xmppRosterOthers = rosterGetOthers state | 230 | , xmppRosterOthers = rosterGetOthers state |
196 | , xmppSubscribeToRoster = \k -> return () | 231 | , xmppSubscribeToRoster = \k -> return () |
197 | -- , xmppLookupClientJID = \k -> return $ "nobody@" <> hostname <> "/tty666" | 232 | -- , xmppLookupClientJID = \k -> return $ "nobody@" <> hostname <> "/tty666" |
198 | , xmppDeliverMessage = \fail msg -> do | 233 | , {- xmppDeliverMessage = \fail msg -> do |
199 | let msgs = msgLangMap (stanzaType msg) | 234 | let msgs = msgLangMap (stanzaType msg) |
200 | body = fmap (maybe "" id . msgBody . snd) $ take 1 msgs | 235 | body = fmap (maybe "" id . msgBody . snd) $ take 1 msgs |
201 | when (not $ null body) $ do | 236 | when (not $ null body) $ do |
202 | Text.putStrLn $ "MESSAGE " <> head body | 237 | Text.putStrLn $ "MESSAGE " <> head body |
203 | return () | 238 | return () |
239 | -} | ||
240 | xmppDeliverMessage = deliverMessage state | ||
204 | , xmppInformClientPresence = \k stanza -> return () | 241 | , xmppInformClientPresence = \k stanza -> return () |
205 | } | 242 | } |
206 | liftIO $ do | 243 | liftIO $ do |