diff options
author | joe <joe@jerkface.net> | 2017-11-12 20:35:00 -0500 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-11-12 20:35:00 -0500 |
commit | 5e8f82e436c03e1c59e69d5c9eb0e5a14284dd87 (patch) | |
tree | 1f5e8816e162e570131b8f4cfd90f7cb0b4c5fa7 | |
parent | d4288f5a9f87e3889a50a347ebad0a812f52938c (diff) |
We no longer require root. (ConsoleWriter is disabled without).
-rw-r--r-- | Presence/ConsoleWriter.hs | 8 | ||||
-rw-r--r-- | Presence/FGConsole.hs | 25 | ||||
-rw-r--r-- | Presence/Presence.hs | 17 | ||||
-rw-r--r-- | Presence/monitortty.c | 15 | ||||
-rw-r--r-- | examples/dhtd.hs | 4 | ||||
-rwxr-xr-x | p | 20 |
6 files changed, 61 insertions, 28 deletions
diff --git a/Presence/ConsoleWriter.hs b/Presence/ConsoleWriter.hs index e755b27f..986294f4 100644 --- a/Presence/ConsoleWriter.hs +++ b/Presence/ConsoleWriter.hs | |||
@@ -17,7 +17,6 @@ import Data.Monoid | |||
17 | import Data.Char | 17 | import Data.Char |
18 | import Data.Maybe | 18 | import Data.Maybe |
19 | import System.Environment hiding (setEnv) | 19 | import System.Environment hiding (setEnv) |
20 | import System.Process ( rawSystem ) | ||
21 | import System.Exit ( ExitCode(ExitSuccess) ) | 20 | import System.Exit ( ExitCode(ExitSuccess) ) |
22 | import System.Posix.Env ( setEnv ) | 21 | import System.Posix.Env ( setEnv ) |
23 | import System.Posix.Process ( forkProcess, exitImmediately, executeFile ) | 22 | import System.Posix.Process ( forkProcess, exitImmediately, executeFile ) |
@@ -36,7 +35,7 @@ import qualified Data.Text as Text | |||
36 | import qualified Network.BSD as BSD | 35 | import qualified Network.BSD as BSD |
37 | 36 | ||
38 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) | 37 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) |
39 | import FGConsole ( monitorTTY ) | 38 | import FGConsole ( forkTTYMonitor ) |
40 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType | 39 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType |
41 | , LangSpecificMessage(..), msgLangMap, cloneStanza, stanzaFrom ) | 40 | , LangSpecificMessage(..), msgLangMap, cloneStanza, stanzaFrom ) |
42 | import ControlMaybe ( handleIO_ ) | 41 | import ControlMaybe ( handleIO_ ) |
@@ -109,7 +108,7 @@ onLogin cs start = \e -> do | |||
109 | -- | Sets up threads to monitor tty switches and logins that are | 108 | -- | Sets up threads to monitor tty switches and logins that are |
110 | -- written to the system utmp file and returns a 'ConsoleWriter' | 109 | -- written to the system utmp file and returns a 'ConsoleWriter' |
111 | -- object for interacting with that information. | 110 | -- object for interacting with that information. |
112 | newConsoleWriter :: IO ConsoleWriter | 111 | newConsoleWriter :: IO (Maybe ConsoleWriter) |
113 | newConsoleWriter = do | 112 | newConsoleWriter = do |
114 | chan <- atomically $ newEmptyTMVar | 113 | chan <- atomically $ newEmptyTMVar |
115 | cs <- atomically $ do | 114 | cs <- atomically $ do |
@@ -136,7 +135,8 @@ newConsoleWriter = do | |||
136 | inotify <- initINotify | 135 | inotify <- initINotify |
137 | 136 | ||
138 | -- get active tty | 137 | -- get active tty |
139 | mtty <- monitorTTY (onTTY outvar cs) | 138 | mtty <- forkTTYMonitor (onTTY outvar cs) |
139 | forM mtty $ \_ -> do | ||
140 | atomically $ retryWhen (readTVar $ csActiveTTY cs) (==0) | 140 | atomically $ retryWhen (readTVar $ csActiveTTY cs) (==0) |
141 | 141 | ||
142 | -- read utmp | 142 | -- read utmp |
diff --git a/Presence/FGConsole.hs b/Presence/FGConsole.hs index 623fb493..03aaebf2 100644 --- a/Presence/FGConsole.hs +++ b/Presence/FGConsole.hs | |||
@@ -11,7 +11,6 @@ import Unsafe.Coerce | |||
11 | import Control.Exception as E | 11 | import Control.Exception as E |
12 | -- import Prelude as E | 12 | -- import Prelude as E |
13 | import Control.Monad | 13 | import Control.Monad |
14 | import Foreign.C.Error | ||
15 | import Foreign.C | 14 | import Foreign.C |
16 | 15 | ||
17 | import Logging | 16 | import Logging |
@@ -19,12 +18,13 @@ import System.Posix.Signals | |||
19 | 18 | ||
20 | -- c_monitorTTY fd = trace "c_monitorTTY" (return ()) -- (trace "WTF" todo) | 19 | -- c_monitorTTY fd = trace "c_monitorTTY" (return ()) -- (trace "WTF" todo) |
21 | 20 | ||
22 | foreign import ccall "monitorTTY" c_monitorTTY :: Fd -> IO () | 21 | foreign import ccall "monitorTTY" c_monitorTTY :: Fd -> IO CInt |
23 | foreign import ccall "closeTTY" c_closeTTY :: IO () | 22 | foreign import ccall "closeTTY" c_closeTTY :: IO () |
24 | 23 | ||
25 | monitorTTY :: (Word8 -> IO ()) -> IO (Fd,ThreadId) | 24 | forkTTYMonitor :: (Word8 -> IO ()) -> IO (Maybe (Fd,ThreadId)) |
26 | monitorTTY handler = do | 25 | forkTTYMonitor handler = do |
27 | (rfd,wfd) <- createPipe | 26 | (rfd,wfd) <- createPipe |
27 | retvar <- newEmptyMVar | ||
28 | thread <- forkIO $ do | 28 | thread <- forkIO $ do |
29 | let cleanup = do | 29 | let cleanup = do |
30 | trace "quitting monitorTTY thread." (return ()) | 30 | trace "quitting monitorTTY thread." (return ()) |
@@ -32,8 +32,10 @@ monitorTTY handler = do | |||
32 | closeFd rfd `E.catch` \(e::IOException) -> return () | 32 | closeFd rfd `E.catch` \(e::IOException) -> return () |
33 | c_closeTTY | 33 | c_closeTTY |
34 | -- rh <- fdToHandle rfd | 34 | -- rh <- fdToHandle rfd |
35 | c_monitorTTY wfd | 35 | didfork <- c_monitorTTY wfd |
36 | let monitor = | 36 | putMVar retvar didfork |
37 | when (didfork == 0) $ do | ||
38 | let monitor = | ||
37 | (do | 39 | (do |
38 | threadWaitRead rfd | 40 | threadWaitRead rfd |
39 | (cs,cnt) <- fdRead rfd 1 | 41 | (cs,cnt) <- fdRead rfd 1 |
@@ -45,13 +47,16 @@ monitorTTY handler = do | |||
45 | case () of | 47 | case () of |
46 | _ | err==eAGAIN -> monitor | 48 | _ | err==eAGAIN -> monitor |
47 | _ | otherwise -> cleanup | 49 | _ | otherwise -> cleanup |
48 | `E.catch` | 50 | `E.catch` |
49 | \(e :: AsyncException) -> cleanup | 51 | \(e :: AsyncException) -> cleanup |
50 | monitor | 52 | monitor |
51 | return (rfd,thread) | 53 | didfork <- takeMVar retvar |
54 | if didfork == 0 | ||
55 | then return $! Just (rfd,thread) | ||
56 | else return $! Nothing | ||
52 | 57 | ||
53 | unmonitorTTY :: (Fd, ThreadId) -> IO () | 58 | killTTYMonitor :: (Fd, ThreadId) -> IO () |
54 | unmonitorTTY (rfd,thread) = do | 59 | killTTYMonitor (rfd,thread) = do |
55 | closeFd rfd | 60 | closeFd rfd |
56 | yield | 61 | yield |
57 | killThread thread | 62 | killThread thread |
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index 2344fb75..9660b29f 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -148,7 +148,7 @@ data PresenceState = PresenceState | |||
148 | , associatedPeers :: TVar (Map SockAddr ()) | 148 | , associatedPeers :: TVar (Map SockAddr ()) |
149 | , server :: TMVar XMPPServer | 149 | , server :: TMVar XMPPServer |
150 | , keyToChan :: TVar (Map ConnectionKey Conn) | 150 | , keyToChan :: TVar (Map ConnectionKey Conn) |
151 | , consoleWriter :: ConsoleWriter | 151 | , consoleWriter :: Maybe ConsoleWriter |
152 | } | 152 | } |
153 | 153 | ||
154 | 154 | ||
@@ -435,11 +435,11 @@ rewriteJIDForPeer jid = do | |||
435 | in (to',addr) | 435 | in (to',addr) |
436 | 436 | ||
437 | deliverToConsole :: PresenceState -> IO () -> Stanza -> IO () | 437 | deliverToConsole :: PresenceState -> IO () -> Stanza -> IO () |
438 | deliverToConsole state fail msg = do | 438 | deliverToConsole PresenceState{ consoleWriter = Just cw } fail msg = do |
439 | putStrLn $ "TODO: deliver to console" | 439 | did1 <- writeActiveTTY cw msg |
440 | did1 <- writeActiveTTY (consoleWriter state) msg | 440 | did2 <- writeAllPty cw msg |
441 | did2 <- writeAllPty (consoleWriter state) msg | ||
442 | if not (did1 || did2) then fail else return () | 441 | if not (did1 || did2) then fail else return () |
442 | deliverToConsole _ fail _ = fail | ||
443 | 443 | ||
444 | -- | deliver <message/> or error stanza | 444 | -- | deliver <message/> or error stanza |
445 | deliverMessage :: PresenceState | 445 | deliverMessage :: PresenceState |
@@ -636,6 +636,11 @@ informPeerPresence state k stanza = do | |||
636 | sendModifiedStanzaToClient (dup { stanzaFrom=Just from' }) | 636 | sendModifiedStanzaToClient (dup { stanzaFrom=Just from' }) |
637 | (connChan con) | 637 | (connChan con) |
638 | 638 | ||
639 | consoleClients :: PresenceState -> STM (Map Text ClientState) | ||
640 | consoleClients PresenceState{ consoleWriter = Just cw } = readTVar (cwClients cw) | ||
641 | consoleClients _ = return Map.empty | ||
642 | |||
643 | |||
639 | answerProbe :: PresenceState | 644 | answerProbe :: PresenceState |
640 | -> Maybe Text -> ConnectionKey -> TChan Stanza -> IO () | 645 | -> Maybe Text -> ConnectionKey -> TChan Stanza -> IO () |
641 | answerProbe state mto k chan = do | 646 | answerProbe state mto k chan = do |
@@ -671,7 +676,7 @@ answerProbe state mto k chan = do | |||
671 | replies <- runTraversableT $ do | 676 | replies <- runTraversableT $ do |
672 | cbu <- lift . atomically $ readTVar (clientsByUser state) | 677 | cbu <- lift . atomically $ readTVar (clientsByUser state) |
673 | let lpres = maybeToList $ Map.lookup u cbu | 678 | let lpres = maybeToList $ Map.lookup u cbu |
674 | cw <- lift . atomically $ readTVar (cwClients $ consoleWriter state) | 679 | cw <- lift . atomically $ consoleClients state |
675 | clientState <- liftT $ (lpres >>= Map.elems . networkClients) | 680 | clientState <- liftT $ (lpres >>= Map.elems . networkClients) |
676 | ++ Map.elems cw | 681 | ++ Map.elems cw |
677 | stanza <- liftIOMaybe $ atomically (readTVar (clientStatus clientState)) | 682 | stanza <- liftIOMaybe $ atomically (readTVar (clientStatus clientState)) |
diff --git a/Presence/monitortty.c b/Presence/monitortty.c index a9a095cf..7582aa56 100644 --- a/Presence/monitortty.c +++ b/Presence/monitortty.c | |||
@@ -146,10 +146,19 @@ void *write_vtch(void *pfd) { | |||
146 | } | 146 | } |
147 | 147 | ||
148 | 148 | ||
149 | void monitorTTY(int fd) { | 149 | // Returns 0 on success. |
150 | int monitorTTY(int fd) { | ||
151 | int er = -1, dev = -1; | ||
150 | pthread_mutex_init(&mu,NULL); | 152 | pthread_mutex_init(&mu,NULL); |
151 | // printf ("Hello world.\n"); | 153 | // Ensure we can open a device before we bother forking a thread. |
152 | pthread_create (&mt, NULL, write_vtch, (void*)(intptr_t)fd); | 154 | dev = ttyfd(); |
155 | if( dev != -1 ) { | ||
156 | er = pthread_create (&mt, NULL, write_vtch, (void*)(intptr_t)fd); | ||
157 | return er; | ||
158 | } | ||
159 | else { | ||
160 | return -1; | ||
161 | } | ||
153 | } | 162 | } |
154 | 163 | ||
155 | void closeTTY() { | 164 | void closeTTY() { |
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index 0996ffab..4c0cd114 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -1368,10 +1368,10 @@ main = do | |||
1368 | 1368 | ||
1369 | forkIO $ do | 1369 | forkIO $ do |
1370 | myThreadId >>= flip labelThread "XMPP.stanzas" | 1370 | myThreadId >>= flip labelThread "XMPP.stanzas" |
1371 | let console = cwPresenceChan $ consoleWriter state | 1371 | let console = cwPresenceChan <$> consoleWriter state |
1372 | fix $ \loop -> do | 1372 | fix $ \loop -> do |
1373 | what <- atomically | 1373 | what <- atomically |
1374 | $ orElse (do (client,stanza) <- takeTMVar console | 1374 | $ orElse (do (client,stanza) <- maybe retry takeTMVar console |
1375 | return $ do informClientPresence0 state Nothing client stanza | 1375 | return $ do informClientPresence0 state Nothing client stanza |
1376 | loop) | 1376 | loop) |
1377 | (checkQuit >> return (return ())) | 1377 | (checkQuit >> return (return ())) |
@@ -1,14 +1,28 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | args="-rtsopts -osuf -prof pf -fprof-auto -fprof-auto-exported" | 2 | warn="-freverse-errors -fwarn-unused-imports -Wmissing-signatures -fdefer-typed-holes" |
3 | exts="-XOverloadedStrings -XRecordWildCards" | ||
4 | defs="-DBENCODE_AESON -DTHREAD_DEBUG" | ||
5 | hide="-hide-package crypto-random -hide-package crypto-api -hide-package crypto-numbers -hide-package cryptohash -hide-package prettyclass" | ||
6 | opts="-rtsopts -hisuf p_hi -osuf p_o -prof -fprof-auto -fprof-auto-exported" | ||
3 | 7 | ||
4 | root=${0%/*} | 8 | root=${0%/*} |
5 | cd "$root" | 9 | cd "$root" |
6 | 10 | ||
7 | me=${0##*/} | 11 | me=${0##*/} |
8 | me=${me%.*} | 12 | me=${me%.*} |
13 | set -x | ||
9 | ghc \ | 14 | ghc \ |
15 | $opts \ | ||
16 | $hide \ | ||
17 | $exts \ | ||
18 | $defs \ | ||
10 | -hidir build/$me -odir build/$me \ | 19 | -hidir build/$me -odir build/$me \ |
11 | -iPresence \ | 20 | -iPresence \ |
12 | -iArchive \ | 21 | -iArchive \ |
13 | $args \ | 22 | -isrc \ |
23 | -icryptonite-backport \ | ||
24 | build/b/Presence/monitortty.o \ | ||
25 | build/b/cbits/cryptonite_salsa.o \ | ||
26 | build/b/cbits/cryptonite_xsalsa.o\ | ||
27 | $warn \ | ||
14 | "$@" | 28 | "$@" |