diff options
Diffstat (limited to 'appl/spree/man/styxservers.man2')
| -rw-r--r-- | appl/spree/man/styxservers.man2 | 902 |
1 files changed, 0 insertions, 902 deletions
diff --git a/appl/spree/man/styxservers.man2 b/appl/spree/man/styxservers.man2 deleted file mode 100644 index fca2748a..00000000 --- a/appl/spree/man/styxservers.man2 +++ /dev/null @@ -1,902 +0,0 @@ -.TH STYXSERVERS 2 -.SH NAME -styxservers \- -Styx server implementation assistance -.SH SYNOPSIS -.EX -include "sys.m"; -include "styx.m"; -Tmsg, Rmsg: import Styx; -include "styxservers.m"; -styxservers := load Styxservers Styxservers->PATH; -Styxserver, Fid, Navigator: import styxservers; - -Styxserver: adt { - fd: ref Sys->FD; # file server end of connection - t: ref Navigator; # name space navigator for this server - msize: int; # negotiated Styx message size - - new: fn(fd: ref Sys->FD, t: ref Navigator, rootpath: big) - :(chan of ref Tmsg, ref Styxserver); - reply: fn(srv: self ref Styxserver, m: ref Rmsg): int; - - # protocol operations - attach: fn(srv: self ref Styxserver, m: ref Tmsg.Attach): ref Fid; - clunk: fn(srv: self ref Styxserver, m: ref Tmsg.Clunk): ref Fid; - walk: fn(srv: self ref Styxserver, m: ref Tmsg.Walk): ref Fid; - open: fn(srv: self ref Styxserver, m: ref Tmsg.Open): ref Fid; - read: fn(srv: self ref Styxserver, m: ref Tmsg.Read): ref Fid; - remove: fn(srv: self ref Styxserver, m: ref Tmsg.Remove): ref Fid; - stat: fn(srv: self ref Styxserver, m: ref Tmsg.Stat); - default: fn(srv: self ref Styxserver, gm: ref Tmsg); - - # check validity - cancreate: fn(srv: self ref Styxserver, m: ref Tmsg.Create) - :(ref Fid, int, ref Sys->Dir, string); - canopen: fn(srv: self ref Styxserver, m: ref Tmsg.Open) - :(ref Fid, int, ref Sys->Dir, string); - canread: fn(srv: self ref Styxserver, m: ref Tmsg.Read) - :(ref Fid, string); - canwrite: fn(srv: self ref Styxserver, m: ref Tmsg.Write) - :(ref Fid, string); - - # fid management - getfid: fn(srv: self ref Styxserver, fid: int): ref Fid; - newfid: fn(srv: self ref Styxserver, fid: int): ref Fid; - delfid: fn(srv: self ref Styxserver, c: ref Fid); - allfids: fn(srv: self ref Styxserver): list of ref Fid; - - iounit: fn(srv: self ref Styxserver): int; -}; - -Fid: adt { - fid: int; # client's fid - path: big; # file's 64-bit unique path - qtype: int; # file's qid type (eg, Sys->QTDIR if directory) - isopen: int; # non-zero if file is open - mode: int; # if open, the open mode - uname: string; # user name from original attach - param: string; # attach aname from original attach - data: array of byte; # application data - - clone: fn(f: self ref Fid, nf: ref Fid): ref Fid; - open: fn(f: self ref Fid, mode: int, qid: Sys->Qid); - walk: fn(f: self ref Fid, qid: Sys->Qid); -}; - -Navop: adt { - reply: chan of (ref Sys->Dir, string); # channel for reply - path: big; # file or directory path - pick { - Stat => - Walk => - name: string; - Readdir => - offset: int; # index (origin 0) of first entry to return - count: int; # number of directory entries requested - } -}; - -Navigator: adt { - new: fn(c: chan of ref Navop): ref Navigator; - stat: fn(t: self ref Navigator, path: big): (ref Sys->Dir, string); - walk: fn(t: self ref Navigator, parent: big, name: string) - : (ref Sys->Dir, string); - readdir:fn(t: self ref Navigator, path: big, - offset, count: int): array of ref Sys->Dir; -}; - -init: fn(styx: Styx); -traceset: fn(on: int); - -readbytes: fn(m: ref Styx->Tmsg.Read, d: array of byte): - ref Styx->Rmsg.Read; -readstr: fn(m: ref Styx->Tmsg.Read, s: string): - ref Styx->Rmsg.Read; -openok: fn(uname: string, omode, - perm: int, funame, fgname: string): int; -openmode: fn(o: int): int; -.EE -.SH DESCRIPTION -When writing a Styx file server, there are some -commonly performed tasks that are -fiddly or tedious to implement each time. -.B Styxservers -provides a framework to automate some of these -routine tasks. -In particular, it helps manage the fid space, -implements common default processing for protocol messages, -and assists walking around the -directory hierarchy and reading of directories. Other -tasks, such as defining the structure of the -name space, and reading and writing files in it, are -left to the file server program itself. -Familiarity with Section 5 of the manual which defines the protocol -(see -.IR intro (5)), -and with the representation of Styx messages in Limbo -(see -.IR styx (2)), -is a prerequisite for use of this module. -.PP -.B Styxservers -does not define or store any of the directory hierarchy itself; -instead it queries an external process for information -when necessary, through a value of type -.BR Navigator , -which encapsulates communication with that process. -That process must be started up -independently of each -.BR Styxserver ; -a channel to such a process should be provided -when starting a new -.BR Styxserver . -The channel carries messages of type -.BR Navop . -.IR Styxservers-nametree (2) -provides a ready-made -implementation of such a process that is sufficient for many applications. -.PP -.B Styxserver -keeps tabs on the fids that are currently in use, and remembers -some associated information, such as the Qid path -of the file, whether it has been opened, etc. -It does this using values of type -.BR Fid . -.PP -Once the -.B Styxservers -module has been loaded, -the -.B init -function must be called before anything else, -to initialise its internal state. The -.I styx -argument should be an implementation of -the -.IR styx (2) -module, which will be used to translate messages. -Individual -.B Styxserver -instances do not share state, and are therefore -independently thread-safe. -.SS Fid representation -.B Styxservers -represents each active fid as a -.B Fid -value, -which has the following public members: -.TF param -.TP -.B fid -The integer -.I fid -value provided by the client to refer to an active instance of a file in the file server, -as described in -.IR intro (5). -.TP -.B path -The 64-bit qid path that uniquely identifies the file on the file server, -as described in -.IR intro (5). -It is set by -.IB f .walk -and -.IB f .open -(see below). -.TP -.B qtype -The file's qid type; it is -.B Sys->QTDIR -if and only if the fid refers to a directory. -The value is set by -.IB f .walk -and -.IB f .open -(see below). -.TP -.B isopen -Non-zero if and only if the fid has been opened by an -.IR open (5) -message. -It is initially zero, and set by -.IB f .open -(see below). -.TP -.B mode -Valid only if the fid has been opened. -It has one of the values -.BR Sys->OREAD , -.BR Sys->OWRITE , -.BR Sys->ORDWR , -possibly ORed with -.BR Sys->ORCLOSE , -corresponding to the mode with which the file was opened. -It is set by -.IB f .open -(see below). -.TP -.B uname -The name of the user that created the fid. -.TP -.B param -Set by -.B Styxservers -to the -.B aname -of the initial -.IR attach (5) -message, -and subsequently inherited by each new fid created by -.IR walk (5), -but not otherwise used by -.B Styxservers -itself, and may be changed by the application. -.TP -.B data -Unused by -.BR Styxservers ; -for application use. -It might be used, for instance, to implement a file that gives different -data to different clients. -.TP -.IB f .clone( nf ) -Copy the current state of all members of -.I f -except -.IB f .fid\f1,\fP -into -.IR nf , -and return -.IR nf . -Used by -.BR Styxserver.walk , -and is needed by an application only if it replaces that function. -.TP -.IB f .walk( qid ) -Make -.I f -refer to the file with the given -.IR qid : -set -.IB f .path -and -.IB f .qtype -from -.IB qid .path -and -.IB qid .qtype . -Used by -.IB Styxserver.walk -and is needed by an application only if it replaces that function. -.TP -.IB f .open( mode,\ qid ) -Mark -.I f -as `open', -set -.IR f .mode -to -.IR mode , -and set -.B path -and -.B qtype -to the path and type of -.IR qid . -Used by the -implementations of -.B open -and -.B create -messages. -The default implementation of -.IR open (5) -in -.B Styxserver -obtains the value of -.I mode -from -.B Styxserver.canopen -(below), -and -obtains the value of -.I qid -by querying the application's navigator. -.SS Styxserver and file server state -Each -.B Styxserver -value holds the state for a single file server, including its active fids, -the link to the external name space process, and other internal data. -Most of the state is manipulated through the member functions described below. -The exceptions are two read-only values: -the -.B Navigator -reference -.IB srv .t -which can be used to access that navigator; and -the file descriptor -.IB srv .fd -that is the file server's end of the connection to the Styx client. -Both values are initially provided by the file serving application, -but can be accessed through the -.B Styxserver -value for convenience. -The file descriptor value is normally used only through -.BR Styxserver.reply , -but will be needed directly if the caller needs the file descriptor value -as a parameter to -.IR sys-pctl (2) -when insulating the serving process's file descriptors from the surrounding environment. -.PP -The first set of functions in -.B Styxserver -provides common and default actions: -.TP -.B Styxserver.new(\fIfd\fP,\ \fIt\fP,\ \fIrootpath\fP) -Create a new -.BR Styxserver . -It returns a tuple, say -.RI ( c ", " srv ), -and spawns a new process, which uses -.IR styx (2) -to read and parse Styx messages read -from -.IR fd , -and send them down -.IR c ; -.I t -should be a -.B Navigator -adt which the -.B Styxserver -can use to answer queries -on the name space (see ``Navigating file trees'', below). -.I Rootpath -gives the Qid path of the root of the served name space. -.TP -.IB srv .reply(\fIm\fP) -Send a reply (R-message) to a client. The various utility methods, -listed below, call this function to make their response. -.TP -.IB srv .attach(\fIm\fP) -Respond to an -.IR attach (5) -message -.IR m , -creating a new fid in the process, and returning it. -Returns -.B nil -if -.IB m .fid -is a duplicate of an existing fid. -The value of the attach parameter -.IB m .aname -is copied into the new fid's -.B param -field, as is the attaching user name, -.IB m .uname . -.TP -.IB srv .clunk(\fIm\fP) -Respond to a -.IR clunk (5) -message -.IR m , -and return the old -.BR Fid . -Note that this does nothing about remove-on-close -files; that should be programmed explicitly if needed. -.TP -.IB srv .walk(\fIm\fP) -Respond to a -.IR walk (5) -message -.IR m , -querying -.IB srv . t -for information on existing files. -.TP -.IB srv .open(\fIm\fP) -Respond to an -.IR open (5) -message -.IR m . -This will allow a file to be opened if its permissions allow the -specified mode of access. -.TP -.IB srv .read(\fIm\fP) -Respond to a -.IR read (5) -message -.IR m . -If a directory is being read, the appropriate reply -is made; for files, an error is given. -.TP -.IB srv .remove(\fIm\fP) -Respond to a -.IR remove (5) -message -.IR m -with an error, clunking the fid as it does so, -and returning the old -.BR Fid . -.TP -.IB srv .stat(\fIm\fP) -Respond to a -.IR stat (5) -message -.IR m . -.TP -.IB srv .default(\fIgm\fP) -Respond to an arbitrary T-message, -.IR gm , -as appropriate (eg, by calling -.IB srv .walk -for a -.IR walk (5) -message). -It responds appropriately to -.IR version (5), -and replies to -.B Tauth -(see -.IR attach (5)) -stating that authentication is not required. -Other messages without an associated -.B Styxserver -function are generally responded to -with a ``permission denied'' error. -.PP -All the functions above check the validity of the fids, modes, counts and offsets -in the messages, and automatically reply to the client with a suitable -.IR error (5) -message on error. -.PP -The following further -.B Styxserver -operations are useful -in applications that override all or part of the default handling -(in particular, -to process read and write requests): -.TP -.IB srv .canopen( m ) -Check whether it is legal to open a file as requested by message -.IR m : -the fid is valid but not already open, the corresponding file exists and its -permissions allow access in the requested mode, and if -.B Sys->ORCLOSE -is requested, the parent directory is writable (to allow the file to be removed when closed). -.B Canopen -returns a tuple, say -.RI ( f ,\ mode ,\ d,\ err\ \fP). -If the open request was invalid, -.I f -will be nil, and the string -.I err -will diagnose the error (for return to the client in an -.B Rmsg.Error -message). -If the request was valid: -.I f -contains the -.B Fid -representing the file to be opened; -.I mode -is the access mode derived from -.IB m .mode , -.BR Sys->OREAD , -.BR Sys->OWRITE , -.BR Sys->ORDWR , -ORed with -.BR Sys->ORCLOSE ; -.I d -is a -.B Dir -value giving the file's attributes, obtained from the navigator; -and -.I err -is nil. -Once the application has done what it must to open the file, -it must call -.IB f .open -to mark it open. -.TP -.IB srv .cancreate( m ) -Checks whether the -creation of the file requested by -message -.I m -is legal: -the fid is valid but not open, refers to a directory, -the permissions returned by -.IR srv .t.stat -show that directory is writable by the requesting user, -the name does not already exist in that directory, -and the mode with which the new file would be opened is valid. -.B Cancreate -returns a tuple, say -.RI ( f ,\ mode,\ d,\ err\ \fP). -If the creation request was invalid, -.I f -will be nil, and the string -.I err -will diagnose the error, for use in an error reply to the client. -If the request was valid: -.I f -contains the -.B Fid -representing the parent directory; -.I mode -is the open mode as defined for -.B canopen -above; -.I d -is a -.B Dir -value containing some initial attributes for the new file or directory; -and -.I err -is nil. -The initial attributes set in -.I d -are: -.IB d .name -(the name of the file to be created); -.IB d .uid -and -.IB d .muid -(the user that did the initial attach); -.IB d .gid , -.IB d .dtype , -.IB d .dev -(taken from the parent directory's attributes); -and -.IB d .mode -holds the file mode that should be attributed to the new -file (taking into account the parent mode, as -described in -.IR open (5)). -The caller must supply -.IB d .qid -once the file has successfully been created, -and -.IB d .atime -and -.IB d .mtime ; -it must also call -.IB f .open -to mark -.I f -open and set its path to the file's path. -If the file cannot be created successfully, the application should reply with -an -.IR error (5) -message and leave -.I f -untouched. -The -.B Fid -.I f -will then continue to refer to the original directory, and remain unopened. -.TP -.IB srv .canread( m ) -Checks whether -.IR read (5) -message -.I m -refers to a valid fid that has been opened for reading, -and that the count and file offset are non-negative. -.B Canread -returns a tuple, say -.RI ( f ,\ err ); -if the attempted access is illegal, -.I f -will be nil, and -.I err -contains a description of the error, -otherwise -.I f -contains the -.B Fid -corresponding to the file in question. -It is typically called by an application's implementation of -.B Tmsg.Read -to obtain the -.B Fid -corresponding to the fid in the message, and check the access. -.TP -.IB srv .canwrite( m ) -Checks whether -message -.I m -refers to a valid fid that has been opened for writing, -and that the file offset is non-negative. -.B Canwrite -returns a tuple, say -.RI ( f ,\ err ); -if the attempted access is illegal, -.I f -will be nil, and -.I err -contains a description of the error, -otherwise -.I f -contains the -.B Fid -corresponding to the file in question. -It is typically called by an application's implementation of -.B Tmsg.Write -to obtain the -.B Fid -corresponding to the fid in the message, and check the access. -.TP -.IB srv .iounit() -Return an appropriate value for use as the -.I iounit -element in -.B Rmsg.Open -and -.B Rmsg.Create -replies, -as defined in -.IR open (5), -based on the message size negotiated by the initial -.IR version (5) -message. -.PP -The remaining functions are normally used only by servers that need to -override default actions. -They maintain and access the mapping between a client's fid values presented in -.B Tmsg -messages and the -.B Fid -values that represent the corresponding files internally. -.TP -.IB srv .newfid(\fIfid\fP) -Create a new -.B Fid -associated with number -.I fid -and return it. -Return nil if the -.I fid -is already in use (implies a client error if the server correctly clunks fids). -.TP -.IB srv .getfid(\fIfid\fP) -Get the -.B Fid -data associated with numeric id -.IR fid ; -return nil if there is none such (a malicious or erroneous client -can cause this). -.TP -.IB srv .delfid(\fIfid\fP) -Delete -.I fid -from the table of fids in the -.BR Styxserver . -(There is no error return.) -.TP -.IB srv .allfids() -Return a list of all current fids (ie, the files currently active on the client). -.PP -.B Newfid -is required when processing -.IR auth (5), -.IR attach (5) -and -.IR walk (5) -messages to create new fids. -.B Delfid -is used to clunk fids when processing -.IR clunk (5), -.IR remove (5), -and in a failed -.IR walk (5) -when it specified a new fid. -All other messages should refer only to already existing fids, and the associated -.B Fid -data is fetched by -.BR getfid . -.SS Navigating file trees -When a -.B Styxserver -instance needs to know about the namespace, -it queries an external process through a channel -by sending a -.B Navop -request; -each such request carries with it a -.B reply -channel through which the -reply should be made. -The reply tuple has a reference to a -.B Sys->Dir -value that is non-nil on success, and a diagnostic string -that is non-nil on error. -.PP -Files in the tree are referred to -by their Qid -.BR path . -The requests are: -.TF Walk -.TP -.BR Stat -.br -Find a file in the hierarchy by its -.BR path , -and reply with the corresponding -.B Dir -data if found (or a diagnostic on error). -.TP -.BR Walk -.br -Look for file -.B name -in the directory with the given -.BR path . -.TP -.BR Readdir -.br -Get information on selected files in the directory with the given -.BR path . -In this case, the reply channel is used to send -a sequence of values, one for each entry in the directory, finishing with a tuple value -.BR (nil,nil) . -The entries to return are those selected by an -.B offset -that is the index (origin 0) of the first directory entry to return, -and a -.B count -of a number of entries to return starting with that index. -Note that both values are expressed in units of directory entries, not as byte counts. -.PP -.B Styxserver -provides a -.B Navigator -adt to enable convenient access to this functionality; calls -into the -.B Navigator -adt are bundled up into requests on the channel, and the -reply returned. -The functions provided are: -.TP 10 -.BI Navigator.new( c ) -Create a new -.BR Navigator , -sending requests down -.IR c . -.TP -.IB t .stat(\fIpath\fP) -Find the file with the given -.IR path . -Return a tuple -.RI ( d ,\ err ), -where -.I d -holds directory information for the file -if found; otherwise -.I err -contains an error message. -.TP -.IB t .walk(\fIparent\fP,\ \fIname\fP) -Find the file with name -.I name -inside parent directory -.IR parent . -Return a tuple as for -.BR stat . -.TP -.IB t .readdir(\fIpath\fP,\ \fIoffset\fP,\ \fIcount\fP) -Return directory data read from directory -.IR path , -starting at entry -.I offset -for -.I count -entries. -.SS Other functions -The following functions provide some commonly used functionality: -.TP 10 -.BI readbytes( m ,\ d ) -Assuming that the file in question contains data -.IR d , -.B readbytes -returns an appropriate reply to -.IR read (5) -message -.IR m , -taking account of -.IB m .offset -and -.IB m.count -when extracting data from -.IR d . -.TP 10 -.BI readstr( m ,\ s ) -Assuming that the file in question contains string -.IR s , -.B readstr -returns an appropriate reply to -.IR read (5) -message -.IR m , -taking account of -.IB m .offset -and -.IB m.count -when extracting data from the UTF-8 representation of -.IR s . -.TP -.BI openok (\fIuname\fP,\ \fIomode\fP,\ \fIperm\fP,\ \fIfuid\fP,\ \fIfgid\fP) -Does standard permission checking, assuming user -.I uname -is trying to open a file with access mode -.IR omode , -where the file is owned by -.IR fuid , -has group -.IR fgid , -and permissions -.IR perm . -Returns true (non-zero) if permission would be granted, and false (zero) otherwise. -.TP -.BI openmode( o ) -Checks to see whether the open mode -.I o -is well-formed; if it is not, -.B openmode -returns -1; if it is, it returns the mode -with OTRUNC and ORCLOSE flags removed. -.TP -.BI traceset( on ) -If -.I on -is true (non-zero), -will trace Styx requests and replies, on standard error. -This option must be set before creating a -.BR Styxserver , -to ensure that it preserves its standard error descriptor. -.SS Constants -.B Styxservers -defines a number of constants applicable to the writing -of Styx servers, including: -.TP -.BR Einuse\fP,\fP\ Ebadfid\fP,\fP\ Eopen\fP,\fP\ Enotfound\fP,\fP\ Enotdir\fP,\fP\ Eperm\fP,\fP\ Ebadarg\fP,\fP\ Eexists -These provide standard strings for commonly used error conditions, -to be used in -.B Rmsg.Error -replies. -.SS Authentication -If authentication is required beyond that provided at the link level -(for instance by -.IR security-auth (2)), -the server application must handle -.B Tauth -itself, -remember the value of -.I afid -in that message, and generate an -.B Rauth -reply with a suitable Qid referring to a file with -.B Qid.qtype -of -.BR QTAUTH . -Following successful authentication by read and write on that file, -it must associate that status with the -.IR afid . -Then, on a subsequent -.B Tattach -message, before calling -.I srv .attach -it must check that the -.BR Tattach 's -.I afid -value corresponds to one previously authenticated, and -reply with an appropriate error if not. -.SH SOURCE -.B /appl/lib/styxservers.b -.SH SEE ALSO -.IR styxservers-nametree (2), -.IR sys-stat (2), -.IR intro (5) |
