go9p

package module
v0.0.0-...-a7c66ab Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2018 License: MIT Imports: 7 Imported by: 0

README

go9p

This is a golang implementation of the 9p2000 protocol. Provided is foremost an API to implement servers serving the protocol, but also some more primitive constructs if you'd like to dink with the protocol outside the confines of what the API provides.

Examples are available in examples/ (duh)

Docs available here: http://godoc.org/github.com/knusbaum/go9p

These programs are meant to be used with plan9port's 9pfuse (or some equivalent) https://github.com/9fans/plan9port

For example, you would mount the ramfs example with the following command:

9pfuse localhost:9999 /mnt/myramfs

Then you can copy files to/from the ramfs and do all the other stuff that you'd expect.

This is distributed under the MIT license

    Copyright (c) 2016 Kyle Nusbaum


    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is furnished
    to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Documentation

Overview

Package go9p is a Go implementation of the 9P2000 protocol. It imlements a parser and composer for 9P2000 messages as well as a server (See the Server type).

The server requires users to implement callbacks for certain operations. Open, Read, Write, Create, and Setup. See the docs for the *context structs for explanations of how to appropriately respond to these events.

IFCall, FCall, and all the T* and R* types are internal types used for parsing, etc. They're left exposed if you want to do some less structured 9P programming.

Details of the 9P2000 protocol can be found here: http://knusbaum.inlisp.org/res/rfc9p2000.html

Index

Constants

View Source
const (
	Oread  = 0
	Owrite = 1
	Ordwr  = 2
	Oexec  = 3
	None   = 4
	Otrunc = 0x10
)

Open mode file constants

View Source
const (
	Tversion = 100
	Rversion = 101
	Tauth    = 102
	Rauth    = 103
	Tattach  = 104
	Rattach  = 105
	Terror   = 106 /* illegal */
	Rerror   = 107
	Tflush   = 108
	Rflush   = 109
	Twalk    = 110
	Rwalk    = 111
	Topen    = 112
	Ropen    = 113
	Tcreate  = 114
	Rcreate  = 115
	Tread    = 116
	Rread    = 117
	Twrite   = 118
	Rwrite   = 119
	Tclunk   = 120
	Rclunk   = 121
	Tremove  = 122
	Rremove  = 123
	Tstat    = 124
	Rstat    = 125
	Twstat   = 126
	Rwstat   = 127
)

Variables

This section is empty.

Functions

func SliceForRead

func SliceForRead(ctx *ReadContext, file []byte) []byte

SliceForRead - Given a read context and a slice representing the full file contents, return a slice at offset ctx.Offset of ctx.Count bytes. Handles cases where file is nil, offset + count > len(file), etc. The return value is ready to be passed to ctx.Respond.

Types

type AuthContext

type AuthContext struct {
	Ctx
}

AuthContext - The context given to the user's authentication functions

func (*AuthContext) SetAuthenticated

func (ctx *AuthContext) SetAuthenticated(b bool)

type Client

type Client struct {
	// contains filtered or unexported fields
}

func (*Client) Connect

func (cli *Client) Connect(rw io.ReadWriter) error

func (*Client) Create

func (cli *Client) Create(path string, fmode uint32, omode Mode) (*File9P, error)

func (*Client) ListDir

func (cli *Client) ListDir(path string) ([]Stat, error)

func (*Client) Open

func (cli *Client) Open(path string, omode Mode) (*File9P, error)

func (*Client) Stat

func (cli *Client) Stat(path string) (*Stat, error)

type CreateContext

type CreateContext struct {
	Ctx
	NewPath string
	Name    string
	Perm    uint32
	Mode    uint8
}

CreateContext - The context passed to the Create callback in Server. NewPath - the full path of the new file (including Name) Name - the name of the new file. Perm - the permissions of the file. Lower 9 bits are Unix-style permissions (user/group/other rwxrwxrwx). The high bit (1 << 31) is the directory flag.

func (*CreateContext) Respond

func (ctx *CreateContext) Respond(length uint64) *File

Respond - Creates the file requested and sets the length. Returns the new file.

type Ctx

type Ctx struct {
	Fid  uint32
	File *File
	// contains filtered or unexported fields
}

Ctx is the base context. All other contexts embed this type and therefore inherit the Fail() and UpdateFS() functions.

Fid is the file descriptor on which the request is operating. File is the file associated with the request. For Setup, File is the root directory, and for Create, it's the directory in which the client is trying to create a file. For Open, Read, and Write, File is the file to be opened, read, or written.

func (*Ctx) Fail

func (ctx *Ctx) Fail(s string)

Fail - Call this on the context when a request can't be fulfilled. The string is passed to the client as an explanation of the failure that occurred.

func (*Ctx) FileByPath

func (ctx *Ctx) FileByPath(path string) *File

func (*Ctx) UniqueFileID

func (ctx *Ctx) UniqueFileID() string

Returns an ID unique to a particular connection and file. Different connections can use the same Fids, so this is a way of tracking a particular connection/file pair.

func (*Ctx) UpdateFS

func (ctx *Ctx) UpdateFS(fn func(*UpdateContext))

UpdateFS runs the argument function, passing it an update context so that it can make modifications to the filesystem. fn is not run immediately, but passed to the main routine. This removes the need for synchronization. You can be sure that only one routine is modifying the filesystem structure at any one time.

func (*Ctx) Username

func (ctx *Ctx) Username() string

Username - Returns the user associated with the action. This will be the empty string on Setup - no user has connected.

type DirReadContext

type DirReadContext struct {
	Ctx
	// contains filtered or unexported fields
}

func (*DirReadContext) Respond

func (ctx *DirReadContext) Respond()

Respond - Marks the directory ready for read by the client.

type FCall

type FCall struct {
	Ctype uint8
	Tag   uint16
}

FCall - The base FCall type. All FCall-like types embed this and inherit its functions. For explanations of the functions, see IFCall.

func (*FCall) GetFCall

func (fc *FCall) GetFCall() *FCall

func (*FCall) Reply

func (fc *FCall) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*FCall) String

func (fc *FCall) String() string

type File

type File struct {
	Path   string
	Stat   Stat
	Parent *File
	// contains filtered or unexported fields
}

File - Represents a file in the filesystem. Path - The full path of the file in the filesystem. Stat - The Stat struct associated with the file. Parent - A pointer to the file's parent directory.

func (*File) IsDirectory

func (f *File) IsDirectory() bool

func (*File) ListSubfiles

func (f *File) ListSubfiles() []*File

type File9P

type File9P struct {
	// contains filtered or unexported fields
}

func (*File9P) Close

func (f *File9P) Close() error

func (*File9P) Read

func (f *File9P) Read(p []byte) (n int, err error)

func (*File9P) Seek

func (f *File9P) Seek(offset uint64)

func (*File9P) SingleRead

func (f *File9P) SingleRead(p []byte) (n int, err error)

func (*File9P) SingleWrite

func (f *File9P) SingleWrite(p []byte) (n int, err error)

func (*File9P) Write

func (f *File9P) Write(p []byte) (n int, err error)

type IFCall

type IFCall interface {
	String() string
	Parse([]byte) ([]byte, error)
	Compose() []byte
	GetFCall() *FCall
	Reply(*filesystem, *connection, *Server) IFCall
}

IFCall - the interface that all FCall-like types imlement. String - typical human readable string representation. Parse - Parse the call from a slice. Compose - returns a slice containing the call serialized according the the 9P2000 protocol, ready to be written out to a client. GetFCall() - get the base FCall associated with this call. Reply() - Handles the fcall and calls appropriate functions in Server. Returns nil or an IFCall that should be sent as a response back to the client.

func ParseCall

func ParseCall(r io.Reader) (IFCall, error)

ParseCall - Reads from a 9P2000 stream and parses an IFCall from it. On error, the protocol on the stream is in an unknown state and the stream should be closed.

type Mode

type Mode uint8

type OpenContext

type OpenContext struct {
	Ctx
	Mode uint8
}

OpenContext - The context passed to the Open callback in Server. Mode is the requested open mode for the file. Mode can be ignored unless you want to do some special logic. The server handles the common case - it won't call Write on a file not opened for writing, etc.

func (*OpenContext) Respond

func (ctx *OpenContext) Respond()

Respond - Tells the client the open operation was successful.

type ParseError

type ParseError struct {
	Err string
}

func (*ParseError) Error

func (pe *ParseError) Error() string

type Qid

type Qid struct {
	Qtype uint8
	Vers  uint32
	Uid   uint64
}

Qid - Qids are unique ids for files. Qtype should be the upper 8 bits of the file's permissions (Stat.Mode)

func (*Qid) Compose

func (qid *Qid) Compose() []byte

Compose - Returns a slice of the Qid serialized to be written out on a 9P2000 stream.

func (*Qid) Parse

func (qid *Qid) Parse(buff []byte) ([]byte, error)

Parse - Parse a Qid from a slice of a 9P2000 stream

func (*Qid) String

func (qid *Qid) String() string

type RAttach

type RAttach struct {
	FCall
	Qid Qid
}

func (*RAttach) Compose

func (attach *RAttach) Compose() []byte

func (*RAttach) Parse

func (attach *RAttach) Parse(buff []byte) ([]byte, error)

func (*RAttach) String

func (attach *RAttach) String() string

type RAuth

type RAuth struct {
	FCall
	Aqid Qid
}

func (*RAuth) Compose

func (auth *RAuth) Compose() []byte

func (*RAuth) Parse

func (auth *RAuth) Parse(buff []byte) ([]byte, error)

func (*RAuth) String

func (auth *RAuth) String() string

type RClunk

type RClunk struct {
	FCall
}

func (*RClunk) Compose

func (clunk *RClunk) Compose() []byte

func (*RClunk) Parse

func (clunk *RClunk) Parse(buff []byte) ([]byte, error)

func (*RClunk) String

func (clunk *RClunk) String() string

type RCreate

type RCreate struct {
	FCall
	Qid    Qid
	Iounit uint32
}

func (*RCreate) Compose

func (create *RCreate) Compose() []byte

func (*RCreate) Parse

func (create *RCreate) Parse(buff []byte) ([]byte, error)

func (*RCreate) String

func (create *RCreate) String() string

type RError

type RError struct {
	FCall
	Ename string
}

func (*RError) Compose

func (error *RError) Compose() []byte

func (*RError) Parse

func (error *RError) Parse(buff []byte) ([]byte, error)

func (*RError) String

func (error *RError) String() string

type RFlush

type RFlush struct {
	FCall
}

func (*RFlush) Compose

func (flush *RFlush) Compose() []byte

func (*RFlush) Parse

func (flush *RFlush) Parse(buff []byte) ([]byte, error)

func (*RFlush) String

func (flush *RFlush) String() string

type ROpen

type ROpen struct {
	FCall
	Qid    Qid
	Iounit uint32
}

func (*ROpen) Compose

func (open *ROpen) Compose() []byte

func (*ROpen) Parse

func (open *ROpen) Parse(buff []byte) ([]byte, error)

func (*ROpen) String

func (open *ROpen) String() string

type RRead

type RRead struct {
	FCall
	Count uint32
	Data  []byte
}

func (*RRead) Compose

func (read *RRead) Compose() []byte

func (*RRead) Parse

func (read *RRead) Parse(buff []byte) ([]byte, error)

func (*RRead) String

func (read *RRead) String() string

type RRemove

type RRemove struct {
	FCall
}

func (*RRemove) Compose

func (remove *RRemove) Compose() []byte

func (*RRemove) Parse

func (remove *RRemove) Parse(buff []byte) ([]byte, error)

func (*RRemove) String

func (remove *RRemove) String() string

type RStat

type RStat struct {
	FCall
	Stat
}

func (*RStat) Compose

func (stat *RStat) Compose() []byte

func (*RStat) Parse

func (stat *RStat) Parse(buff []byte) ([]byte, error)

func (*RStat) String

func (stat *RStat) String() string

type RWalk

type RWalk struct {
	FCall
	Nwqid uint16
	Wqid  []Qid
}

func (*RWalk) Compose

func (walk *RWalk) Compose() []byte

func (*RWalk) Parse

func (walk *RWalk) Parse(buff []byte) ([]byte, error)

func (*RWalk) String

func (walk *RWalk) String() string

type RWrite

type RWrite struct {
	FCall
	Count uint32
}

func (*RWrite) Compose

func (write *RWrite) Compose() []byte

func (*RWrite) Parse

func (write *RWrite) Parse(buff []byte) ([]byte, error)

func (*RWrite) String

func (write *RWrite) String() string

type RWstat

type RWstat struct {
	FCall
}

func (*RWstat) Compose

func (wstat *RWstat) Compose() []byte

func (*RWstat) Parse

func (wstat *RWstat) Parse(buff []byte) ([]byte, error)

func (*RWstat) String

func (wstat *RWstat) String() string

type ReadContext

type ReadContext struct {
	Ctx
	Offset uint64
	Count  uint32
}

ReadContext - The context passed to the Read callback in Server. Offset is the offset into the file that is requested Count is the number of bytes requested.

func (*ReadContext) Respond

func (ctx *ReadContext) Respond(data []byte)

Respond - Sends requested data back to the client.

type RemoveContext

type RemoveContext struct {
	Ctx
}

RemoveContext - The context passed to the Create callback in Server.

func (*RemoveContext) Respond

func (ctx *RemoveContext) Respond()

Respond removes the file

type Server

type Server struct {
	Open    func(ctx *OpenContext)
	Read    func(ctx *ReadContext)
	DirRead func(ctx *DirReadContext) // CANNOT SPAWN GOROUTINES USING UPDATE CONTEXT!
	Write   func(ctx *WriteContext)
	Close   func(ctx *Ctx)
	Create  func(ctx *CreateContext)
	Remove  func(ctx *RemoveContext)
	Setup   func(ctx *UpdateContext)
	Auth    func(ctx *AuthContext, in <-chan []byte, out chan<- []byte) // Run in a separate goroutine
	// contains filtered or unexported fields
}

Server struct contains functions which are called on file open, read, write, and create See the definitions of the various context types. All "inherit" Ctx and so the Fail() and AddFile() functions. Each implements a Respond() function. The parameters and behavior of each changes among the contexts

Setup is called once the server is up and running, and is the appropriate place to add any initial files to the server.

func (*Server) Serve

func (srv *Server) Serve(listener net.Listener)

Serve serves the 9P2000 file server.

type Stat

type Stat struct {
	Stype  uint16
	Dev    uint32
	Qid    Qid
	Mode   uint32
	Atime  uint32
	Mtime  uint32
	Length uint64
	Name   string
	Uid    string
	Gid    string
	Muid   string
}

func (*Stat) Compose

func (stat *Stat) Compose() []byte

func (*Stat) ComposeLength

func (stat *Stat) ComposeLength() uint16

func (*Stat) Parse

func (stat *Stat) Parse(buff []byte) ([]byte, error)

func (*Stat) String

func (stat *Stat) String() string

type TAttach

type TAttach struct {
	FCall
	Fid   uint32
	Afid  uint32
	Uname string
	Aname string
}

func (*TAttach) Compose

func (attach *TAttach) Compose() []byte

func (*TAttach) Parse

func (attach *TAttach) Parse(buff []byte) ([]byte, error)

func (*TAttach) Reply

func (attach *TAttach) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TAttach) String

func (attach *TAttach) String() string

type TAuth

type TAuth struct {
	FCall
	Afid  uint32
	Uname string
	Aname string
}

func (*TAuth) Compose

func (auth *TAuth) Compose() []byte

func (*TAuth) Parse

func (auth *TAuth) Parse(buff []byte) ([]byte, error)

func (*TAuth) Reply

func (auth *TAuth) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TAuth) String

func (auth *TAuth) String() string

type TClunk

type TClunk struct {
	FCall
	Fid uint32
}

func (*TClunk) Compose

func (clunk *TClunk) Compose() []byte

func (*TClunk) Parse

func (clunk *TClunk) Parse(buff []byte) ([]byte, error)

func (*TClunk) Reply

func (clunk *TClunk) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TClunk) String

func (clunk *TClunk) String() string

type TCreate

type TCreate struct {
	FCall
	Fid  uint32
	Name string
	Perm uint32
	Mode uint8
}

func (*TCreate) Compose

func (create *TCreate) Compose() []byte

func (*TCreate) Parse

func (create *TCreate) Parse(buff []byte) ([]byte, error)

func (*TCreate) Reply

func (create *TCreate) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TCreate) String

func (create *TCreate) String() string

type TFlush

type TFlush struct {
	FCall
	Oldtag uint16
}

func (*TFlush) Compose

func (flush *TFlush) Compose() []byte

func (*TFlush) Parse

func (flush *TFlush) Parse(buff []byte) ([]byte, error)

func (*TFlush) String

func (flush *TFlush) String() string

type TOpen

type TOpen struct {
	FCall
	Fid uint32
	Mode
}

func (*TOpen) Compose

func (open *TOpen) Compose() []byte

func (*TOpen) Parse

func (open *TOpen) Parse(buff []byte) ([]byte, error)

func (*TOpen) Reply

func (open *TOpen) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TOpen) String

func (open *TOpen) String() string

type TRVersion

type TRVersion struct {
	FCall
	Msize   uint32
	Version string
}

func (*TRVersion) Compose

func (version *TRVersion) Compose() []byte

func (*TRVersion) Parse

func (version *TRVersion) Parse(buff []byte) ([]byte, error)

func (*TRVersion) Reply

func (version *TRVersion) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TRVersion) String

func (version *TRVersion) String() string

type TRead

type TRead struct {
	FCall
	Fid    uint32
	Offset uint64
	Count  uint32
}

func (*TRead) Compose

func (read *TRead) Compose() []byte

func (*TRead) Parse

func (read *TRead) Parse(buff []byte) ([]byte, error)

func (*TRead) Reply

func (read *TRead) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TRead) String

func (read *TRead) String() string

type TRemove

type TRemove struct {
	FCall
	Fid uint32
}

func (*TRemove) Compose

func (remove *TRemove) Compose() []byte

func (*TRemove) Parse

func (remove *TRemove) Parse(buff []byte) ([]byte, error)

func (*TRemove) Reply

func (remove *TRemove) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TRemove) String

func (remove *TRemove) String() string

type TStat

type TStat struct {
	FCall
	Fid uint32
}

func (*TStat) Compose

func (stat *TStat) Compose() []byte

func (*TStat) Parse

func (stat *TStat) Parse(buff []byte) ([]byte, error)

func (*TStat) Reply

func (stat *TStat) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TStat) String

func (stat *TStat) String() string

type TWalk

type TWalk struct {
	FCall
	Fid    uint32
	Newfid uint32
	Nwname uint16
	Wname  []string
}

func (*TWalk) Compose

func (walk *TWalk) Compose() []byte

func (*TWalk) Parse

func (walk *TWalk) Parse(buff []byte) ([]byte, error)

func (*TWalk) Reply

func (walk *TWalk) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TWalk) String

func (walk *TWalk) String() string

type TWrite

type TWrite struct {
	FCall
	Fid    uint32
	Offset uint64
	Count  uint32
	Data   []byte
}

func (*TWrite) Compose

func (write *TWrite) Compose() []byte

func (*TWrite) Parse

func (write *TWrite) Parse(buff []byte) ([]byte, error)

func (*TWrite) Reply

func (write *TWrite) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TWrite) String

func (write *TWrite) String() string

type TWstat

type TWstat struct {
	FCall
	Fid  uint32
	Stat Stat
}

func (*TWstat) Compose

func (wstat *TWstat) Compose() []byte

func (*TWstat) Parse

func (wstat *TWstat) Parse(buff []byte) ([]byte, error)

func (*TWstat) Reply

func (wstat *TWstat) Reply(fs *filesystem, conn *connection, s *Server) IFCall

func (*TWstat) String

func (wstat *TWstat) String() string

type UpdateContext

type UpdateContext struct {
	Ctx
}

UpdateContext is the context given to functions passed to UpdateFS. UpdateContext has functions that allow a user to modify the filesystem, adding, removing files, etc.

func (*UpdateContext) AddFile

func (ctx *UpdateContext) AddFile(mode uint32, length uint64, name string, owner string, parent *File) *File

AddFile - Use this function to add a file to the server. mode - The mode for the new file length - The length of the new file name - The file's name (not the full path) owner - The owner of the new file parent - The directory that the file will be created under. This function returns a pointer to the newly created file.

func (*UpdateContext) RemoveFile

func (ctx *UpdateContext) RemoveFile(f *File)

RemoveFile - Remove a file from the filesystem.

type WriteContext

type WriteContext struct {
	Ctx
	Data   []byte
	Offset uint64
	Count  uint32
}

WriteContext - The context passed to the Write callback in Server. Data - the data from the client that they want to write to the file Offset - the offset within the file that the data is to be written at Count - the number of bytes to be written. (this should correspond with len(Data)

func (*WriteContext) Respond

func (ctx *WriteContext) Respond(count uint32)

Respond - Tells the client the number of bytes that were successfully written. This should be identical to Writecontext.Count. The client might consider it to be an error if the bytes written differs from the requested amount.

Directories

Path Synopsis
examples
ramfs
A memory-backed filesystem for storing files.
A memory-backed filesystem for storing files.
utilfs
This is a sample filesystem that serves a couple "utilities" There's /time, which when read, will return a human-readable string of the current time.
This is a sample filesystem that serves a couple "utilities" There's /time, which when read, will return a human-readable string of the current time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL