summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-06-27 22:38:53 -0400
committerjoe <joe@jerkface.net>2013-06-27 22:38:53 -0400
commit86e16f72783bcb546dd3ac447237f729e68c710d (patch)
tree14d195c6ee5770f26120612ce33ca52c337a3b91 /Presence
parent61e76eb99c74aa4c0769e2fe7f280b9a4530171d (diff)
Started conduits-based XMPP module (will replace XMPPServer)
Diffstat (limited to 'Presence')
-rw-r--r--Presence/ServerC.hs7
-rw-r--r--Presence/XMPP.hs36
-rw-r--r--Presence/XMPPServer.hs69
-rw-r--r--Presence/XMPPTypes.hs84
-rw-r--r--Presence/main.hs4
5 files changed, 133 insertions, 67 deletions
diff --git a/Presence/ServerC.hs b/Presence/ServerC.hs
index 3933c812..36e2d7bf 100644
--- a/Presence/ServerC.hs
+++ b/Presence/ServerC.hs
@@ -7,6 +7,7 @@ module ServerC
7 , ConnId(..) 7 , ConnId(..)
8 , ServerHandle 8 , ServerHandle
9 , quitListening 9 , quitListening
10 , dummyServerHandle
10 ) where 11 ) where
11 12
12import Network.Socket as Socket 13import Network.Socket as Socket
@@ -39,6 +40,7 @@ import Control.Monad.Trans.Class (lift)
39import Control.Monad.IO.Class (MonadIO (liftIO)) 40import Control.Monad.IO.Class (MonadIO (liftIO))
40import qualified Data.ByteString as S (ByteString) 41import qualified Data.ByteString as S (ByteString)
41import System.IO (Handle) 42import System.IO (Handle)
43import Control.Concurrent.MVar (newMVar)
42 44
43import ByteStringOperators 45import ByteStringOperators
44import SocketLike 46import SocketLike
@@ -50,6 +52,11 @@ newtype ConnId = ConnId Int
50 52
51newtype ServerHandle = ServerHandle Socket 53newtype ServerHandle = ServerHandle Socket
52 54
55dummyServerHandle = do
56 mvar <- newMVar Closed
57 let sock = MkSocket 0 AF_UNSPEC NoSocketType 0 mvar
58 return (ServerHandle sock)
59
53quitListening :: ServerHandle -> IO () 60quitListening :: ServerHandle -> IO ()
54quitListening (ServerHandle socket) = sClose socket 61quitListening (ServerHandle socket) = sClose socket
55 62
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
new file mode 100644
index 00000000..f361641e
--- /dev/null
+++ b/Presence/XMPP.hs
@@ -0,0 +1,36 @@
1{-# LANGUAGE FlexibleContexts #-}
2module XMPP
3 ( module XMPP
4 , module XMPPTypes
5 , quitListening
6 ) where
7
8import ServerC
9import XMPPTypes
10
11import Data.HList
12import Network.Socket (Family)
13import Network.BSD (PortNumber)
14import Control.Concurrent.STM
15
16listenForXmppClients
17 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) =>
18 Family -> XMPPClass t -> e -> l -> IO ServerHandle
19listenForXmppClients addr_family session_factory port st = do
20 putStrLn "unimplemented: listenForXmppClients"
21 dummyServerHandle
22 -- TODO
23
24listenForRemotePeers
25 :: (HList t1, HExtend e l (HCons PortNumber t1), XMPPSession t) =>
26 Family -> XMPPClass t -> e -> l -> IO ServerHandle
27listenForRemotePeers addrfamily session_factory port st = do
28 putStrLn "unimplemented: listenForRemotePeers"
29 dummyServerHandle
30 -- TODO
31
32seekRemotePeers :: XMPPConfig config =>
33 config -> TChan Presence -> IO ()
34seekRemotePeers config chan = do
35 putStrLn "unimplemented: seekRemotePeers"
36 return ()
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index e8ab5490..813c7c7b 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -6,6 +6,7 @@
6-- {-# LANGUAGE GADTs #-} 6-- {-# LANGUAGE GADTs #-}
7module XMPPServer 7module XMPPServer
8 ( module XMPPServer 8 ( module XMPPServer
9 , module XMPPTypes
9 , quitListening 10 , quitListening
10 ) where 11 ) where
11 12
@@ -58,39 +59,13 @@ import Control.Concurrent.STM
58import Control.Concurrent 59import Control.Concurrent
59import Control.Exception as Exception 60import Control.Exception as Exception
60import Text.Show.ByteString as L 61import Text.Show.ByteString as L
61import Data.Binary.Builder as B
62import Data.Binary.Put
63import qualified Data.Map as Map 62import qualified Data.Map as Map
64import GHC.Conc 63import GHC.Conc
65import Network.BSD hiding (getHostByAddr) 64import Network.BSD hiding (getHostByAddr)
66import Control.Concurrent.Async 65import Control.Concurrent.Async
67import qualified Data.Set as Set 66import qualified Data.Set as Set
68import GetHostByAddr 67import GetHostByAddr
69 68import XMPPTypes
70data Peer = LocalHost | RemotePeer SockAddr
71 deriving (Eq,Prelude.Show)
72
73instance Ord Peer where
74 LocalHost <= _
75 = True
76 RemotePeer (SockAddrUnix a) <= RemotePeer (SockAddrUnix b)
77 = a <= b
78 RemotePeer (SockAddrUnix _) <= _
79 = True
80 RemotePeer (SockAddrInet aport a) <= RemotePeer (SockAddrInet bport b)
81 = (a,aport) <= (b,bport)
82 RemotePeer (SockAddrInet aport a) <= _
83 = True
84 RemotePeer (SockAddrInet6 aport aflow a ascope) <= RemotePeer (SockAddrInet6 bport bflow b bscope)
85 = (a,aport,ascope,aflow) <= (b,bport,bscope,bflow)
86 a <= b = False
87
88-- | Jabber ID (JID) datatype
89data JID = JID { name :: Maybe ByteString
90 , peer :: Peer
91 , resource :: Maybe ByteString
92 }
93 deriving (Eq,Ord)
94 69
95is_remote (RemotePeer _) = True 70is_remote (RemotePeer _) = True
96is_remote _ = False 71is_remote _ = False
@@ -110,37 +85,10 @@ getNamesForPeer peer@(RemotePeer addr) = do
110 return . map pack $ names 85 return . map pack $ names
111 86
112 87
113showPeer :: Peer -> ByteString
114showPeer LocalHost = "localhost"
115showPeer (RemotePeer addr@(SockAddrInet _ _)) = pack $ stripColon (Prelude.show addr)
116 where stripColon s = pre where (pre,port) = break (==':') s
117showPeer (RemotePeer addr@(SockAddrInet6 _ _ _ _)) = pack $ stripColon (Prelude.show addr)
118 where stripColon s = if null bracket then pre else pre ++ "]"
119 where
120 (pre,bracket) = break (==']') s
121
122peerAddr :: Peer -> SockAddr 88peerAddr :: Peer -> SockAddr
123peerAddr (RemotePeer addr) = addr 89peerAddr (RemotePeer addr) = addr
124-- peerAddr LocalHost = throw exception 90-- peerAddr LocalHost = throw exception
125 91
126instance L.Show JID where
127 showp (JID n s r ) = putBuilder . B.fromLazyByteString $ n <$++> "@" <?++> showPeer s <++?> "/" <++$> r
128
129instance Prelude.Show JID where
130 show jid = L.unpack $ L.show jid
131
132instance NFData JID where
133 rnf v@(JID n s r) = n `seq` s `seq` r `seq` ()
134
135jid user host rsrc = JID (Just user) host (Just rsrc)
136
137data JabberShow = Offline
138 | Away
139 | Available
140 deriving (Prelude.Show,Enum,Ord,Eq,Read)
141
142data Presence = Presence JID JabberShow
143 deriving Prelude.Show
144 92
145xmlifyPresenceForPeer sock (Presence jid stat) = do 93xmlifyPresenceForPeer sock (Presence jid stat) = do
146 -- TODO: accept socket argument and determine local ip address 94 -- TODO: accept socket argument and determine local ip address
@@ -184,19 +132,6 @@ instance NFData Presence where
184 rnf (Presence jid stat) = rnf jid `seq` stat `seq` () 132 rnf (Presence jid stat) = rnf jid `seq` stat `seq` ()
185 133
186 134
187class XMPPSession session where
188 data XMPPClass session
189 newSession :: XMPPClass session -> Socket -> Handle -> IO session
190 setResource :: session -> ByteString -> IO ()
191 getJID :: session -> IO JID
192 closeSession :: session -> IO ()
193 subscribe :: session -> Maybe JID -> IO (TChan Presence)
194 announcePresence :: session -> Presence -> IO ()
195
196class XMPPConfig config where
197 getBuddies :: config -> ByteString -> IO [ByteString]
198 getSubscribers :: config -> ByteString -> IO [ByteString]
199
200greet host = L.unlines 135greet host = L.unlines
201 [ "<?xml version='1.0'?>" 136 [ "<?xml version='1.0'?>"
202 , "<stream:stream" 137 , "<stream:stream"
diff --git a/Presence/XMPPTypes.hs b/Presence/XMPPTypes.hs
new file mode 100644
index 00000000..eb5d349e
--- /dev/null
+++ b/Presence/XMPPTypes.hs
@@ -0,0 +1,84 @@
1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE TypeFamilies #-}
3module XMPPTypes where
4
5import Network.Socket (Socket,SockAddr(..))
6import System.IO (Handle)
7import Control.Concurrent.STM (TChan)
8import Data.ByteString.Lazy.Char8 as L (ByteString,unpack,pack)
9import Text.Show.ByteString as L
10import Data.Binary.Builder as B
11import Data.Binary.Put
12import Control.DeepSeq
13import ByteStringOperators
14
15class XMPPSession session where
16 data XMPPClass session
17 newSession :: XMPPClass session -> Socket -> Handle -> IO session
18 setResource :: session -> ByteString -> IO ()
19 getJID :: session -> IO JID
20 closeSession :: session -> IO ()
21 subscribe :: session -> Maybe JID -> IO (TChan Presence)
22 announcePresence :: session -> Presence -> IO ()
23
24class XMPPConfig config where
25 getBuddies :: config -> ByteString -> IO [ByteString]
26 getSubscribers :: config -> ByteString -> IO [ByteString]
27
28-- | Jabber ID (JID) datatype
29data JID = JID { name :: Maybe ByteString
30 , peer :: Peer
31 , resource :: Maybe ByteString
32 }
33 deriving (Eq,Ord)
34
35data JabberShow = Offline
36 | Away
37 | Available
38 deriving (Prelude.Show,Enum,Ord,Eq,Read)
39
40data Presence = Presence JID JabberShow
41 deriving Prelude.Show
42
43data Peer = LocalHost | RemotePeer SockAddr
44 deriving (Eq,Prelude.Show)
45
46
47
48instance Ord Peer where
49 LocalHost <= _
50 = True
51 RemotePeer (SockAddrUnix a) <= RemotePeer (SockAddrUnix b)
52 = a <= b
53 RemotePeer (SockAddrUnix _) <= _
54 = True
55 RemotePeer (SockAddrInet aport a) <= RemotePeer (SockAddrInet bport b)
56 = (a,aport) <= (b,bport)
57 RemotePeer (SockAddrInet aport a) <= _
58 = True
59 RemotePeer (SockAddrInet6 aport aflow a ascope) <= RemotePeer (SockAddrInet6 bport bflow b bscope)
60 = (a,aport,ascope,aflow) <= (b,bport,bscope,bflow)
61 a <= b = False
62
63instance L.Show JID where
64 showp (JID n s r ) = putBuilder . B.fromLazyByteString $ n <$++> "@" <?++> showPeer s <++?> "/" <++$> r
65
66instance Prelude.Show JID where
67 show jid = L.unpack $ L.show jid
68
69instance NFData JID where
70 rnf v@(JID n s r) = n `seq` s `seq` r `seq` ()
71
72jid user host rsrc = JID (Just user) host (Just rsrc)
73
74
75showPeer :: Peer -> ByteString
76showPeer LocalHost = "localhost"
77showPeer (RemotePeer addr@(SockAddrInet _ _)) = pack $ stripColon (Prelude.show addr)
78 where stripColon s = pre where (pre,port) = break (==':') s
79showPeer (RemotePeer addr@(SockAddrInet6 _ _ _ _)) = pack $ stripColon (Prelude.show addr)
80 where stripColon s = if null bracket then pre else pre ++ "]"
81 where
82 (pre,bracket) = break (==']') s
83
84
diff --git a/Presence/main.hs b/Presence/main.hs
index a0a80569..403a6ac7 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -25,7 +25,11 @@ import UTmp
25-- 25--
26#endif 26#endif
27import FGConsole 27import FGConsole
28#ifdef HAXML
28import XMPPServer 29import XMPPServer
30#else
31import XMPP
32#endif
29import Data.HList 33import Data.HList
30import Control.Exception 34import Control.Exception
31import LocalPeerCred 35import LocalPeerCred