Пример #1
0
struct node *procfs_make_node (const struct procfs_node_ops *ops, void *hook)
{
  struct netnode *nn;
  struct node *np;
 
  nn = malloc (sizeof *nn);
  if (! nn)
    goto fail;

  memset (nn, 0, sizeof *nn);
  nn->ops = ops;
  nn->hook = hook;

  np = netfs_make_node (nn);
  if (! np)
    goto fail;

  np->nn = nn;
  memset (&np->nn_stat, 0, sizeof np->nn_stat);
  np->nn_translated = 0;

  if (np->nn->ops->lookup)
    np->nn_stat.st_mode = S_IFDIR | 0555;
  else
    np->nn_stat.st_mode = S_IFREG | 0444;

  return np;

fail:
  if (ops->cleanup)
    ops->cleanup (hook);

  free (nn);
  return NULL;
}
Пример #2
0
/*Derives a new node from `lnode` and adds a reference to `lnode`*/
error_t node_create (lnode_t * lnode, node_t ** node)
{
  error_t err = 0;

  /*Create a new netnode */
  netnode_t *netnode_new = malloc (sizeof (netnode_t));

  /*Reset the memory allocated for the new netnode (just in case :-) ) */
  memset (netnode_new, 0, sizeof (netnode_t));

  /*If the memory could not be allocated */
  if (netnode_new == NULL)
    err = ENOMEM;
  else
    {
      /*create a new node from the netnode */
      node_t *node_new = netfs_make_node (netnode_new);

      /*If the creation failed */
      if (node_new == NULL)
	{
	  /*set the error code */
	  err = ENOMEM;

	  /*destroy the netnode created above */
	  free (netnode_new);

	  /*stop */
	  return err;
	}

      node_new->nn->type = NODE_TYPE_NORMAL;

      /*link the lnode to the new node */
      lnode->node = node_new;

      /*setup the references in the newly created node */
      node_new->nn->lnode = lnode;
      lnode_ref_add (lnode);

      /*setup the information in the netnode */
      node_new->nn->flags = 0;
      node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;

      /*initialize the data fields dealing with positioning this node
	in the dynamic translator stack */
      node_new->nn->dyntrans = NULL;
      node_new->nn->below = NULL;

      /*store the result of creation in the second parameter */
      *node = node_new;
    }

  /*Return the result of operations */
  return err;
}				/*node_create */
Пример #3
0
/*Creates a proxy (or a shadow) node for the supplied port*/
error_t node_create_from_port (mach_port_t port, node_t ** node)
{
  error_t err = 0;

  /*Create a new netnode */
  netnode_t * netnode_new = malloc (sizeof (netnode_t));

  /*Reset the memory allocated for the new netnode (just in case :-) ) */
  memset (netnode_new, 0, sizeof (netnode_t));

  /*If the memory could not be allocated */
  if (netnode_new == NULL)
    err = ENOMEM;
  else
    {
      /*create a new node from the netnode */
      node_t * node_new = netfs_make_node (netnode_new);

      /*If the creation failed */
      if (node_new == NULL)
	{
	  /*set the error code */
	  err = ENOMEM;

	  /*destroy the netnode created above */
	  free (netnode_new);

	  /*stop */
	  return err;
	}

      /*The caller may want to change this to NODE_TYPE_SHADOW if it's
	the case. */
      node_new->nn->type = NODE_TYPE_PROXY;

      /*this node is ``orphan'' -- it is not associated to any lnode
	and has some service functions only */
      node_new->nn->lnode = NULL;

      /*setup the information in the netnode */
      node_new->nn->flags = 0;
      node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;
      node_new->nn->port = port;

      /*initialize the data fields dealing with positioning this node
	in the dynamic translator stack */
      node_new->nn->dyntrans = NULL;
      node_new->nn->below = NULL;

      /*store the result of creation in the second parameter */
      *node = node_new;
    }

  /*Return the result of operations */
  return err;
}				/*node_create_from_port */
Пример #4
0
/*Derives a new proxy from `lnode`*/
error_t node_create_proxy (lnode_t * lnode, node_t ** node)
{
  error_t err = 0;

  /*Create a new netnode */
  netnode_t *netnode_new = malloc (sizeof (netnode_t));

  /*Reset the memory allocated for the new netnode. We do this here
     since lnode_add_proxy will try to reference the `lnode` in this
     netnode and will do bad writes to memory. */
  memset (netnode_new, 0, sizeof (netnode_t));

  /*If the memory could not be allocated */
  if (netnode_new == NULL)
    err = ENOMEM;
  else
    {
      /*create a new node from the netnode */
      node_t *node_new = netfs_make_node (netnode_new);

      /*If the creation failed */
      if (node_new == NULL)
	{
	  /*set the error code */
	  err = ENOMEM;

	  /*destroy the netnode created above */
	  free (netnode_new);

	  /*stop */
	  return err;
	}

      node_new->nn->type = NODE_TYPE_PROXY;

      /*add this new node to the list of proxies of `lnode` */
      lnode_add_proxy (lnode, node_new);

      /*setup the information in the netnode */
      node_new->nn->flags = 0;
      node_new->nn->ncache_next = node_new->nn->ncache_prev = NULL;

      /*initialize the data fields dealing with positioning this node
	in the dynamic translator stack */
      node_new->nn->dyntrans = NULL;
      node_new->nn->below = NULL;

      /*store the result of creation in the second parameter */
      *node = node_new;
    }

  /*Return the result of operations */
  return err;
}				/*node_create_proxy */
Пример #5
0
/* Make a new virtual node.  Always consumes the ports.  */
error_t
new_node (struct lnode *ln, struct node **np)
{
  error_t err = 0;
  struct netnode *nn = calloc (1, sizeof *nn);
  struct node *node;

  if (nn == 0)
    return ENOMEM;
  node = netfs_make_node (nn);
  if (node == 0)
    {
      free (nn);
      *np = NULL;
      return ENOMEM;
    }
  if (ln)
    ln->n = node;
  nn->ln = ln;
  *np = node;
  return err;
}
Пример #6
0
/* cvsfs_make_node
 *
 * create a struct node* for the specified netnode 'nn'.
 */
struct node *
cvsfs_make_node(struct netnode *nn)
{
    struct node *node;

    rwlock_writer_lock(&nn->lock);

    if(nn->node)
    {
        /* there already is a node structure, just return another reference
         * to this one, instead of wasting memory for yet another one
         */
        mutex_lock(&nn->node->lock);
        netfs_nref(nn->node);
        mutex_unlock(&nn->node->lock);

        rwlock_writer_unlock(&nn->lock);
        return nn->node;
    }

    if(! (node = netfs_make_node(nn)))
    {
        rwlock_writer_unlock(&nn->lock);
        return NULL;
    }

    /* put timestamp on file */
    fshelp_touch(&node->nn_stat,
                 TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME, cvsfs_maptime);

    /* initialize stats of new node ... */
    node->nn_stat.st_fstype = FSTYPE_MISC;
    node->nn_stat.st_fsid = stat_template.fsid;
    node->nn_stat.st_ino = nn->fileno;
    node->nn_stat.st_mode = stat_template.mode;
    node->nn_stat.st_nlink = 1;
    node->nn_stat.st_uid = stat_template.uid;
    node->nn_stat.st_gid = stat_template.gid;
    node->nn_stat.st_size = 0;
    node->nn_stat.st_blksize = 4096; /* is there a better default?? */
    node->nn_stat.st_blocks = 0;
    node->nn_stat.st_author = stat_template.author;

    if(! nn->revision)
    {
        /* we're creating a node for a directory, mark as such! */
        node->nn_stat.st_mode |= S_IFDIR;

        /* since we got a directory we need to supply "executable"
         * permissions, so our user is enabled to make use of this dir
         */
        if(node->nn_stat.st_mode & S_IRUSR)
            node->nn_stat.st_mode |= S_IXUSR;

        if(node->nn_stat.st_mode & S_IRGRP)
            node->nn_stat.st_mode |= S_IXGRP;

        if(node->nn_stat.st_mode & S_IROTH)
            node->nn_stat.st_mode |= S_IXOTH;
    }
    else
    {
        if(nn->revision->contents
                && ! config.nostats)
        {
            node->nn_stat.st_mode = nn->revision->perm;
            node->nn_stat.st_size = nn->revision->length;
            node->nn_stat.st_blocks = (node->nn_stat.st_size >> 9) + 1;

            node->nn_stat.st_atime =
                node->nn_stat.st_mtime =
                    node->nn_stat.st_ctime = nn->revision->time;

            node->nn_stat.st_atime_usec =
                node->nn_stat.st_mtime_usec =
                    node->nn_stat.st_ctime_usec = 0;
        }

        /* well, we're creating a new node for a file ... */
        node->nn_stat.st_mode |= S_IFREG;

        /* for now simply drop all execute permissions, this needs to be fixed,
         * since CVS support executables, e.g. shell scripts, that we need to
         * support .... FIXME
         */
        node->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
    }
Пример #7
0
	default:
	  return ARGP_ERR_UNKNOWN;
	}
      return 0;
    }
  struct argp argp = { options, parse_opt, args_doc, doc };

  /* Parse our command line arguments.  */
  argp_parse (&argp, argc, argv, 0, 0, 0);

  task_get_bootstrap_port (mach_task_self (), &bootstrap);
  netfs_init ();

  /* Create the root node (some attributes initialized below).  */
  netfs_root_node = netfs_make_node (&root_nn);
  if (! netfs_root_node)
    error (5, ENOMEM, "Cannot create root node");

  err = maptime_map (0, 0, &usermux_maptime);
  if (err)
    error (6, err, "Cannot map time");

  /* Handshake with the party trying to start the translator.  */
  mux.underlying = netfs_startup (bootstrap, 0);

  /* We inherit various attributes from the node underlying this translator. */
  err = io_stat (mux.underlying, &ul_stat);
  if (err)
    error (7, err, "Cannot stat underlying node");