NineP-0.0.2.1: 9P2000 in pure Haskell

CopyrightTim Newsham
LicenseBSD3-style (see LICENSE)
MaintainerDavid Leimbach <leimy2k@gmail.com>
Stabilityexperimental
PortabilityOnly tested on GHC 6.12.1, uses TypeSynonymInstances
Safe HaskellSafe
LanguageHaskell98

Data.NineP

Contents

Description

Module providing Binary serialization of 9P messages to and from lazy ByteStrings.

This library does not currently provide any networking support or wrappers for easy to write clients or servers, though that may come with time as we decide the best way to implement these.

9P2000 messages are sent in little endian byte order rather than network byte order (big endian)

Lightly tested against an Inferno operating system share with no authentication successfully.

Synopsis

Bin - a little endian encode/decode class for Binary

class Bin a where #

Minimal complete definition

get, put

Methods

get :: Get a #

put :: a -> Put #

Instances
Bin Char # 
Instance details

Defined in Data.NineP

Methods

get :: Get Char #

put :: Char -> Put #

Bin Word8 # 
Instance details

Defined in Data.NineP

Methods

get :: Get Word8 #

put :: Word8 -> Put #

Bin Word16 # 
Instance details

Defined in Data.NineP

Methods

get :: Get Word16 #

put :: Word16 -> Put #

Bin Word32 # 
Instance details

Defined in Data.NineP

Methods

get :: Get Word32 #

put :: Word32 -> Put #

Bin Word64 # 
Instance details

Defined in Data.NineP

Methods

get :: Get Word64 #

put :: Word64 -> Put #

Bin String # 
Instance details

Defined in Data.NineP

Methods

get :: Get String #

put :: String -> Put #

Bin Msg # 
Instance details

Defined in Data.NineP

Methods

get :: Get Msg #

put :: Msg -> Put #

Bin Tag # 
Instance details

Defined in Data.NineP

Methods

get :: Get Tag #

put :: Tag -> Put #

Bin Stat # 
Instance details

Defined in Data.NineP

Methods

get :: Get Stat #

put :: Stat -> Put #

Bin Qid # 
Instance details

Defined in Data.NineP

Methods

get :: Get Qid #

put :: Qid -> Put #

Qid - Server side data type for path tracking (http://9p.cat-v.org for details)

data Qid #

A Plan 9 Qid type. See http://9p.cat-v.org for more information

Constructors

Qid 
Instances
Eq Qid # 
Instance details

Defined in Data.NineP

Methods

(==) :: Qid -> Qid -> Bool #

(/=) :: Qid -> Qid -> Bool #

Show Qid # 
Instance details

Defined in Data.NineP

Methods

showsPrec :: Int -> Qid -> ShowS #

show :: Qid -> String #

showList :: [Qid] -> ShowS #

Bin Qid # 
Instance details

Defined in Data.NineP

Methods

get :: Get Qid #

put :: Qid -> Put #

Stat - Namespace metadata (somewhat like a unix fstat)

data Stat #

Provides information on a path entry at a 9P2000 server

Instances
Eq Stat # 
Instance details

Defined in Data.NineP

Methods

(==) :: Stat -> Stat -> Bool #

(/=) :: Stat -> Stat -> Bool #

Show Stat # 
Instance details

Defined in Data.NineP

Methods

showsPrec :: Int -> Stat -> ShowS #

show :: Stat -> String #

showList :: [Stat] -> ShowS #

Bin Stat # 
Instance details

Defined in Data.NineP

Methods

get :: Get Stat #

put :: Stat -> Put #

Msg - envelope for 9P2000 messages

data Msg #

The message envelope type for all 9P2000 messages

Constructors

Msg 
Instances
Eq Msg # 
Instance details

Defined in Data.NineP

Methods

(==) :: Msg -> Msg -> Bool #

(/=) :: Msg -> Msg -> Bool #

Show Msg # 
Instance details

Defined in Data.NineP

Methods

showsPrec :: Int -> Msg -> ShowS #

show :: Msg -> String #

showList :: [Msg] -> ShowS #

Bin Msg # 
Instance details

Defined in Data.NineP

Methods

get :: Get Msg #

put :: Msg -> Put #

Tag - A message payload type

data Tag #

A type that enumerates all the valid (and one invalid) message types in 9P2000

Instances
Enum Tag # 
Instance details

Defined in Data.NineP

Methods

succ :: Tag -> Tag #

pred :: Tag -> Tag #

toEnum :: Int -> Tag #

fromEnum :: Tag -> Int #

enumFrom :: Tag -> [Tag] #

enumFromThen :: Tag -> Tag -> [Tag] #

enumFromTo :: Tag -> Tag -> [Tag] #

enumFromThenTo :: Tag -> Tag -> Tag -> [Tag] #

Eq Tag # 
Instance details

Defined in Data.NineP

Methods

(==) :: Tag -> Tag -> Bool #

(/=) :: Tag -> Tag -> Bool #

Ord Tag # 
Instance details

Defined in Data.NineP

Methods

compare :: Tag -> Tag -> Ordering #

(<) :: Tag -> Tag -> Bool #

(<=) :: Tag -> Tag -> Bool #

(>) :: Tag -> Tag -> Bool #

(>=) :: Tag -> Tag -> Bool #

max :: Tag -> Tag -> Tag #

min :: Tag -> Tag -> Tag #

Show Tag # 
Instance details

Defined in Data.NineP

Methods

showsPrec :: Int -> Tag -> ShowS #

show :: Tag -> String #

showList :: [Tag] -> ShowS #

Bin Tag # 
Instance details

Defined in Data.NineP

Methods

get :: Get Tag #

put :: Tag -> Put #

VarMsg - A data type encapsulating the various 9P messages

data VarMsg #

A variable message type that encapsulates the valid kinds of messages in a 9P2000 payload

Instances
Eq VarMsg # 
Instance details

Defined in Data.NineP

Methods

(==) :: VarMsg -> VarMsg -> Bool #

(/=) :: VarMsg -> VarMsg -> Bool #

Show VarMsg # 
Instance details

Defined in Data.NineP

putVarMsg - function that can encode all VarMsg types to a lazy ByteString

putVarMsg :: VarMsg -> Put #

For every lower level VarMsg type, encodes a full wrapper around that type for use with 9P2000 streams

getVarMsg - function to decode all VarMsg types from a lazy ByteString

getVarMsg :: Tag -> Get VarMsg #

For every messages type, runs a Get parser to decode that type of payload from the 9P2000 stream

Example

Exchanging initial version data with any 9P2000 server

module Main where
import Data.Maybe
import Control.Monad
import qualified Data.ByteString.Lazy.Char8 as C
import Network.Socket hiding (send, recv)
import Network.Socket.ByteString.Lazy
import Data.Int
import Data.Binary.Get
import Data.Binary.Put
import Debug.Trace
import Data.NineP

connector :: IO Socket 
connector = withSocketsDo $
            do
              ainfo <- getAddrInfo Nothing (Just "127.0.0.1") (Just "6872")
              let a = head ainfo
              sock <- socket AF_INET Stream defaultProtocol

At this point we've just created our socket to a machine on 127.0.0.1:6872 where we'd expect to see a 9P2000 server.

              putStrLn "Trying to connect"
              connect sock (addrAddress (traceShow a a))
              putStrLn "connected!"

The socket is connected at this point, build up a TVersion message, asking to speak to the server with the 9P2000 protocol.

The 1024 tells the server the maximum message size we'd like to support.

              let version = Msg TTversion (-1) $ Tversion 1024 "9P2000"
              putStrLn $ "About to send: " ++ show version

We now need to pack the message into a bytestring. This is handled by the Bin class instance Msg, and the serialization is handled by runPut. We send this data to the socket.

              send sock $ runPut (put version) 
              putStrLn "Getting response"

Now wait for a response from the server, evaluated runGet over it to de-serialize it, and show it.

              msg <- recv sock 50
              let response = runGet get msg ::Msg
              putStrLn $ show response
              return sock