parent
							
								
									24a5eae3f4
								
							
						
					
					
						commit
						174b1af658
					
				
				 7 changed files with 225 additions and 0 deletions
			
			
		@ -0,0 +1,30 @@ | 
				
			|||||||
 | 
					Copyright Gaël Depreeuw (c) 2018 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All rights reserved. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Redistribution and use in source and binary forms, with or without | 
				
			||||||
 | 
					modification, are permitted provided that the following conditions are met: | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Redistributions of source code must retain the above copyright | 
				
			||||||
 | 
					      notice, this list of conditions and the following disclaimer. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Redistributions in binary form must reproduce the above | 
				
			||||||
 | 
					      copyright notice, this list of conditions and the following | 
				
			||||||
 | 
					      disclaimer in the documentation and/or other materials provided | 
				
			||||||
 | 
					      with the distribution. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Neither the name of Gaël Depreeuw nor the names of other | 
				
			||||||
 | 
					      contributors may be used to endorse or promote products derived | 
				
			||||||
 | 
					      from this software without specific prior written permission. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
				
			||||||
 | 
					"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
				
			||||||
 | 
					LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
				
			||||||
 | 
					A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
				
			||||||
 | 
					OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
				
			||||||
 | 
					SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
				
			||||||
 | 
					LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
				
			||||||
 | 
					DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
				
			||||||
 | 
					THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
				
			||||||
 | 
					(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
				
			||||||
 | 
					OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
				
			||||||
@ -0,0 +1 @@ | 
				
			|||||||
 | 
					# client | 
				
			||||||
@ -0,0 +1,2 @@ | 
				
			|||||||
 | 
					import Distribution.Simple | 
				
			||||||
 | 
					main = defaultMain | 
				
			||||||
@ -0,0 +1,25 @@ | 
				
			|||||||
 | 
					name:                client | 
				
			||||||
 | 
					version:             0.1.0.0 | 
				
			||||||
 | 
					-- synopsis: | 
				
			||||||
 | 
					-- description: | 
				
			||||||
 | 
					homepage:            https://github.com/Mithror/client#readme | 
				
			||||||
 | 
					license:             BSD3 | 
				
			||||||
 | 
					license-file:        LICENSE | 
				
			||||||
 | 
					author:              Gaël Depreeuw | 
				
			||||||
 | 
					maintainer:          gael.depreeuw@gmail.com | 
				
			||||||
 | 
					copyright:           Copyright (c) 2018 Gaël Depreeuw | 
				
			||||||
 | 
					category:            daemon | 
				
			||||||
 | 
					build-type:          Simple | 
				
			||||||
 | 
					cabal-version:       >=1.10 | 
				
			||||||
 | 
					extra-source-files:  README.md | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					executable client | 
				
			||||||
 | 
					  hs-source-dirs:      src | 
				
			||||||
 | 
					  main-is:             Main.hs | 
				
			||||||
 | 
					  default-language:    Haskell2010 | 
				
			||||||
 | 
					  build-depends:       base >= 4.7 && < 5 | 
				
			||||||
 | 
					                     , network | 
				
			||||||
 | 
					                     , text | 
				
			||||||
 | 
					                     , bytestring | 
				
			||||||
 | 
					                     , transformers | 
				
			||||||
 | 
					                     , optparse-applicative | 
				
			||||||
@ -0,0 +1,102 @@ | 
				
			|||||||
 | 
					{-# LANGUAGE OverloadedStrings #-} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Main where | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import qualified Control.Exception as E | 
				
			||||||
 | 
					import qualified Data.ByteString.Char8 as C | 
				
			||||||
 | 
					import System.IO | 
				
			||||||
 | 
					import Network.Socket hiding (recv) | 
				
			||||||
 | 
					import Network.Socket.ByteString (recv, sendAll) | 
				
			||||||
 | 
					import Data.Text (Text) | 
				
			||||||
 | 
					import Data.String (fromString) | 
				
			||||||
 | 
					import Control.Monad.Trans.Reader | 
				
			||||||
 | 
					import Control.Monad.IO.Class (liftIO) | 
				
			||||||
 | 
					import Options.Applicative | 
				
			||||||
 | 
					import Data.Semigroup ((<>)) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Host = String | 
				
			||||||
 | 
					type Port = String | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Config = Config { configHost :: Host | 
				
			||||||
 | 
					                     , configPort :: Port | 
				
			||||||
 | 
					                     } deriving (Eq, Show) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ConfigT a = ReaderT Config IO a | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sendData :: C.ByteString -> ConfigT () | 
				
			||||||
 | 
					sendData byteString = do | 
				
			||||||
 | 
					    config <- ask | 
				
			||||||
 | 
					    liftIO $ withSocketsDo $ do | 
				
			||||||
 | 
					      addr <- resolve (configHost config) (configPort config) | 
				
			||||||
 | 
					      E.bracket (open addr) close (talk byteString) | 
				
			||||||
 | 
					  where | 
				
			||||||
 | 
					    resolve h p = do | 
				
			||||||
 | 
					      let hints = defaultHints { addrSocketType = Stream } | 
				
			||||||
 | 
					      addr:_ <- getAddrInfo (Just hints) (Just h) (Just p) | 
				
			||||||
 | 
					      return addr | 
				
			||||||
 | 
					    open addr = do | 
				
			||||||
 | 
					      sock <- socket (addrFamily addr) (addrSocketType addr) defaultProtocol --(addrProtocol addr) | 
				
			||||||
 | 
					      connect sock $ addrAddress addr | 
				
			||||||
 | 
					      return sock | 
				
			||||||
 | 
					    talk bs sock = do | 
				
			||||||
 | 
					      sendAll sock $ bs | 
				
			||||||
 | 
					      msg <- recv sock 1024 | 
				
			||||||
 | 
					      C.putStrLn msg | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sendJSON :: FilePath -> ConfigT () | 
				
			||||||
 | 
					sendJSON filePath = | 
				
			||||||
 | 
					  (liftIO $ readFile filePath) >>= (sendData . fromString . (++ "\0")) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sendFinger :: String -> ConfigT () | 
				
			||||||
 | 
					sendFinger = sendData . fromString . (++ "\r\n") | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Arguments = Finger String Config | 
				
			||||||
 | 
					               | FileInput FilePath Config | 
				
			||||||
 | 
					               deriving (Show, Eq) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					configInput :: Parser Config | 
				
			||||||
 | 
					configInput = Config | 
				
			||||||
 | 
					  <$> strOption | 
				
			||||||
 | 
					    (  long "host" | 
				
			||||||
 | 
					    <> short 'h' | 
				
			||||||
 | 
					    <> metavar "HOST" | 
				
			||||||
 | 
					    <> help "host to connect to") | 
				
			||||||
 | 
					  <*> strOption | 
				
			||||||
 | 
					    (  long "port" | 
				
			||||||
 | 
					    <> short 'p' | 
				
			||||||
 | 
					    <> metavar "PORT" | 
				
			||||||
 | 
					    <> help "port of daemon") | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fingerInput :: Parser Arguments | 
				
			||||||
 | 
					fingerInput = Finger | 
				
			||||||
 | 
					  <$> strOption | 
				
			||||||
 | 
					    (  long "name" | 
				
			||||||
 | 
					    <> short 'n' | 
				
			||||||
 | 
					    <> metavar "NAME" | 
				
			||||||
 | 
					    <> help "name of person to look up") | 
				
			||||||
 | 
					  <*> configInput | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fileInput :: Parser Arguments | 
				
			||||||
 | 
					fileInput = FileInput | 
				
			||||||
 | 
					  <$> strOption | 
				
			||||||
 | 
					    (  long "file" | 
				
			||||||
 | 
					    <> short 'f' | 
				
			||||||
 | 
					    <> metavar "FILENAME" | 
				
			||||||
 | 
					    <> help "json file with config") | 
				
			||||||
 | 
					  <*> configInput | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input :: Parser Arguments | 
				
			||||||
 | 
					input = fingerInput <|> fileInput | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					handleArguments :: Arguments -> IO () | 
				
			||||||
 | 
					handleArguments (Finger n c) = runReaderT (sendFinger n) c | 
				
			||||||
 | 
					handleArguments (FileInput f c) = runReaderT (sendJSON f) c | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main :: IO () | 
				
			||||||
 | 
					main = handleArguments =<< execParser opts | 
				
			||||||
 | 
					  where | 
				
			||||||
 | 
					    opts = info (input <**> helper) | 
				
			||||||
 | 
					      ( fullDesc | 
				
			||||||
 | 
					     <> progDesc "Finger a person or update the server's database." | 
				
			||||||
 | 
					     <> header "client - a tool to talk to the fingerd" ) | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,65 @@ | 
				
			|||||||
 | 
					# This file was automatically generated by 'stack init' | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# Some commonly used options have been documented as comments in this file. | 
				
			||||||
 | 
					# For advanced use and comprehensive documentation of the format, please see: | 
				
			||||||
 | 
					# https://docs.haskellstack.org/en/stable/yaml_configuration/ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Resolver to choose a 'specific' stackage snapshot or a compiler version. | 
				
			||||||
 | 
					# A snapshot resolver dictates the compiler version and the set of packages | 
				
			||||||
 | 
					# to be used for project dependencies. For example: | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# resolver: lts-3.5 | 
				
			||||||
 | 
					# resolver: nightly-2015-09-21 | 
				
			||||||
 | 
					# resolver: ghc-7.10.2 | 
				
			||||||
 | 
					# resolver: ghcjs-0.1.0_ghc-7.10.2 | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# The location of a snapshot can be provided as a file or url. Stack assumes | 
				
			||||||
 | 
					# a snapshot provided as a file might change, whereas a url resource does not. | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# resolver: ./custom-snapshot.yaml | 
				
			||||||
 | 
					# resolver: https://example.com/snapshots/2018-01-01.yaml | 
				
			||||||
 | 
					resolver: lts-11.15 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# User packages to be built. | 
				
			||||||
 | 
					# Various formats can be used as shown in the example below. | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# packages: | 
				
			||||||
 | 
					# - some-directory | 
				
			||||||
 | 
					# - https://example.com/foo/bar/baz-0.0.2.tar.gz | 
				
			||||||
 | 
					# - location: | 
				
			||||||
 | 
					#    git: https://github.com/commercialhaskell/stack.git | 
				
			||||||
 | 
					#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a | 
				
			||||||
 | 
					# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a | 
				
			||||||
 | 
					#  subdirs: | 
				
			||||||
 | 
					#  - auto-update | 
				
			||||||
 | 
					#  - wai | 
				
			||||||
 | 
					packages: | 
				
			||||||
 | 
					- . | 
				
			||||||
 | 
					# Dependency packages to be pulled from upstream that are not in the resolver | 
				
			||||||
 | 
					# using the same syntax as the packages field. | 
				
			||||||
 | 
					# (e.g., acme-missiles-0.3) | 
				
			||||||
 | 
					# extra-deps: [] | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override default flag values for local packages and extra-deps | 
				
			||||||
 | 
					# flags: {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Extra package databases containing global packages | 
				
			||||||
 | 
					# extra-package-dbs: [] | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Control whether we use the GHC we find on the path | 
				
			||||||
 | 
					# system-ghc: true | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# Require a specific version of stack, using version ranges | 
				
			||||||
 | 
					# require-stack-version: -any # Default | 
				
			||||||
 | 
					# require-stack-version: ">=1.7" | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# Override the architecture used by stack, especially useful on Windows | 
				
			||||||
 | 
					# arch: i386 | 
				
			||||||
 | 
					# arch: x86_64 | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# Extra directories used by stack for building | 
				
			||||||
 | 
					# extra-include-dirs: [/path/to/dir] | 
				
			||||||
 | 
					# extra-lib-dirs: [/path/to/dir] | 
				
			||||||
 | 
					# | 
				
			||||||
 | 
					# Allow a newer minor version of GHC than the snapshot specifies | 
				
			||||||
 | 
					# compiler-check: newer-minor | 
				
			||||||
									
										Binary file not shown.
									
								
							
						
					Loading…
					
					
				
		Reference in new issue