support library for servers (continued)

From: Joerg Wittenberger <joerg.wittenberger_at_nospam.org>
Date: Wed Dec 28 1994 - 06:09:23 PST

To quote myself:

>For testing I converted tmpfs to use this library and wrote a server
>which only passes the received messages to another server (acts
>simillar to a simple mount, but it leaves all permission checks out).
>I don't expect it to be usefull as it is, but is a good template for
>real servers so I'll append it as a example)

But I forgot to append the "passfs.[hc]" here it is:

#ifndef _PASSFS_H
#define _PASSFS_H
/*
 * passfs.h
 * Data structures in pass filesystem
 *
 * PASSFS is a filesystem, which simply passes all requests down to a
 * underlying file system. This is not really a useful server,
 * because the same effect can be achived be a simple mount (in
 * VSTa). But it is a generic stub which is simple to extend to a
 * layered file system
 */

#include <sys/types.h>
#include <sys/fs.h>
#include <sys/perm.h>

/*
 * Structure of an open file in the filesystem
 */

/*
 * Our per-open-file data structure
 */
struct file {
  port_t port;
};

#endif /* _PASSFS_H */

-------------------------------------

/*
 * passfs.c
 * Main handling loop and startup
 */
#include <sys/namer.h>
#include "../lib/server.h"
#include "passfs.h"
#include <sys/seg.h>
#include <stdio.h>
#include <fcntl.h>
#include <std.h>
#include <syslog.h>

port_t theBasePort; /* where we are mounted on */

static char*
passmsg(struct msg *m, struct file *f)
{
  return server_passmsg(f->port,m);
}

/*
 * new_client()
 * Create new per-connect structure
 */
static char *
new_client(struct msg *m, struct file * dummy)
{
  struct file *f;
  
  /*
   * Get data structure
   */
  if ((f = malloc(sizeof(struct file))) == 0) {
    return strerror();
  }

  /*
   * Fill in fields
   */
  f->port = clone(theBasePort);

  if( f->port < 0 ) {
    free(f);
    return strerror();
  }
  /*
   * Hash under the sender's handle
   */

  server_bindclient(m->m_sender, f);

  /*
   * Return acceptance
   */
 return 0;
}

/*
 * dup_client()
 * Duplicate current file access onto new session
 *
 * This is more of a Plan9 clone operation. The intent is
 * to not share a struct file, so that when you walk it down
 * a level or seek it, you don't affect the thing you cloned
 * off from.
 *
 * This is a kernel-generated message; the m_sender is the
 * current user; m_arg specifies a handle which will be used
 * if we complete the operation with success.
 */
static char *
dup_client(struct msg *m, struct file *fold)
{
  struct file *f;

  /*
   * Get data structure
   */
  if ((f = malloc(sizeof(struct file))) == 0) {
    return strerror();
  }

  /*
   * Fill in fields
   */
  *f = *fold;
  f->port = clone(fold->port);

  if( f->port < 0 ) {
    free(f);
    return strerror();
  }

  /*
   * Hash under the sender's handle
   */
  server_bindclient( m->m_arg, f);

  /*
   * Return acceptance
   */
  m->m_arg = m->m_arg1 = m->m_buflen = m->m_nseg = 0;
  return 0;
}

/*
 * dead_client()
 * Someone has gone away. Free their info.
 */
static char *
dead_client(struct msg *m, struct file *f)
{
  struct file*old;
  msg_disconnect(f->port);
  old=server_bindclient( m->m_sender,0);
  /* old and f should be the same */
  if(old) free(old);
  return 0;
}

/*
 * usage()
 * Tell how to use the thing
 */
static void
usage(void)
{
        printf("Usage is: passfs <fsname> <basefsname>\n");
        exit(1);
}

/*
 * init_fssrv()
 * Startup of a passfs filesystem
 *
 * A PASSFS instance expects to start with a command line:
 * $ passfs <filesystem name> <basesystem>
 */
init_server(int argc, char *argv[])
{
#define BIND(a,b) server_bindfn(a,(service*)b)

  int fd;

#ifdef DEBUG
  extern int server_dbg_flag;
  server_dbg_flag=0;
#endif

  /*
   * Initialize syslog
   */
  openlog("passfs", LOG_PID, LOG_DAEMON);

  /*
   * Check arguments
   */
  if (argc != 1) {
    usage();
    return 1;
  }

  fd = open(argv[0], O_RDWR);
  if( fd < 0 ) {
    syslog(LOG_ERR, "unable to open '%s'", argv[2]);
    exit(1);
  }
  theBasePort = __fd_port(fd);

  /*
   * Allocate data structures we'll need
   */
  BIND(M_CONNECT,new_client);
  BIND(M_DISCONNECT,dead_client);
  BIND(M_DUP,dup_client);
  BIND(FS_OPEN,passmsg);
  BIND(FS_ABSREAD,passmsg);
  BIND(FS_READ,passmsg);
  BIND(FS_ABSWRITE,passmsg);
  BIND(FS_WRITE,passmsg);
  BIND(FS_SEEK,passmsg);
  BIND(FS_REMOVE,passmsg);
  BIND(FS_STAT,passmsg);
  BIND(FS_WSTAT,passmsg);

  /*
   * Start serving requests for the filesystem
   */
  syslog(LOG_INFO, "filesystem established");
  return 0;
}
Received on Wed Dec 28 09:29:05 1994

This archive was generated by hypermail 2.1.8 : Thu Sep 22 2005 - 15:12:11 PDT