STYX(10.2)                                             STYX(10.2)

     NAME
          Fcall, convS2M, convD2M, convM2S, convM2D, fcallfmt, dirfmt,
          dirmodefmt, statcheck, sizeS2M, sizeD2M - interface to
          Inferno File protocol

     SYNOPSIS
          #include <lib9.h>
          #include <styx.h>

          uint convS2M(Fcall *f, uchar *ap, uint nap)

          uint convD2M(Dir *d, uchar *ap, uint nap)

          uint convM2S(uchar *ap, uint nap, Fcall *f)

          uint convM2D(uchar *ap, uint nap, Dir *d, char *strs)

          int dirfmt(Fmt*)

          int fcallfmt(Fmt*)

          int dirmodefmt(Fmt*)

          int statcheck(uchar *buf, uint nbuf)

          uint sizeS2M(Fcall *f)

          uint sizeD2M(Dir *d)

     DESCRIPTION
          These routines convert messages in the machine-independent
          format of the Inferno file protocol, described by intro(5),
          to and from a more convenient form, an Fcall structure:

          #define MAXWELEM 16

          typedef
          struct Fcall
          {
              uchar type;
              u32int     fid;
              ushort     tag;
              union {
                    struct {
                         u32int                  msize;/* Tversion, Rversion */
                         char  *version;         /* Tversion, Rversion */
                    };
                    struct {
                         ushort                  oldtag;/* Tflush */
                    };

     Page 1                       Plan 9             (printed 4/19/24)

     STYX(10.2)                                             STYX(10.2)

                    struct {
                         char  *ename;           /* Rerror */
                    };
                    struct {
                         Qid   qid;              /* Rattach, Ropen, Rcreate */
                         u32int                  iounit;/* Ropen, Rcreate */
                    };
                    struct {
                         Qid   aqid;             /* Rauth */
                    };
                    struct {
                         u32int                  afid;/* Tauth, Tattach */
                         char  *uname;           /* Tauth, Tattach */
                         char  *aname;           /* Tauth, Tattach */
                    };
                    struct {
                         u32int                  perm;/* Tcreate */
                         char  *name;            /* Tcreate */
                         uchar mode;             /* Tcreate, Topen */
                    };
                    struct {
                         u32int                  newfid;/* Twalk */
                         ushort                  nwname;/* Twalk */
                         char  *wname[MAXWELEM]; /* Twalk */
                    };
                    struct {
                         ushort                  nwqid;/* Rwalk */
                         Qid   wqid[MAXWELEM];   /* Rwalk */
                    };
                    struct {
                         vlong offset;           /* Tread, Twrite */
                         u32int                  count;/* Tread, Twrite, Rread */
                         char  *data;            /* Twrite, Rread */
                    };
                    struct {
                         ushort                  nstat;/* Twstat, Rstat */
                         uchar *stat;            /* Twstat, Rstat */
                    };
              };
          } Fcall;

          /* these are implemented as macros */

          uchar     GBIT8(uchar*)
          ushort    GBIT16(uchar*)
          ulong     GBIT32(uchar*)
          vlong     GBIT64(uchar*)

          void      PBIT8(uchar*, uchar)
          void      PBIT16(uchar*, ushort)
          void      PBIT32(uchar*, ulong)
          void      PBIT64(uchar*, vlong)

     Page 2                       Plan 9             (printed 4/19/24)

     STYX(10.2)                                             STYX(10.2)

          #define   BIT8SZ     1
          #define   BIT16SZ    2
          #define   BIT32SZ    4
          #define   BIT64SZ    8

          This structure is defined in <styx.h>.  See section 5 for a
          full description of 9P messages and their encoding.  For all
          message types, the type field of an Fcall holds one of
          Tversion, Rversion, Tattach, Rattach, etc. (defined in an
          enumerated type in <styx.h>).  Fid is used by most messages,
          and tag is used by all messages.  The other fields are used
          selectively by the message types given in comments.

          ConvM2S takes a 9P message at ap of length nap, and uses it
          to fill in Fcall structure f. If the passed message includ-
          ing any data for Twrite and Rread messages is formatted
          properly, the return value is the number of bytes the mes-
          sage occupied in the buffer ap, which will always be less
          than or equal to nap; otherwise it is 0.  For Twrite and
          Tread messages, data is set to a pointer into the argument
          message, not a copy.

          ConvS2M does the reverse conversion, turning f into a mes-
          sage starting at ap. The length of the resulting message is
          returned.  For Twrite and Rread messages, count bytes start-
          ing at data are copied into the message.

          The constant IOHDRSZ is a suitable amount of buffer to
          reserve for storing the 9P header; the data portion of a
          Twrite or Rread will be no more than the buffer size negoti-
          ated in the Tversion/Rversion exchange, minus IOHDRSZ.

          The routine sizeS2M returns the number of bytes required to
          store the machine-independent representation of the Fcall
          structure f, including its initial 32-bit size field.  In
          other words, it reports the number of bytes produced by a
          successful call to convS2M.

          Another structure is Dir, used by C functions in much the
          same way as the Limbo versions described in sys-stat(2).
          ConvM2D converts the machine-independent form starting at ap
          into d and returns the length of the machine-independent
          encoding.  The strings in the returned Dir structure are
          stored at successive locations starting at strs.  Usually
          strs will point to storage immediately after the Dir itself.
          It can also be a nil pointer, in which case the string
          pointers in the returned Dir are all nil; however, the
          return value still includes their length.

          ConvD2M does the reverse translation, also returning the
          length of the encoding.  If the buffer is too short, the
          return value will be BIT16SZ and the correct size will be

     Page 3                       Plan 9             (printed 4/19/24)

     STYX(10.2)                                             STYX(10.2)

          returned in the first BIT16SZ bytes.  (If the buffer is less
          than BIT16SZ, the return value is zero; therefore a correct
          test for complete packing of the message is that the return
          value is greater than BIT16SZ).  The macro GBIT16 can be
          used to extract the correct value.  The related macros with
          different sizes retrieve the corresponding-sized quantities.
          PBIT16 and its brethren place values in messages.  With the
          exception of handling short buffers in convD2M, these macros
          are not usually needed except by internal routines.

          Analogous to sizeS2M, sizeD2M returns the number of bytes
          required to store the machine-independent representation of
          the Dir structure d, including its initial 16-bit size
          field.

          The routine statcheck checks whether the nbuf bytes of buf
          contain a validly formatted machine-independent Dir entry.
          It checks that the sizes of all the elements of the the
          entry sum to exactly nbuf, which is a simple but effective
          test of validity.  Nbuf and buf should include the second
          two-byte (16-bit) length field that precedes the entry when
          formatted in a 9P message (see stat(5)); in other words,
          nbuf is 2 plus the sum of the sizes of the entry itself.
          Statcheck also verifies that the length field has the cor-
          rect value (that is, nbuf-2).  It returns 0 for a valid
          entry and -1 for an incorrectly formatted entry.

          Dirfmt, fcallfmt, and dirmodefmt are formatting routines,
          suitable for fmtinstall(10.2). They convert Dir*, Fcall*,
          and long values into string representations of the directory
          buffer, Fcall buffer, or file mode value.  Fcallfmt assumes
          that dirfmt has been installed with format letter `D' and
          dirmodefmt with format letter `M'.  They currently cannot be
          used in the kernels because they clash with the use of for-
          mat `D' for Dis instructions.

     SOURCE
          /lib9/convM2D.c
          /lib9/convM2D.c
          /lib9/convM2S.c
          /lib9/convS2M.c
          /lib9/fcallfmt.c
          /libkern/convM2D.c
          /libkern/convM2D.c
          /libkern/convM2S.c
          /libkern/convS2M.c
          /libkern/fcallfmt.c

     SEE ALSO
          intro(2), styx(2), sys-stat(2), intro(5)

     Page 4                       Plan 9             (printed 4/19/24)