summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2018-06-22 04:44:50 -0400
committerjoe <joe@jerkface.net>2018-06-22 04:44:50 -0400
commit6bbc15735f6e28740c0e05fc8219fd83a5a464a4 (patch)
tree7bfef6823a2c1d88a71ef27c0f2bb3f3600ca59a /Presence
parent716f51cce4ab52b3f67567b405e6455f0752e10c (diff)
It sends tox-messages to pidgin!
Diffstat (limited to 'Presence')
-rw-r--r--Presence/ConfigFiles.hs8
-rw-r--r--Presence/ConsoleWriter.hs23
-rw-r--r--Presence/Presence.hs60
3 files changed, 58 insertions, 33 deletions
diff --git a/Presence/ConfigFiles.hs b/Presence/ConfigFiles.hs
index 5682ea94..46d5a01c 100644
--- a/Presence/ConfigFiles.hs
+++ b/Presence/ConfigFiles.hs
@@ -16,6 +16,8 @@ import ByteStringOperators () -- For NFData instance
16import Data.List (partition) 16import Data.List (partition)
17import Data.Maybe (catMaybes,isJust) 17import Data.Maybe (catMaybes,isJust)
18 18
19import DPut
20
19type User = ByteString 21type User = ByteString
20type Profile = String 22type Profile = String
21 23
@@ -36,9 +38,15 @@ configPath :: User -> Profile -> String -> IO String
36configPath user "." filename = do 38configPath user "." filename = do
37 ue <- getUserEntryForName (unpack user) 39 ue <- getUserEntryForName (unpack user)
38 return $ (++("/"++configDir++"/"++filename)) $ homeDirectory ue 40 return $ (++("/"++configDir++"/"++filename)) $ homeDirectory ue
41 `catchIOError` \e -> do
42 dput XJabber $ "configPath " ++ show user ++ "\".\": " ++ show e
43 return $ (++("/"++configDir++"/"++filename)) $ "/tmp"
39configPath user profile filename = do 44configPath user profile filename = do
40 ue <- getUserEntryForName (unpack user) 45 ue <- getUserEntryForName (unpack user)
41 return $ (++("/"++configDir++"/"++profile++"/"++filename)) $ homeDirectory ue 46 return $ (++("/"++configDir++"/"++profile++"/"++filename)) $ homeDirectory ue
47 `catchIOError` \e -> do
48 dput XJabber $ "configPath " ++ show user ++ " " ++ show profile ++ ": " ++ show e
49 return $ (++("/"++configDir++"/"++filename)) $ "/tmp"
42 50
43createConfigFile :: ByteString -> FilePath -> IO () 51createConfigFile :: ByteString -> FilePath -> IO ()
44createConfigFile tag path = do 52createConfigFile tag path = do
diff --git a/Presence/ConsoleWriter.hs b/Presence/ConsoleWriter.hs
index 6b611e68..7c377d83 100644
--- a/Presence/ConsoleWriter.hs
+++ b/Presence/ConsoleWriter.hs
@@ -23,6 +23,7 @@ import System.Posix.Process ( forkProcess, exitImmediately, executeFile )
23import System.Posix.User ( setUserID, getUserEntryForName, userID ) 23import System.Posix.User ( setUserID, getUserEntryForName, userID )
24import System.Posix.Files ( getFileStatus, fileMode ) 24import System.Posix.Files ( getFileStatus, fileMode )
25import System.INotify ( initINotify, EventVariety(Modify), addWatch ) 25import System.INotify ( initINotify, EventVariety(Modify), addWatch )
26import System.IO.Error
26import Data.Word ( Word8 ) 27import Data.Word ( Word8 )
27import Data.Text ( Text ) 28import Data.Text ( Text )
28import Data.Map ( Map ) 29import Data.Map ( Map )
@@ -34,6 +35,7 @@ import qualified Data.Text as Text
34-- import qualified Data.Text.IO as Text 35-- import qualified Data.Text.IO as Text
35import qualified Network.BSD as BSD 36import qualified Network.BSD as BSD
36 37
38import DPut
37import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) 39import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) )
38import FGConsole ( forkTTYMonitor ) 40import FGConsole ( forkTTYMonitor )
39import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType 41import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType
@@ -256,14 +258,19 @@ deliverGUIMessage cw tty utmp msg = do
256 Nothing -> t 258 Nothing -> t
257 putStrLn $ "deliverGUI: " ++ text 259 putStrLn $ "deliverGUI: " ++ text
258 handleIO_ (return False) $ do 260 handleIO_ (return False) $ do
259 uentry <- getUserEntryForName (Text.unpack $ utmpUser utmp) 261 muentry <- fmap Just (getUserEntryForName (Text.unpack $ utmpUser utmp))
260 let display = Text.unpack $ utmpHost utmp 262 `catchIOError` \e -> do
261 pid <- forkProcess $ do 263 dput XJabber $ "deliverGUIMessage(getUserEntryForName "++show (utmpUser utmp)++"): "++show e
262 setUserID (userID uentry) 264 return Nothing
263 setEnv "DISPLAY" display True 265 forM_ muentry $ \uentry -> do
264 -- rawSystem "/usr/bin/notify-send" [text] 266 let display = Text.unpack $ utmpHost utmp
265 executeFile "/usr/bin/notify-send" False [text] (Just [("DISPLAY",display)]) 267 pid <- forkProcess $ do
266 exitImmediately ExitSuccess 268 setUserID (userID uentry)
269 setEnv "DISPLAY" display True
270 -- rawSystem "/usr/bin/notify-send" [text]
271 executeFile "/usr/bin/notify-send" False [text] (Just [("DISPLAY",display)])
272 exitImmediately ExitSuccess
273 return ()
267 return True 274 return True
268 275
269crlf :: Text -> Text 276crlf :: Text -> Text
diff --git a/Presence/Presence.hs b/Presence/Presence.hs
index daa93716..697c1476 100644
--- a/Presence/Presence.hs
+++ b/Presence/Presence.hs
@@ -99,8 +99,8 @@ data ToxManager k = ToxManager
99 99
100data PresenceState = forall status. PresenceState 100data PresenceState = forall status. PresenceState
101 { clients :: TVar (Map ConnectionKey ClientState) 101 { clients :: TVar (Map ConnectionKey ClientState)
102 , clientsByUser :: TVar (Map Text LocalPresence) -- TODO: For tox-enabled clients, the lookup key should be the client's toxid 102 , clientsByUser :: TVar (Map Text LocalPresence)
103 -- rather than the unix user. 103 , clientsByProfile :: TVar (Map Text LocalPresence)
104 , remotesByPeer :: TVar (Map ConnectionKey 104 , remotesByPeer :: TVar (Map ConnectionKey
105 (Map UserName RemotePresence)) 105 (Map UserName RemotePresence))
106 , server :: TMVar (XMPPServer, Connection.Manager status Text) 106 , server :: TMVar (XMPPServer, Connection.Manager status Text)
@@ -115,18 +115,20 @@ newPresenceState :: Maybe ConsoleWriter
115 -> TMVar (XMPPServer, Connection.Manager status Text) 115 -> TMVar (XMPPServer, Connection.Manager status Text)
116 -> IO PresenceState 116 -> IO PresenceState
117newPresenceState cw toxman xmpp = atomically $ do 117newPresenceState cw toxman xmpp = atomically $ do
118 clients <- newTVar Map.empty 118 clients <- newTVar Map.empty
119 clientsByUser <- newTVar Map.empty 119 clientsByUser <- newTVar Map.empty
120 remotesByPeer <- newTVar Map.empty 120 clientsByProfile <- newTVar Map.empty
121 keyToChan <- newTVar Map.empty 121 remotesByPeer <- newTVar Map.empty
122 keyToChan <- newTVar Map.empty
122 let st = PresenceState 123 let st = PresenceState
123 { clients = clients 124 { clients = clients
124 , clientsByUser = clientsByUser 125 , clientsByUser = clientsByUser
125 , remotesByPeer = remotesByPeer 126 , clientsByProfile = clientsByProfile
126 , keyToChan = keyToChan 127 , remotesByPeer = remotesByPeer
127 , server = xmpp 128 , keyToChan = keyToChan
128 , consoleWriter = cw 129 , server = xmpp
129 , toxManager = Nothing 130 , consoleWriter = cw
131 , toxManager = Nothing
130 } 132 }
131 return $ st { toxManager = fmap ($ st) toxman } 133 return $ st { toxManager = fmap ($ st) toxman }
132 134
@@ -277,10 +279,11 @@ chooseResourceName state k addr clientsNameForMe desired = do
277 279
278 atomically $ do 280 atomically $ do
279 modifyTVar' (clients state) $ Map.insert k client 281 modifyTVar' (clients state) $ Map.insert k client
280 modifyTVar' (clientsByUser state) $ flip Map.alter (clientUser client) 282 let add mb = Just $ maybe (pcSingletonNetworkClient k client)
281 $ \mb -> Just $ maybe (pcSingletonNetworkClient k client)
282 (pcInsertNetworkClient k client) 283 (pcInsertNetworkClient k client)
283 mb 284 mb
285 modifyTVar' (clientsByUser state) $ Map.alter add (clientUser client)
286 modifyTVar' (clientsByProfile state) $ Map.alter add (clientProfile client)
284 287
285 localJID (clientUser client) (clientProfile client) (clientResource client) 288 localJID (clientUser client) (clientProfile client) (clientResource client)
286 289
@@ -477,8 +480,8 @@ eofConn state k = do
477 stanza <- makePresenceStanza "jabber:server" Nothing Offline 480 stanza <- makePresenceStanza "jabber:server" Nothing Offline
478 informClientPresence state k stanza 481 informClientPresence state k stanza
479 atomically $ do 482 atomically $ do
480 modifyTVar' (clientsByUser state) 483 modifyTVar' (clientsByUser state) $ Map.alter (delclient k) (clientUser client)
481 $ Map.alter (delclient k) (clientUser client) 484 modifyTVar' (clientsByProfile state) $ Map.alter (delclient k) (clientProfile client)
482 PeerKey {} -> do 485 PeerKey {} -> do
483 let h = peerKeyToText k 486 let h = peerKeyToText k
484 jids <- atomically $ do 487 jids <- atomically $ do
@@ -600,24 +603,31 @@ deliverMessage state fail msg =
600 (mine,(n,h,r)) <- rewriteJIDForClient laddr to [] 603 (mine,(n,h,r)) <- rewriteJIDForClient laddr to []
601 if not mine then fail else do 604 if not mine then fail else do
602 let to' = unsplitJID (n,h,r) 605 let to' = unsplitJID (n,h,r)
603 cmap <- atomically . readTVar $ clientsByUser state 606 let (cmapVar,ckey) = case ctyp of
607 Tox -> (clientsByProfile state , n <&> (<> ".tox") )
608 XMPP -> (clientsByUser state , n )
609 cmap <- atomically . readTVar $ cmapVar
604 chans <- fmap (fromMaybe []) $ do 610 chans <- fmap (fromMaybe []) $ do
605 -- TODO: Tox-enabled clients need to be found by tox key. 611 forM (ckey >>= flip Map.lookup cmap) $ \presence_container -> do
606 forM (n >>= flip Map.lookup cmap) $ \presence_container -> do
607 let ks = Map.keys (networkClients presence_container) 612 let ks = Map.keys (networkClients presence_container)
608 chans = do 613 chans = do
609 (k,client) <- Map.toList $ networkClients presence_container 614 (k,client) <- Map.toList $ networkClients presence_container
610 chan <- maybeToList $ Map.lookup k key_to_chan 615 chan <- maybeToList $ Map.lookup k key_to_chan
611 return (clientProfile client, chan) 616 return (clientProfile client, clientUser client, chan)
612 forM chans $ \(profile,chan) -> do 617 forM chans $ \(profile,user,chan) -> do
613 buds <- configText ConfigFiles.getBuddies (fromJust n) profile 618 buds <- configText ConfigFiles.getBuddies user profile
614 from' <- do 619 from' <- case ctyp of
620 Tox -> return $ stanzaFrom msg
621 XMPP -> do
615 forM (stanzaFrom msg) $ \from -> do 622 forM (stanzaFrom msg) $ \from -> do
616 (_,trip) <- rewriteJIDForClient laddr from buds 623 (_,trip) <- rewriteJIDForClient laddr from buds
617 return $ unsplitJID trip 624 return $ unsplitJID trip
625 to' <- case ctyp of
626 XMPP -> return $ stanzaTo msg
627 Tox -> return $ Just $ unsplitJID (Just user, profile, Nothing)
618 return (from',chan) 628 return (from',chan)
619 putStrLn $ "chan count: " ++ show (length chans) 629 putStrLn $ "chan count: " ++ show (length chans)
620 if null chans then do 630 if null chans then when (ctyp == XMPP) $ do
621 forM_ (stanzaFrom msg) $ \from -> do 631 forM_ (stanzaFrom msg) $ \from -> do
622 from' <- do 632 from' <- do
623 -- Fallback to "." profile when no clients. 633 -- Fallback to "." profile when no clients.