blob: 5968b152f351872c3b3216732df5e5833d964415 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
module Main where
import LocalPeerCred
import ControlMaybe
import System.Directory
import Data.Char
import System.Posix.Types
import System.Posix.Files
import Data.ByteString.Lazy.Char8 as L (unpack)
import Data.List (groupBy)
import Data.Maybe (listToMaybe)
import Network.Socket
import System.Environment
import Control.Arrow (first)
usage = do
putStrLn $ "whosocket numeric-address port"
main = do
args <- getArgs
case (args??0,args??1) of
(Just addr_str,Just port_str) -> whosocket addr_str port_str
_ -> usage
whosocket addr_str port_str = do
info <- getAddrInfo (Just $ defaultHints { addrFlags = [ AI_NUMERICHOST ] })
(Just addr_str)
(Just port_str)
let addr = head $ map addrAddress info
r <- getLocalPeerCred' addr
putStrLn $ "r{"++show addr++"} = " ++ show r
let Just (uid,inode) = r
pid <- scanProc (show uid) (L.unpack inode)
putStrLn $ "scanProc --> "++show pid
withJust pid $ \(pid,ttydev) -> do
tty <- ttyOrDisplay pid ttydev
putStrLn $ "pid = " ++ show pid
putStrLn $ "tty = " ++ show tty
return ()
makeUidStr "4294967295" = "invalid"
makeUidStr uid = uid
scanProc uid inode = do
contents <- getDirectoryContents "/proc" `catchIO_` return []
let pids = reverse $ filter (\n -> not (null n) && isDigit (head n)) contents
let searchPids [] = return Nothing
searchPids (pid:pids) = do
loginuid <- fmap makeUidStr $ readFile $ "/proc/"++pid++"/loginuid"
if False -- (uid/=loginuid) -- this check proved bad when mcabber ran on tty3
then searchPids pids
else do
-- putStrLn $ "pid "++show pid ++ " --> uid "++show loginuid
let loop [] = return Nothing
loop ("0":fds) = loop fds
loop (fd:fds) = do
handleIO_ (loop fds) $ do
what <- readSymbolicLink $ "/proc/"++pid++"/fd/"++fd
-- putStrLn $ " what= "++show what
if (what=="socket:["++inode++"]")
then do
tty <- readSymbolicLink $ "/proc/"++pid++"/fd/0"
return (Just (pid,tty))
else loop fds
fds <- getDirectoryContents ("/proc/"++pid++"/fd") `catchIO_` return []
mb <- loop fds
maybe (searchPids pids) (return . Just) mb
fmap (fmap (first (read :: String -> CPid))) $ searchPids pids
ttyOrDisplay pid ttydev | take 8 ttydev == "/dev/tty" = return (drop 5 ttydev)
ttyOrDisplay pid ttydev = do
env <- handleIO_ (return "") . readFile $ "/proc/"++show pid++"/environ"
let vs = unzero $ groupBy (\_ c->c/='\0') env
unzero [] = []
unzero (v:vs) = v:map tail vs
keyvalue xs = (key,value)
where
(key,ys) = break (=='=') xs
value = case ys of { [] -> []; (_:ys') -> ys' }
display = listToMaybe . filter ((=="DISPLAY").fst) . map keyvalue $ vs
putStrLn $ "display = " ++ show display
case display of
Just (_,disp) -> return disp
_ -> return ttydev
|