module System.MapleSSH (maple) where import Data.Maybe(fromMaybe) import Data.Char(isSpace) import System.IO (hPutStrLn, hClose, hGetContents) import System.Process (proc, CreateProcess(..), StdStream(CreatePipe), createProcess, waitForProcess) import System.Environment (lookupEnv) import System.Exit (ExitCode(ExitSuccess)) -- Default values for SSH environment variables defSSH, defUser, defServer, defCommand :: String defSSH = "/usr/bin/ssh" defUser = "ppaml" defServer = "karst.uits.iu.edu" defCommand = "maple" -- On the server side, ~/.modules should load maple/18, and ~/.mapleinit -- should point to ~/hakaru/maple (updated by hakaru/maple/MapleUpdate.hs) envVarsSSH :: IO (String, String, String, String) envVarsSSH = do ssh <- get "MAPLE_SSH" defSSH user <- get "MAPLE_USER" defUser server <- get "MAPLE_SERVER" defServer command <- get "MAPLE_COMMAND" defCommand return (ssh, user, server, command) where get name def = fmap (fromMaybe def) (lookupEnv name) process :: IO CreateProcess process = do bin <- lookupEnv "LOCAL_MAPLE" case bin of Just b -> return $ proc b ["-q", "-t"] Nothing -> do (ssh, user, server, command) <- envVarsSSH let commands = command ++ " -q -t" -- quiet mode return $ proc ssh ["-l" ++ user, server, commands] maple :: String -> IO String maple cmd = do p <- process (Just inH, Just outH, Nothing, p') <- createProcess p { std_in = CreatePipe, std_out = CreatePipe, close_fds = True } hPutStrLn inH $ cmd ++ ";" hClose inH c <- hGetContents outH length c `seq` hClose outH exit <- waitForProcess p' case exit of ExitSuccess -> return $ trim c _ -> error ("maple returned exit code: " ++ show exit) trim :: String -> String trim = dropWhile isSpace