packages feed

WL500gPControl (empty) → 0.3.1

raw patch · 6 files changed

+195/−0 lines, 6 filesdep +WL500gPLibrarydep +basedep +mtlsetup-changed

Dependencies added: WL500gPLibrary, base, mtl, unix

Files

+ LICENSE view
+ Setup.lhs view
@@ -0,0 +1,5 @@+#!/usr/bin/env runhaskell++> import Distribution.Simple+> main = defaultMain+ 
+ WL500gPControl.cabal view
@@ -0,0 +1,23 @@+name:                           WL500gPControl+version:                        0.3.1+cabal-version:                  >= 1.2+license:                        BSD3+license-file:                   LICENSE+author:                         Vasyl Pasternak <vasyl.pasternak@gmail.com>+category:                       Network, UI+synopsis:                       A simple command line tools to control the +                                Asus WL500gP router+build-type:                     Simple++executable WL500gPStatus+           main-is:             Status/Main.hs+           build-depends:       base < 4, WL500gPLibrary >= 0.3+           hs-source-dirs:      src+           other-modules:       Common++executable WL500gPControl+           main-is:             Control/Main.hs+           build-depends:       base < 4, WL500gPLibrary >= 0.3, mtl, unix+           hs-source-dirs:      src+           other-modules:       Common+
+ src/Common.hs view
@@ -0,0 +1,33 @@++module Common +    (+     defaultCredsFile+    ,parseCredsFile+    )where++import System.IO.Unsafe (unsafePerformIO)+import System.Environment (getEnv)+import Text.Printf (printf)+import qualified Network.Asus.WL500gP as W+import Data.Char (toLower)+import Control.Monad (liftM)+    +homeDirectory = unsafePerformIO $ getEnv "HOME"++defaultCredsFile = printf "%s/.wl500gp" homeDirectory :: String+++parseCredsFile :: String -> IO (Maybe W.Connection)+parseCredsFile fname = +    let toPair (a:b:[]) = (map toLower a, b)+        toPair _ = ("", "")+        parse = filter (/= ("", "")) . map (toPair . words) . lines+    in do+      contentsMap <- liftM parse $ readFile fname+      return $ do (host:passwd:user:[]) <- +                      mapM (`lookup` contentsMap) ["host:"+                                                  ,"password:"+                                                  ,"user:"]+                  return $ W.Connection {W.user = user+                                        ,W.password = passwd+                                        ,W.hostname = host}
+ src/Control/Main.hs view
@@ -0,0 +1,96 @@++module Main where++import System.Console.GetOpt+import System.Environment (getArgs, getProgName)+import Data.Maybe (maybe)+import Common+import Control.Monad (sequence_, zipWithM_)+import Text.Printf (printf)+import qualified Network.Asus.WL500gP as W+import Data.Either (either)+import Data.List (intersperse)+import Control.Monad.Trans (liftIO)+import System.Posix.Unistd (sleep)++data Operation = Connect +               | Disconnect +               | Reconnect Int+               | Status +               | Log Int+               | ClearLog deriving (Show)++options :: [OptDescr Operation]+options = +    [Option ['c'] ["connect"] (NoArg Connect) +                "Connects to the WAN"+    ,Option ['d'] ["disconnect"] (NoArg Disconnect) +                "Disconnects from the provider"+    ,Option ['r'] ["reconnect"] (OptArg (Reconnect . maybe 5 read) "S") +                "Disconnects from WAN, waits S seconds and reconnects to the WAN"+    ,Option ['s'] ["status"] (NoArg Status) +                "Prints the connection status"+    ,Option ['l'] ["log"] (OptArg (Log . maybe 25 read) "N") +                "Prints last N lines from the log"+    ,Option ['x'] ["log-clear"] (NoArg ClearLog) +                "Clears log"+    ]++-- returns the list of flags and the config filename+parseOpts :: [String] -> IO (Operation, String)+parseOpts argv = +    case getOpt Permute options argv of+      (o, n, []) -> let creds = if null n +                                 then defaultCredsFile +                                 else (head n)+                        op = if null o +                              then Status+                              else (head o)+                    in return (op, creds)+      (_, _, errs) -> do +        progName <- getProgName+        let header = printf "Usage: %s OPERATION CREDENTIAL_FILE" progName+        ioError (userError (concat errs ++ usageInfo header options))+     ++main :: IO ()+main = do+  (oper, creds) <- getArgs >>= parseOpts+  parseCredsFile creds >>= maybe +                     (ioError $ userError $ printf "Failed to open credentials file '%s'" creds) +                     (switch oper)++brace :: String -> String -> W.Conn () -> W.Conn ()+brace b a c = sequence_ [liftIO $ putStrLn b, c, liftIO $ putStrLn a]++switch op conn = +    W.withConnection conn $ +     case op of +       Connect -> brace "Connecting..." "Done" W.connectWan+       Disconnect -> brace "Disconnecting..." "Done" W.disconnectWan+       ClearLog -> brace "Erasing log.." "Done" W.clearLog+       Reconnect n -> brace "Reconnecting..." "Done" $ +                      sequence_ [W.disconnectWan+                                ,liftIO (sleep n >> return ())+                                ,W.connectWan]+       Status -> W.readStatus >>= liftIO . either (ioError . userError) showStatus+       Log n -> W.readLog >>= liftIO . either (ioError . userError) (showLog n)++showStatus stat = do+  printf "Connection status:\n"    +  case W.connectionStatus stat of+    W.Disconnected -> printf "\tWAN disconnected\n"+    _ -> do printf " WAN Connected\n"+            zipWithM_ printf [" IP:\t\t%s\n"+                             ," Subnet Mask:\t%s\n"+                             ," Gateway:\t%s\n"+                             ," DNS Servers:\t%s\n"+                             ] $ +                               map ($ stat) [W.ip+                                            ,W.subnetMask+                                            ,W.defaultGateway+                                            ,concat . intersperse ", " . W.dnsServers]+++showLog n = printf "%s" . unlines . reverse . take n . reverse+    
+ src/Status/Main.hs view
@@ -0,0 +1,38 @@++module Main where++import qualified Network.Asus.WL500gP as W+import System.Environment (getArgs)+import Text.Printf (printf)+import Common+import Data.Either (either)++data Status = StatusConnected | StatusDisconnected | StatusError String deriving Eq++fromConnStatus :: W.ConnectionStatus -> Status+fromConnStatus W.Connected = StatusConnected+fromConnStatus W.Disconnected = StatusDisconnected++main :: IO ()+main = do+  args <- getArgs+  -- config file name should be the last argument+  let configFile = if null args +                   then defaultCredsFile+                   else head (reverse args)+  -- '-c' - for colorized output+  let outString = printStatus ("-c" `elem` args)+  let configError = outString (StatusError $ printf "Failed to open file %s " configFile)+  let getStatus conn = +          either (outString . StatusError) +                 (outString . fromConnStatus . W.connectionStatus) =<< +                 W.withConnection conn W.readStatus++  maybe configError getStatus  =<< parseCredsFile configFile+  +printStatus c StatusConnected = format c "#00ff00" "Connected"+printStatus c StatusDisconnected = format c "#ff0000" "Disconnected"+printStatus c (StatusError e) = format c "#dddddd" (if c then "N/A" else e)++format True col s = printf "<fc=%s>%s</fc>" col s+format _ _ s = printf s