Пример #1
0
/* This should attempt a utimes call for the user specified by CRED on node
   NODE, to change the atime to ATIME and the mtime to MTIME. */
error_t
netfs_attempt_utimes (struct iouser *cred, struct node *node,
		      struct timespec *atime, struct timespec *mtime)
{
  error_t err = procfs_refresh_node (node);
  int flags = TOUCH_CTIME;

  if (! err)
    err = fshelp_isowner (&node->nn_stat, cred);

  if (! err)
    {
      if (atime)
	node->nn_stat.st_atim = *atime;
      else
	flags |= TOUCH_ATIME;

      if (mtime)
	node->nn_stat.st_mtim = *mtime;
      else
	flags |= TOUCH_MTIME;

      fshelp_touch (&node->nn_stat, flags, procfs_maptime);
    }

  return err;
}
Пример #2
0
/* This should attempt a chmod call for the user specified by CRED on node
   NODE, to change the mode to MODE.  Unlike the normal Unix and Hurd meaning
   of chmod, this function is also used to attempt to change files into other
   types.  If such a transition is attempted which is impossible, then return
   EOPNOTSUPP.  */
error_t netfs_attempt_chmod (struct iouser *cred, struct node *node,
			     mode_t mode)
{
  error_t err = 0;
  debug("");
  if (node->nn->ln == NULL)
    return EOPNOTSUPP;

  mode &= ~S_ITRANS;
  err = fshelp_isowner (&node->nn->ln->st, cred);
  if (err)
    return err;
  mode |= node->nn->ln->st.st_mode & S_IFMT;
  node->nn->ln->st.st_mode = mode;
  fshelp_touch (&node->nn_stat, TOUCH_CTIME, multiplexer_maptime);
  return err;
}
Пример #3
0
/* Lookup NAME in DIR for USER; set *NODE to the found name upon return.  If
   the name was not found, then return ENOENT.  On any error, clear *NODE.
   (*NODE, if found, should be locked, this call should unlock DIR no matter
   what.) */
error_t
netfs_attempt_lookup (struct iouser *user, struct node *dir,
		      char *name, struct node **node)
{
  error_t err;

  if (dir->nn->name)
    err = ENOTDIR;
  else
    err = fshelp_access (&dir->nn_stat, S_IEXEC, user);

  if (! err)
    {
      if (strcmp (name, ".") == 0)
	/* Current directory -- just add an additional reference to DIR and
	   return it.  */
	{
	  netfs_nref (dir);
	  *node = dir;
	  err = 0;
	}
      else if (strcmp (name, "..") == 0)
	err = EAGAIN;
      else
	err = lookup_host (dir->nn->mux, name, node);

      fshelp_touch (&dir->nn_stat, TOUCH_ATIME, hostmux_maptime);
    }

  pthread_mutex_unlock (&dir->lock);
  if (err)
    *node = 0;
  else
    pthread_mutex_lock (&(*node)->lock);

  return err;
}
Пример #4
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);
    }