   INTRO(9P) INTRO(9P)

   NAME
   intro – introduction to the Plan 9 File Protocol, 9P

   SYNOPSIS
   #include <fcall.h>

   DESCRIPTION
   A Plan 9 server is an agent that provides one or more hierarchical file
   systems -- file trees -- that may be accessed by Plan 9 processes. A
   server responds to requests by clients to navigate the hierarchy, and
   to create, remove, read, and write files. The prototypical server is a
   separate machine that stores large numbers of user files on permanent
   media; such a machine is called, somewhat confusingly, a file server.
   Another possibility for a server is to synthesize files on demand,
   perhaps based on information on data structures maintained in memory;
   the plumber(4) server is an example of such a server.
   A connection to a server is a bidirectional communication path from the
   client to the server. There may be a single client or multiple clients
   sharing the same connection.
   The Plan 9 File Protocol, 9P, is used for messages between clients and
   servers. A client transmits requests (T-messages) to a server, which
   subsequently returns replies (R-messages) to the client. The combined
   acts of transmitting (receiving) a request of a particular type, and
   receiving (transmitting) its reply is called a transaction of that
   type.
   Each message consists of a sequence of bytes. Two-, four-, and
   eight-byte fields hold unsigned integers represented in little-endian
   order (least significant byte first). Data items of larger or variable
   lengths are represented by a two-byte field specifying a count, n,
   followed by n bytes of data. Text strings are represented this way,
   with the text itself stored as a UTF-8 encoded sequence of Unicode
   characters (see utf(7)). Text strings in 9P messages are not
   NUL-terminated: n counts the bytes of UTF-8 data, which include no
   final zero byte. The NUL character is illegal in all text strings in
   9P, and is therefore excluded from file names, user names, and so on.
   Each 9P message begins with a four-byte size field specifying the
   length in bytes of the complete message including the four bytes of the
   size field itself. The next byte is the message type, one of the
   constants in the enumeration in the include file <fcall.h>. The next
   two bytes are an identifying tag, described below. The remaining bytes
   are parameters of different sizes. In the message descriptions, the
   number of bytes in a field is given in brackets after the field name.
   The notation parameter[n] where n is not a constant represents a
   variable-length parameter: n[2] followed by n bytes of data forming the
   parameter. The notation string[s] (using a literal s character) is
   shorthand for s[2] followed by s bytes of UTF-8 text. (Systems may
   choose to reduce the set of legal characters to reduce syntactic
   problems, for example to remove slashes from name components, but the
   protocol has no such restriction. Plan 9 names may contain any
   printable character (that is, any character outside hexadecimal 00-1F
   and 80-9F) except slash.) Messages are transported in byte form to
   allow for machine independence; fcall(3) describes routines that
   convert to and from this form into a machine-dependent C structure.

   MESSAGES
   size[4] Tversion tag[2] msize[4] version[s]
   size[4] Rversion tag[2] msize[4] version[s]
   size[4] Tauth tag[2] afid[4] uname[s] aname[s]
   size[4] Rauth tag[2] aqid[13]
   size[4] Rerror tag[2] ename[s]
   size[4] Tflush tag[2] oldtag[2]
   size[4] Rflush tag[2]
   size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s]
   size[4] Rattach tag[2] qid[13]
   size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s])
   size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13])
   size[4] Topen tag[2] fid[4] mode[1]
   size[4] Ropen tag[2] qid[13] iounit[4]
   size[4] Topenfd tag[2] fid[4] mode[1]
   size[4] Ropenfd tag[2] qid[13] iounit[4] unixfd[4]
   size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1]
   size[4] Rcreate tag[2] qid[13] iounit[4]
   size[4] Tread tag[2] fid[4] offset[8] count[4]
   size[4] Rread tag[2] count[4] data[count]
   size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count]
   size[4] Rwrite tag[2] count[4]
   size[4] Tclunk tag[2] fid[4]
   size[4] Rclunk tag[2]
   size[4] Tremove tag[2] fid[4]
   size[4] Rremove tag[2]
   size[4] Tstat tag[2] fid[4]
   size[4] Rstat tag[2] stat[n]
   size[4] Twstat tag[2] fid[4] stat[n]
   size[4] Rwstat tag[2]
   Each T-message has a tag field, chosen and used by the client to
   identify the message. The reply to the message will have the same tag.
   Clients must arrange that no two outstanding messages on the same
   connection have the same tag. An exception is the tag NOTAG, defined as
   (ushort)~0 in <fcall.h>: the client can use it, when establishing a
   connection, to override tag matching in version messages.
   The type of an R-message will either be one greater than the type of
   the corresponding T-message or Rerror, indicating that the request
   failed. In the latter case, the ename field contains a string
   describing the reason for failure.
   The version message identifies the version of the protocol and
   indicates the maximum message size the system is prepared to handle. It
   also initializes the connection and aborts all outstanding I/O on the
   connection. The set of messages between version requests is called a
   session.
   Most T-messages contain a fid, a 32-bit unsigned integer that the
   client uses to identify a “current file” on the server. Fids are
   somewhat like file descriptors in a user process, but they are not
   restricted to files open for I/O: directories being examined, files
   being accessed by stat(3) calls, and so on -- all files being
   manipulated by the operating system -- are identified by fids. Fids are
   chosen by the client. All requests on a connection share the same fid
   space; when several clients share a connection, the agent managing the
   sharing must arrange that no two clients choose the same fid.
   The fid supplied in an attach message will be taken by the server to
   refer to the root of the served file tree. The attach identifies the
   user to the server and may specify a particular file tree served by the
   server (for those that supply more than one).
   Permission to attach to the service is proven by providing a special
   fid, called afid, in the attach message. This afid is established by
   exchanging auth messages and subsequently manipulated using read and
   write messages to exchange authentication information not defined
   explicitly by 9P. Once the authentication protocol is complete, the
   afid is presented in the attach to permit the user to access the
   service.
   A walk message causes the server to change the current file associated
   with a fid to be a file in the directory that is the old current file,
   or one of its subdirectories. Walk returns a new fid that refers to the
   resulting file. Usually, a client maintains a fid for the root, and
   navigates by walks from the root fid.
   A client can send multiple T-messages without waiting for the
   corresponding R-messages, but all outstanding T-messages must specify
   different tags. The server may delay the response to a request and
   respond to later ones; this is sometimes necessary, for example when
   the client reads from a file that the server synthesizes from external
   events such as keyboard characters.
   Replies (R-messages) to auth, attach, walk, open, and create requests
   convey a qid field back to the client. The qid represents the server’s
   unique identification for the file being accessed: two files on the
   same server hierarchy are the same if and only if their qids are the
   same. (The client may have multiple fids pointing to a single file on a
   server and hence having a single qid.) The thirteen-byte qid fields
   hold a one-byte type, specifying whether the file is a directory,
   append-only file, etc., and two unsigned integers: first the four-byte
   qid version, then the eight-byte qid path. The path is an integer
   unique among all files in the hierarchy. If a file is deleted and
   recreated with the same name in the same directory, the old and new
   path components of the qids should be different. The version is a
   version number for a file; typically, it is incremented every time the
   file is modified.
   An existing file can be opened, or a new file may be created in the
   current (directory) file. I/O of a given number of bytes at a given
   offset on an open file is done by read and write.
   A client should clunk any fid that is no longer needed. The remove
   transaction deletes files.
   Openfd is an extension used by Unix utilities to allow traditional Unix
   programs to have their input or output attached to fids on 9P servers.
   See openfd(9p) and 9pclient(3) for details.
   The stat transaction retrieves information about the file. The stat
   field in the reply includes the file’s name, access permissions (read,
   write and execute for owner, group and public), access and modification
   times, and owner and group identifications (see stat(3)). The owner and
   group identifications are textual names. The wstat transaction allows
   some of a file’s properties to be changed.
   A request can be aborted with a flush request. When a server receives a
   Tflush, it should not reply to the message with tag oldtag (unless it
   has already replied), and it should immediately send an Rflush. The
   client must wait until it gets the Rflush (even if the reply to the
   original message arrives in the interim), at which point oldtag may be
   reused.
   Because the message size is negotiable and some elements of the
   protocol are variable length, it is possible (although unlikely) to
   have a situation where a valid message is too large to fit within the
   negotiated size. For example, a very long file name may cause a Rstat
   of the file or Rread of its directory entry to be too large to send. In
   most such cases, the server should generate an error rather than modify
   the data to fit, such as by truncating the file name. The exception is
   that a long error string in an Rerror message should be truncated if
   necessary, since the string is only advisory and in some sense
   arbitrary.
   Most programs do not see the 9P protocol directly; on Plan 9, calls to
   library routines that access files are translated by the kernel’s mount
   driver into 9P messages.

   Unix
   On Unix, 9P services are posted as Unix domain sockets in a well-known
   directory (see getns(3) and 9pserve(4)). Clients connect to these
   servers using a 9P client library (see 9pclient(3)).

   DIRECTORIES
   Directories are created by create with DMDIR set in the permissions
   argument (see stat(9P)). The members of a directory can be found with
   read(9P). All directories must support walks to the directory ..
   (dot-dot) meaning parent directory, although by convention directories
   contain no explicit entry for .. or . (dot). The parent of the root
   directory of a server’s tree is itself.

   ACCESS PERMISSIONS
   This section describes the access permission conventions implemented by
   most Plan 9 file servers. These conventions are not enforced by the
   protocol and may differ between servers, especially servers built on
   top of foreign operating systems.
   Each file server maintains a set of user and group names. Each user can
   be a member of any number of groups. Each group has a group leader who
   has special privileges (see stat(9P) and Plan 9’s users(6)). Every file
   request has an implicit user id (copied from the original attach) and
   an implicit set of groups (every group of which the user is a member).
   Each file has an associated owner and group id and three sets of
   permissions: those of the owner, those of the group, and those of
   “other” users. When the owner attempts to do something to a file, the
   owner, group, and other permissions are consulted, and if any of them
   grant the requested permission, the operation is allowed. For someone
   who is not the owner, but is a member of the file’s group, the group
   and other permissions are consulted. For everyone else, the other
   permissions are used. Each set of permissions says whether reading is
   allowed, whether writing is allowed, and whether executing is allowed.
   A walk in a directory is regarded as executing the directory, not
   reading it. Permissions are kept in the low-order bits of the file
   mode: owner read/write/execute permission represented as 1 in bits 8,
   7, and 6 respectively (using 0 to number the low order). The group
   permissions are in bits 5, 4, and 3, and the other permissions are in
   bits 2, 1, and 0.
   The file mode contains some additional attributes besides the
   permissions. If bit 31 (DMDIR) is set, the file is a directory; if bit
   30 (DMAPPEND) is set, the file is append-only (offset is ignored in
   writes); if bit 29 (DMEXCL) is set, the file is exclusive-use (only one
   client may have it open at a time); if bit 27 (DMAUTH) is set, the file
   is an authentication file established by auth messages; if bit 26
   (DMTMP) is set, the contents of the file (or directory) are not
   included in nightly archives. (Bit 28 is skipped for historical
   reasons.) These bits are reproduced, from the top bit down, in the type
   byte of the Qid: QTDIR, QTAPPEND, QTEXCL, (skipping one bit) QTAUTH,
   and QTTMP. The name QTFILE, defined to be zero, identifies the value of
   the type for a plain file.

                                Space Glenda
