PLUMB(2)                                                 PLUMB(2)

          eplumb, plumbfree, plumbopen, plumbsend, plumbsendtext,
          plumblookup, plumbpack, plumbpackattr, plumbaddattr,
          plumbdelattr, plumbrecv, plumbunpack, plumbunpackpartial,
          plumbunpackattr, Plumbmsg  - plumb messages

          #include <u.h>
          #include <libc.h>
          #include <plumb.h>

          int        plumbopen(char *port, int omode)

          int        plumbsend(int fd, Plumbmsg *m)

          int        plumbsendtext(int fd, char *src, char *dst, char
          *wdir, char *data)

          void       plumbfree(Plumbmsg *m)

          Plumbmsg*  plumbrecv(int fd)

          char*      plumbpack(Plumbmsg *m, int *np)

          Plumbmsg*  plumbunpack(char *buf, int n)

          Plumbmsg*  plumbunpackpartial(char *buf, int n, int *morep)

          char*      plumbpackattr(Plumbattr *a)

          Plumbattr* plumbunpackattr(char *a)

          char*      plumblookup(Plumbattr *a, char *name)

          Plumbattr* plumbaddattr(Plumbattr *a, Plumbattr *new)

          Plumbattr* plumbdelattr(Plumbattr *a, char *name)

          int        eplumb(int key, char *port)

          These routines manipulate plumb(6) messages, transmitting
          them, receiving them, and converting them between text and
          these data structures:

               struct Plumbmsg
                     char      *src;
                     char      *dst;

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

     PLUMB(2)                                                 PLUMB(2)

                     char      *wdir;
                     char      *type;
                     Plumbattr *attr;
                     int       ndata;
                     char      *data;
               } Plumbmsg;

               struct Plumbattr
                     char      *name;
                     char      *value;
                     Plumbattr *next;
               } Plumbattr;

          Plumbopen opens the named plumb port, using open(2) mode
          omode. If port begins with a slash, it is taken as a literal
          file name; otherwise plumbopen searches for the location of
          the plumber(4) service and opens the port there.

          For programs using the event(2) interface, eplumb registers,
          using the given key, receipt of messages from the named

          Plumbsend formats and writes message m to the file descrip-
          tor fd, which will usually be the result of
          plumbopen("send", OWRITE).  Plumbsendtext is a simplified
          version for text-only messages; it assumes type is text,
          sets attr to nil, and sets ndata to strlen(data).

          Plumbfree frees all the data associated with the message m,
          all the components of which must therefore have been allo-
          cated with malloc(2).

          Plumbrecv returns the next message available on the file
          descriptor fd, or nil for error.

          Plumbpack encodes message m as a character string in the
          format of plumb(6), setting *np to the length in bytes of
          the string.  Plumbunpack does the inverse, translating the n
          bytes of buf into a Plumbmsg.

          Plumbunpackpartial enables unpacking of messages that arrive
          in pieces.  The first call to plumbunpackpartial for a given
          message must be sufficient to unpack the header; subsequent
          calls permit unpacking messages with long data sections.
          For each call, buf points to the beginning of the complete
          message received so far, and n reports the total number of
          bytes received for that message.  If the message is com-
          plete, the return value will be as in plumbunpack. If not,
          and morep is not null, the return value will be nil and
          *morep will be set to the number of bytes remaining to be

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

     PLUMB(2)                                                 PLUMB(2)

          read for this message to be complete (recall that the byte
          count is in the header).  Those bytes should be read by the
          caller, placed at location buf+n, and the message unpacked
          again.  If an error is encountered, the return value will be
          nil and *morep will be zero.

          Plumbpackattr converts the list a of Plumbattr structures
          into a null-terminated string.  If an attribute value con-
          tains white space, quote characters, or equal signs, the
          value will be quoted appropriately.  A newline character
          will terminate processing.  Plumbunpackattr converts the
          null-terminated string a back into a list of Plumbattr

          Plumblookup searches the Plumbattr list a for an attribute
          with the given name and returns the associated value.  The
          returned string is the original value, not a copy.  If the
          attribute has no value, the returned value will be the empty
          string; if the attribute does not occur in the list at all,
          the value will be nil.

          Plumbaddattr appends the new Plumbattr (which may be a list)
          to the attribute list a and returns the new list.
          Plumbdelattr searches the list a for the first attribute
          with name name and deletes it from the list, returning the
          resulting list.  Plumbdelattr is a no-op if no such
          attribute exists.


          plumb(1), event(2), plumber(4), plumb(6)

          When appropriate, including when a plumbsend fails, these
          routine set errstr.

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