summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-06-17 21:34:56 -0400
committerjoe <joe@jerkface.net>2013-06-17 21:34:56 -0400
commit012a3b625c0ea236afc1ea09c89d0dcd435a66bd (patch)
treeba105c111665d0587620b76ff18c8b21076fb3f3
parentcc93b83b5a8c9e00839777c59991c5eb8cf0d75a (diff)
State changes on vt switch.
-rw-r--r--Presence/ByteStringOperators.hs20
-rw-r--r--Presence/main.hs49
2 files changed, 57 insertions, 12 deletions
diff --git a/Presence/ByteStringOperators.hs b/Presence/ByteStringOperators.hs
index 26b64bcf..2815f05a 100644
--- a/Presence/ByteStringOperators.hs
+++ b/Presence/ByteStringOperators.hs
@@ -3,6 +3,11 @@ module ByteStringOperators where
3import qualified Data.ByteString as S (ByteString) 3import qualified Data.ByteString as S (ByteString)
4import Data.ByteString.Lazy.Char8 as L 4import Data.ByteString.Lazy.Char8 as L
5 5
6-- These two were imported to provide an NFData instance.
7import qualified Data.ByteString.Lazy.Internal as L (ByteString(..))
8import Control.DeepSeq
9
10
6(<++>) :: ByteString -> ByteString -> ByteString 11(<++>) :: ByteString -> ByteString -> ByteString
7(<++.>) :: ByteString -> S.ByteString -> ByteString 12(<++.>) :: ByteString -> S.ByteString -> ByteString
8(<.++>) :: S.ByteString -> ByteString -> ByteString 13(<.++>) :: S.ByteString -> ByteString -> ByteString
@@ -16,5 +21,20 @@ infixr 5 <.++>
16infixr 5 <++> 21infixr 5 <++>
17infixr 5 <++.> 22infixr 5 <++.>
18 23
24Nothing <?++> b = b
25Just a <?++> b = a <++> b
26infixr 5 <?++>
27
28a <++?> Nothing = a
29a <++?> Just b = a <++> b
30infixr 5 <++?>
31
19bshow :: Show a => a -> ByteString 32bshow :: Show a => a -> ByteString
20bshow = L.pack . show 33bshow = L.pack . show
34
35
36instance NFData L.ByteString where
37 rnf L.Empty = ()
38 rnf (L.Chunk _ b) = rnf b
39
40
diff --git a/Presence/main.hs b/Presence/main.hs
index 36796b6e..ff2f18cf 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -9,6 +9,7 @@ import System.Posix.Signals
9import System.Posix.Types 9import System.Posix.Types
10import System.Posix.Process 10import System.Posix.Process
11import Data.Maybe 11import Data.Maybe
12import Data.Char
12 13
13import System.INotify 14import System.INotify
14#ifndef NOUTMP 15#ifndef NOUTMP
@@ -31,22 +32,40 @@ import LocalPeerCred
31import System.Posix.User 32import System.Posix.User
32import qualified Data.Set as Set 33import qualified Data.Set as Set
33import Data.Set as Set (Set,(\\)) 34import Data.Set as Set (Set,(\\))
35import Control.Concurrent.MVar.Strict
36import Control.DeepSeq
34 37
35import ByteStringOperators 38import ByteStringOperators
36import qualified Data.ByteString.Lazy.Char8 as L 39import qualified Data.ByteString.Lazy.Char8 as L
37import Data.ByteString.Lazy.Char8 as L (putStrLn) 40import Data.ByteString.Lazy.Char8 as L (ByteString,putStrLn)
38import qualified Prelude 41import qualified Prelude
39import Prelude hiding (putStrLn) 42import Prelude hiding (putStrLn)
40 43
41 44
42jid user host rsrc = user <++> "@" <++> host <++> "/" <++> rsrc 45-- | Jabber ID (JID) datatype
46data JID = JID { name :: Maybe ByteString
47 -- ^ Account name
48 , server :: ByteString
49 -- ^ Server adress
50 , resource :: Maybe ByteString
51 -- ^ Resource name
52 }
53 deriving (Ord,Eq)
54
55instance Show JID where
56 show (JID n s r ) = L.unpack $ fmap (<++>"@") n <?++> s <++?> fmap ("/"<++>) r
57
58instance NFData JID where
59 rnf v@(JID n s r) = n `seq` s `seq` r `seq` ()
60
61jid user host rsrc = JID (Just user) host (Just rsrc) -- user <++> "@" <++> host <++> "/" <++> rsrc
43 62
44toJabberId host (user,tty,_) = 63toJabberId host (user,tty,_) =
45 if L.take 3 tty == "tty" 64 if L.take 3 tty == "tty"
46 then Just (jid user host tty) 65 then Just (jid user host tty)
47 else Nothing 66 else Nothing
48 67
49track_login :: IORef (Set L.ByteString) -> t -> IO () 68track_login :: MVar (Set JID) -> t -> IO ()
50track_login tracked e = do 69track_login tracked e = do
51#ifndef NOUTMP 70#ifndef NOUTMP
52 us <- users 71 us <- users
@@ -54,15 +73,13 @@ track_login tracked e = do
54 let us = [] 73 let us = []
55#endif 74#endif
56 let ids = Set.fromList $ mapMaybe (toJabberId "localhost") us 75 let ids = Set.fromList $ mapMaybe (toJabberId "localhost") us
57 -- forM_ ids L.putStrLn 76 state <- swapMVar tracked ids
58 state <- readIORef tracked
59 let arrivals = ids \\ state 77 let arrivals = ids \\ state
60 departures = state \\ ids 78 departures = state \\ ids
61 forM_ (Set.toList departures) $ \id -> do 79 forM_ (Set.toList departures) $ \id -> do
62 putStrLn $ id <++> " logged out." 80 putStrLn $ bshow id <++> " Offline."
63 forM_ (Set.toList arrivals) $ \id -> do 81 forM_ (Set.toList arrivals) $ \id -> do
64 putStrLn $ id <++> " logged in." 82 putStrLn $ bshow id <++> " Available."
65 writeIORef tracked ids
66 83
67data UnixSession = UnixSession { 84data UnixSession = UnixSession {
68 unix_uid :: (IORef (Maybe UserID)), 85 unix_uid :: (IORef (Maybe UserID)),
@@ -99,12 +116,20 @@ instance XMPPSession UnixSession where
99 return jid 116 return jid
100 closeSession _ = L.putStrLn "SESSION: close" 117 closeSession _ = L.putStrLn "SESSION: close"
101 118
102on_chvt vtnum = do 119on_chvt tracked vtnum = do
103 L.putStrLn $ "changed vt to " <++> bshow vtnum 120 let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum)
121 L.putStrLn $ "changed vt to " <++> tty
122 state <- readMVar tracked
123 forM_ (Set.toList state) $ \jid -> do
124 case fmap (==tty) $ resource jid of
125 Just True -> putStrLn $ bshow jid <++> " Available."
126 Just False -> putStrLn $ bshow jid <++> " Away."
127 Nothing -> return ()
128
104 129
105start :: IO () 130start :: IO ()
106start = do 131start = do
107 tracked <- newIORef Set.empty 132 tracked <- newMVar Set.empty
108 let dologin e = track_login tracked e 133 let dologin e = track_login tracked e
109 dologin :: t -> IO () 134 dologin :: t -> IO ()
110 dologin () 135 dologin ()
@@ -120,7 +145,7 @@ start = do
120 utmp_file 145 utmp_file
121 dologin 146 dologin
122#endif 147#endif
123 mtty <- monitorTTY on_chvt 148 mtty <- monitorTTY (on_chvt tracked)
124 sock <- listenForXmppClients UnixSessions 5222 HNil 149 sock <- listenForXmppClients UnixSessions 5222 HNil
125 putStrLn "Hit enter to terminate..." 150 putStrLn "Hit enter to terminate..."
126 getLine 151 getLine