mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-01 12:41:52 -07:00
Add support for global ssh known hosts file, which is checked for via $SSH_KNOWN_HOSTS or a standard list of locations. This is stripped of comments and hashed hosts, combined with the local hosts file (which is trated the same way), and duplicates eliminated.
104 lines
2.7 KiB
Haskell
104 lines
2.7 KiB
Haskell
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonadContrib.SshPrompt
|
|
-- Copyright : (C) 2007 Andrea Rossato
|
|
-- License : BSD3
|
|
--
|
|
-- Maintainer : andrea.rossato@unibz.it
|
|
-- Stability : unstable
|
|
-- Portability : unportable
|
|
--
|
|
-- A ssh prompt for XMonad
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonadContrib.SshPrompt (
|
|
-- * Usage
|
|
-- $usage
|
|
sshPrompt
|
|
) where
|
|
|
|
import XMonad
|
|
import XMonadContrib.XPrompt
|
|
import XMonadContrib.RunInXTerm
|
|
|
|
import Control.Monad
|
|
import System.Directory
|
|
import System.Environment
|
|
import Data.List
|
|
import Data.Maybe
|
|
|
|
-- $usage
|
|
-- 1. In Config.hs add:
|
|
--
|
|
-- > import XMonadContrib.XPrompt
|
|
-- > import XMonadContrib.SshPrompt
|
|
--
|
|
-- 3. In your keybindings add something like:
|
|
--
|
|
-- > , ((modMask .|. controlMask, xK_x), xmonadPrompt defaultXPConfig)
|
|
--
|
|
|
|
-- %import XMonadContrib.XPrompt
|
|
-- %import XMonadContrib.SshPrompt
|
|
-- %keybind , ((modMask .|. controlMask, xK_x), xmonadPrompt defaultXPConfig)
|
|
|
|
data Ssh = Ssh
|
|
|
|
instance XPrompt Ssh where
|
|
showXPrompt Ssh = "SSH to: "
|
|
|
|
sshPrompt :: XPConfig -> X ()
|
|
sshPrompt c = do
|
|
sc <- io $ sshComplList
|
|
mkXPrompt Ssh c (mkComplFunFromList sc) ssh
|
|
|
|
ssh :: String -> X ()
|
|
ssh s = runInXTerm ("ssh " ++ s)
|
|
|
|
sshComplList :: IO [String]
|
|
sshComplList = (nub . sort) `fmap` liftM2 (++) sshComplListLocal sshComplListGlobal
|
|
|
|
sshComplListLocal :: IO [String]
|
|
sshComplListLocal = do
|
|
h <- getEnv "HOME"
|
|
sshComplListFile $ h ++ "/.ssh/known_hosts"
|
|
|
|
sshComplListGlobal :: IO [String]
|
|
sshComplListGlobal = do
|
|
env <- getEnv "SSH_KNOWN_HOSTS" `catch` (\_ -> return "/nonexistent")
|
|
fs <- mapM fileExists [ env
|
|
, "/usr/local/etc/ssh/ssh_known_hosts"
|
|
, "/usr/local/etc/ssh_known_hosts"
|
|
, "/etc/ssh/ssh_known_hosts"
|
|
, "/etc/ssh_known_hosts"
|
|
]
|
|
case catMaybes fs of
|
|
[] -> return []
|
|
(f:_) -> sshComplListFile' f
|
|
|
|
sshComplListFile :: String -> IO [String]
|
|
sshComplListFile kh = do
|
|
f <- doesFileExist kh
|
|
if f then sshComplListFile' kh
|
|
else return []
|
|
|
|
sshComplListFile' :: String -> IO [String]
|
|
sshComplListFile' kh = do
|
|
l <- readFile kh
|
|
return $ map (takeWhile (/= ',') . concat . take 1 . words)
|
|
$ filter nonComment
|
|
$ lines l
|
|
|
|
fileExists :: String -> IO (Maybe String)
|
|
fileExists kh = do
|
|
f <- doesFileExist kh
|
|
if f then return $ Just kh
|
|
else return Nothing
|
|
|
|
nonComment :: String -> Bool
|
|
nonComment [] = False
|
|
nonComment ('#':_) = False
|
|
nonComment ('|':_) = False -- hashed, undecodeable
|
|
nonComment _ = True
|