styxserver man page on Inferno

Man page or keyword search:  
man Server   579 pages
apropos Keyword Search (all sections)
Output format
Inferno logo
[printable version]

STYXSERVER(10.2)					      STYXSERVER(10.2)

NAME
       Styxserver - C Styx server library

SYNOPSIS
       #include <lib9.h>
       #include <styx.h>
       #include <styxserver.h>
       #define Qroot  0

       #define MSGMAX ((((8192+128)*2)+3) & ~3)

       extern char Enomem[];	/* out of memory */
       extern char Eperm[];	     /* permission denied */
       extern char Enodev[];	/* no free devices */
       extern char Ehungup[];	/* i/o on hungup channel */
       extern char Eexist[];	     /* file exists */
       extern char Enonexist[]; /* file does not exist */
       extern char Ebadcmd[];	/* bad command */
       extern char Ebadarg[];	/* bad arguments */

       typedef uvlong Path;
       typedef struct Styxserver     Styxserver;
       typedef struct Styxops Styxops;
       typedef struct Styxfile Styxfile;
       typedef struct Client Client;

       struct Styxserver
       {
	    Styxops *ops;
	    Path qidgen;
	    int connfd;
	    Client *clients;
	    Client *curc;
	    Styxfile *root;
	    Styxfile **ftab;
	    void *priv;	   /* private */
       };

       struct Client
       {
	    Styxserver *server;
	    Client *next;
	    int	      fd;
	    char msg[MSGMAX];
	    uint      nread;	     /* valid bytes in msg (including nc)*/
	    int	      nc;	/* bytes consumed from front of msg by convM2S */
	    char data[MSGMAX];	/* Tread/Rread data */
	    int	      state;
	    Fid	      *fids;
	    char      *uname;	/* uid */
	    char      *aname;	/* attach name */
	    void      *u;
       };

       struct Styxops
       {
	    char *(*newclient)(Client *c);
	    char *(*freeclient)(Client *c);

	    char *(*attach)(char *uname, char *aname);
	    char *(*walk)(Qid *qid, char *name);
	    char *(*open)(Qid *qid, int mode);
	    char *(*create)(Qid *qid, char *name, int perm, int mode);
	    char *(*read)(Qid qid, char *buf, ulong *n, vlong offset);
	    char *(*write)(Qid qid, char *buf, ulong *n, vlong offset);
	    char *(*close)(Qid qid, int mode);
	    char *(*remove)(Qid qid);
	    char *(*stat)(Qid qid, Dir *d);
	    char *(*wstat)(Qid qid, Dir *d);
       };

       struct Styxfile
       {
	    Dir	 d;
	    Styxfile *parent;
	    Styxfile *child;
	    Styxfile *sibling;
	    Styxfile *next;
	    int ref;
	    int open;
	    void *u;
       };

       void styxsetowner(char *user);
       char *styxinit(Styxserver *server, Styxops *ops, char *port, int perm, int needfile);
       char *styxwait(Styxserver *server);
       char *styxprocess(Styxserver *server);
       char *styxend(Styxserver *server);

       Client *styxclient(Styxserver *server);

       Styxfile *styxaddfile(Styxserver *server, Path pqid, Path qid, char *name,
				int mode, char *owner);
       Styxfile *styxadddir(Styxserver *server, Path pqid, Path qid, char *name,
				int mode, char *owner);
       int styxrmfile(Styxserver *server, Path qid);
       Styxfile *styxfindfile(Styxserver *server, Path qid);

       int  styxperm(Styxfile *file, char *uid, int mode);
       long styxreadstr(ulong off, char *buf, ulong n, char *str);
       Qid styxqid(int path, int isdir);
       void *styxmalloc(int bytes);
       void styxfree(void *p);
       void styxdebug(void);

DESCRIPTION
       The C Styx server library provides a small suite of functions to enable
       the production of a file server based on the Inferno Styx protocol. The
       following elements define the primary routines in the interface:

       styxinit(server, ops, port, perm, needfile)
	      Initializes the interface given a pointer to a Styxserver struc‐
	      ture server , a callback table of operations ops , a port number
	      port to announce the file service on and the permissions perm on
	      the root directory. The default permission  is  0555  (read  and
	      execute  for  user, group and others) if the latter is specified
	      as -1. If the last argument needfile is set to  true,  the  styx
	      library  will  check  that  each path number it deals with has a
	      corresponding file associated with it and, if it hasn't, it will
	      issue  a "file does not exist" message automatically. In case of
	      an error, the  error  message  is	 returned,  otherwise  nil  is
	      returned	to  indicate  success.	By default, files are owned by
	      inferno; styxsetowner can be called before styxinit to make user
	      the default owner of files.

       styxwait(server)
	      Waits for communication from a client. Return value as above.

       styxprocess(server)
	      Processes the client message after a successful call to styxwait
	      .	 This may result in calls to the functions in the  table  pro‐
	      vided to styxinit .  Return value as above.

       styxend(server)
	      End all file service. Return value as above.

       styxclient(server)
	      Returns the client whose request is currently being processed.

       The next set of functions allow the creation of a file system structure
       based upon the Styxfile structure. This	contains  a  Dir  structure  d
       describing  the properties of the file (defined in lib9.h) and pointers
       to other files in the file tree: parent , child , sibling  and  next  .
       The  ref	 field	counts	current references to the file. The open field
       counts the current number of opens on the file.	Finally	 the  u	 field
       allows  further	fields	to be tagged onto each file. It is not used by
       the Styx server library.

       Each file must have a unique path number in the server. The root of the
       tree Qroot always has path number zero. It's corresponding file is cre‐
       ated during library initialization and placed in the root field of  the
       server  structure.  All other files must be supplied with a path number
       to identify them. Files are created/deleted as follows:

       styxaddfile(server, ppath, path, name, mode, owner)
	      Add a new file (ie non-directory) with the  given	 path  path  ,
	      name  name  , mode mode and owner owner to the directory identi‐
	      fied by the path ppath .	If path is -1 the library will	gener‐
	      ate  a  unique  path  number instead.  Returns nil if the parent
	      file with path ppath does not exist, if  the  parent  is	not  a
	      directory, if the path number path already is assigned to a file
	      or if the parent already contains a file of name name .

       styxadddir(server, ppath, path, name, mode, owner)
	      Add a new directory with the given path path , name name ,  mode
	      mode  and	 owner	owner  to the directory identified by the path
	      ppath .  Returns nil in the same circumstances as styxaddfile .

       styxrmfile(server, path)
	      Remove the file or directory with path path from the file server
	      tree.  If	 the file is a directory, it's contents will be recur‐
	      sively removed. If the file does not exist, -1 is returned, oth‐
	      erwise 0 is returned for success.

       styxfindfile(server, path)
	      Return the file structure corresponding to the file or directory
	      with path path .	Nil is returned if the file does not exist.

       If the file system is created in this way the Styx library  will	 check
       read/write/execute  permissions,	 check	for  invalid uses of files and
       check that path numbers exist in the file system (see styxinit for  the
       latter).	 If  it's  not feasible to do this (for instance if there is a
       more suitable way of describing the file system in question), then  all
       file checking must be done as part of the callback functions below.

       The  library  provides  a callback mechanism so that the implementer of
       the file server can take corresponding action when a particular request
       is  made of the server. All of these functions may return an error mes‐
       sage which will be communicated back  to	 the  client.  Otherwise  they
       should  return  nil  to	indicate  the success of the operation. Any of
       these functions may be nil in which case the library performs a default
       operation  which	 will  be  described below. These routines use the Qid
       structure defined in lib9.h to describe files. This structure  contains
       the  path number( path ), a version number( vers ) typically zero and a
       type( type ) which indicates whether the file is a  directory,  append-
       only etc.

       newclient(c)
	      Called  whenever a new client connects to the server. The Client
	      structure c contains mainly private data	but  the  uname	 field
	      contains	a  user	 name  and  the	 aname field an attach name if
	      required. The u field may be used to tag further data onto  each
	      client. It is not used by the Styx server library.

       freeclient(c)
	      Called whenever a client disconnects from the server.

       attach(uname, aname)
	      Called  when  a  client  user  first mounts the file server. The
	      uname is the user id and aname is typically  the	file  tree  to
	      access  if  the server provides a choice.	 The default action is
	      to allow the attach to the root of the file system.

       walk(qid, name)
	      In a directory represented by qid , find	a  file	 member	 whose
	      name  is	that  given  and  place it's Qid in qid .  The default
	      action is to perform the walk using any directory structure pro‐
	      vided.

       open(qid, mode)
	      Open  the	 file  represented by qid with mode mode .  The latter
	      may be one of OREAD, OWRITE, ORDWR etc (see lib9.h). If the  Qid
	      of  the  newly  opened file is different from that given (a file
	      server may understand the opening of a file called "new" say  to
	      signify  the  creation  of  a  directory	whose  Qid is returned
	      instead) place it's Qid in qid .	The default action is to nomi‐
	      nally allow the open.

       create(qid, name, perm, mode)
	      Create  a	 file  in  the directory given by qid with name name ,
	      permissions perm and mode mode .	Place the  Qid	of  the	 newly
	      created  file in qid .  The default action is to issue a permis‐
	      sion denied message.

       read(qid, buf, n, offset)
	      Read n bytes of the file represented by qid at offset offset and
	      place the result in buf.
	       Place in n the actual number of bytes read.  The default action
	      is to read directories but to issue permission denied  on	 ordi‐
	      nary files.

       write(qid, buf, n, offset)
	      Write  n	bytes  to the file represented by qid at offset offset
	      from the buffer buf.
	       Place in n the actual number of	bytes  written.	  The  default
	      action is to issue permission denied.

       close(qid, mode)
	      Close  the file represented by qid .  The mode it was originally
	      opened with is given by mode .  The default action is  to	 allow
	      the close.

       remove(qid)
	      Remove  the  file represented by qid .  The default action is to
	      issue a permission denied message.

       stat(qid, d)
	      Place the information for the file represented by qid in the Dir
	      structure(see  lib9.h)  d	 .  The default action is to allow the
	      stat using any information in the file tree.

       wstat(qid, d)
	      Update the information for the file represented by qid according
	      to the Dir structure d .	The default action is to disallow this
	      with a permission denied message.

       A small number of utility functions are provided:

       styxperm(file, uid, mode)
	      Does the file/directory file allow the user uid  the  permission
	      given  by	 mode  .   For	example use OREAD for read permission,
	      OWRITE for write permission and ORDWR for both.

       styxreadstr(off, buf, n, str)
	      Read n bytes of data from the string str at offset off and place
	      the result in buf .  Returns the actual number of bytes read.

       styxqid(path, isdir)
	      Returns  a typical Qid structure with the given path number path
	      and whether the Qid is for a directory isdir .

       styxmalloc(n)
	      Allocate n bytes of memory and return it.

       styxfree(p)
	      Free the memory pointed to by p .

       styxdebug()
	      Print out some of the actions of the server.

EXAMPLE
       A very small file server example	 is  illustrated.  First  the  include
       files and globals.

	    #include <lib9.h>
	    #include "styxserver.h"

	    int nq;
	    Styxserver *server;

       The main processing loop:

	    main(int argc, char **argv)
	    {
		 Styxserver s;

		 server = &s;
		 styxinit(&s, &ops, "6701", 100, 0555, 0);
		 myinit(&s);
		 for(;;) {
		      styxwait(&s);
		      styxprocess(&s);
		 }
		 return 0;
	    }

       Here  the  port number is 6701 and the root file permissions are 0555 -
       no write permission for anyone which implies that files and directories
       cannot be created in the root directory.

       The creation of the directory tree:

	    myinit(Styxserver *s)
	    {
		 styxaddfile(s, Qroot, 1, "fred", 0664, "inferno");
		 styxaddfile(s, Qroot, 2, "joe", 0664, "inferno");
		 styxadddir(s, Qroot, 3, "adir", 0775, "inferno");
		 styxaddfile(s, 3, 4, "bill", 0664, "inferno");
		 styxadddir(s, Qroot, 5, "new", 0775, "inferno");
		 styxadddir(s, 5, 6, "cdir", 0775, "inferno");
		 styxaddfile(s, 6, 7, "cfile", 0664, "inferno");
		 nq = 8;
	    }

       This creates two files fred and joe and two directories adir and new at
       the top level.  adir contains a file called bill	 and  new  contains  a
       directory  called  cdir which contains a file called cfile .  Note that
       each new path number is unique.

       The callback functions:

	    Styxops ops = {
		 nil,		/* newclient */
		 nil,		/* freeclient */

		 nil,		/* attach */
		 nil,		/* walk */
		 nil,		/* open */
		 mycreate,	/* create */
		 myread,	/* read */
		 nil,		/* write */
		 nil,		/* close */
		 myremove, /* remove */
		 nil,		/* stat */
		 nil,		/* wstat */
	    };

       Here we choose the defaults most of the time.

       The supplied callback routines:

	    char *
	    mycreate(Qid *qid, char *name, int perm, int mode)
	    {
		 int isdir;
		 Styxfile *f;

		 isdir = perm&DMDIR;
		 if(isdir)
		      f = styxadddir(server, qid->path, nq++, name , perm, "inferno");
		 else
		      f = styxaddfile(server, qid->path, nq++, name, perm, "inferno");
		 if(f == nil)
		      return Eexist;
		 *qid = f->d.qid;
		 return nil;
	    }

	    char *
	    myremove(Qid qid)
	    {
		 Styxfile *f;

		 f = styxfindfile(server, qid.path);
		 if(f != nil && (f->d.qid.type&QTDIR) && f->child != nil)
		      return "directory not empty";

		 if(styxrmfile(server, qid.path) < 0)
		      return Enonexist;
		 return nil;
	    }

	    char *
	    myread(Qid qid, char *d, ulong *n, vlong offset)
	    {
		 if(qid.path != 1){
		      *n = 0;
		      return nil;
		 }
		 *n = styxreadstr(offset, d, *n, "abcdeghijklmn");
		 return nil;
	    }

       Permission checking for walk (need execute  permission  on  directory),
       open  (the  given  mode	must be compatible with the file permissions),
       create and remove (both of which need write permission on directory) is
       done  automatically whenever possible. The functions mycreate and myre‐
       move below therefore can omit these checks.

       The function mycreate simply creates a directory or  file  and  if  the
       file  cannot  be added to the directory tree it returns a 'file exists'
       error string.  It sets the  Qid	for  the  newly	 created  file	before
       returning.

       The function myremove first checks to see if the file represents a non-
       empty directory, in which case it disallows it's removal. Otherwise  it
       removes	the file if it can find it and returns a 'file does not exist'
       error string if it can't.

       The function myread considers all files to be  empty  except  for  fred
       which  notionally  contains  abcdefghijklmn  .  Note that the number of
       bytes read is returned in the argument n .

       Once this file server is running, the root can be accessed by doing for
       example

	    mount -A tcp!<address>!6701 /n/remote

       under Inferno. Here <address> is the address of the machine running the
       file server (or the loopback address  127.0.0.1	if  it's  all  on  one
       machine).  The -A option is used to prevent authentication which is not
       supported at the moment.	 Then we can do

	    cd /n/remote
	    ls
	    adir
	    fred
	    joe
	    new
	    ...

       For a more complicated file server see /tools/styxtest/styxtest.c.

       The file /tools/styxtest/mkfile shows how to compile and link the  file
       server sources.

SOURCE
       /Nt/386/include/lib9.h
       /tools/libstyx/styxserver.h
       /tools/libstyx/styxserver.c
       /tools/styxtest/styxtest.c
       /tools/styxtest/styxtest0.c

BUGS
       Currently  the  library	is  available under Windows, Linux and Solaris
       only.
       Authentication is not supported.

							      STYXSERVER(10.2)
[top]

List of man pages available for Inferno

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net