Example #1
0
Npfcall*
diod_lcreate(Npfid *fid, Npstr *name, u32 flags, u32 mode, u32 gid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    char *npath = NULL;
    Npqid qid;
    int fd = -1;
    struct stat sb;
    mode_t saved_umask;
    int created = 0;
    u32 iounit = 0; /* client will use msize-P9_IOHDRSZ */

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(flags & O_CREAT)) /* can't happen? */
        flags |= O_CREAT;
    if (!(npath = _mkpath(f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    saved_umask = umask(0);
    if ((fd = open (npath, flags, mode)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    created = 1;
    umask(saved_umask);
    if (fstat (fd, &sb) < 0) {
        np_uerror (errno);
        goto error; /* shouldn't happen? */
    }
    _ustat2qid (&sb, &qid);
    //iounit = sb.st_blksize;
    if (!((ret = np_create_rlcreate (&qid, iounit)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (f->path);
    f->path = npath;
    f->fd = fd;
    return ret;
error:
    errn (np_rerror (), "diod_lcreate %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          name->len, name->str);
error_quiet:
    if (fd >= 0) {
        (void)close (fd);
    }
    if (created && npath)
        (void)unlink (npath);
    if (npath)
        free (npath);
    if (ret)
        free (ret);
    return NULL;
}
Example #2
0
Npfcall*
diod_symlink(Npfid *fid, Npstr *name, Npstr *symtgt, u32 gid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    char *target = NULL, *npath = NULL;
    Npqid qid;
    struct stat sb;
    mode_t saved_umask;
    int created = 0;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (!(target = np_strdup (symtgt))) {
        np_uerror (ENOMEM);
        goto error;
    }
    saved_umask = umask(0);
    if (symlink (target, npath) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    created = 1;
    umask(saved_umask);
    if (lstat (npath, &sb) < 0) {
        np_uerror (errno);
        goto error; /* shouldn't happen? */
    }
    _ustat2qid (&sb, &qid);
    if (!((ret = np_create_rsymlink (&qid)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (npath);
    free (target);
    return ret;
error:
    errn (np_rerror (), "diod_symlink %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          name->len, name->str);
error_quiet:
    if (created && npath)
        (void)unlink (npath);
    if (npath)
        free (npath);
    if (target)
        free (target);
    if (ret)
        free (ret);
    return NULL;
}
Example #3
0
static int _mkdir (const char *path, int mode, int fatal) {
	int r;
	r = _mkpath(path, mode, fatal); if (r < 0) return r;
	r = mkdir(path, mode);
	if (r < 0 && errno != EEXIST) {
		if (fatal) _fatal("cannot create directory %s", path);
		return r;
	}
	return 0;
}
Example #4
0
/* Trename - rename a file, potentially to another directory
 */
Npfcall*
diod_rename (Npfid *fid, Npfid *dfid, Npstr *name)
{
    Fid *f = fid->aux;
    Fid *d = dfid->aux;
    Npfcall *ret = NULL;
    char *npath = NULL;
    int renamed = 0;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(d->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (rename (f->path, npath) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    renamed = 1;
    if (!(ret = np_create_rrename ())) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (f->path);
    f->path = npath;
    return ret;
error:
    errn (np_rerror (), "diod_rename %s@%s:%s to %s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          d->path, name->len, name->str);
error_quiet:
    if (renamed && npath)
        (void)rename (npath, f->path);
    if (npath)
        free (npath);
    if (ret)
        free (f);
    return NULL;
}
Example #5
0
File: ops.c Project: eugmes/diod
/* Twalk - walk a file path
 * Called from fcall.c::np_walk () on each wname component in succession.
 * On error, call np_uerror () and return 0.
 */
int
diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid)
{
    Fid *f = fid->aux;
    struct stat sb, sb2;
    char *npath = NULL;

    if (f->mountpt) {
        np_uerror (ENOENT);
        goto error_quiet;
    }
    if (!(npath = _mkpath (f->path, wname))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (lstat (npath, &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (lstat (f->path, &sb2) < 0) {
        np_uerror (errno);
        goto error;
    }
    if (sb.st_dev != sb2.st_dev) {
        if (_statmnt (npath, &sb) < 0)
            goto error;
        f->mountpt = 1;
    }
    free (f->path);
    f->path = npath;
    _ustat2qid (&sb, wqid);
    return 1;
error:
    errn (np_rerror (), "diod_walk %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          wname->len, wname->str);
error_quiet:
    if (npath)
        free (npath);
    return 0;
}
Example #6
0
Npfcall*
diod_link (Npfid *dfid, Npfid *fid, Npstr *name)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    Fid *df = dfid->aux;
    char *npath = NULL;
    int created = 0;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(df->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (link (f->path, npath) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    created = 1;
    if (!((ret = np_create_rlink ()))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (npath);
    return ret;
error:
    errn (np_rerror (), "diod_link %s@%s:%s %s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          df->path, name->len, name->str);
error_quiet:
    if (created && npath)
        (void)unlink (npath);
    if (npath)
        free (npath);
    if (ret)
        free (ret);
    return NULL;
}
Example #7
0
/* Twalk - walk a file path
 * Called from fcall.c::np_walk () on each wname component in succession.
 * On error, call np_uerror () and return 0.
 */
int
diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid)
{
    Fid *f = fid->aux;
    struct stat st;
    char *npath;

    if (!(npath = _mkpath (f->path, wname))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (lstat (npath, &st) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    /* N.B. inodes would not be unique if we could cross over to another
     * file system.  But with the code below, ls -l returns ??? for mount
     * point dirs, which would otherwise have a "foreign" inode number.
     * How does NFS make them appear as empty directories?  That would be
     * prettier.
     */
    if (_fidstat (f) < 0)
        goto error;
    if (st.st_dev != f->stat.st_dev) { 
        np_uerror (EXDEV);
        goto error;
    }
    free (f->path);
    f->path = npath;
    _ustat2qid (&st, wqid);
    return 1;
error:
    errn (np_rerror (), "diod_walk %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          wname->len, wname->str);
error_quiet:
    if (npath)
        free (npath);
    return 0;
}
Example #8
0
File: ops.c Project: eugmes/diod
Npfcall*
diod_mknod(Npfid *fid, Npstr *name, u32 mode, u32 major, u32 minor, u32 gid)
{
    Npfcall *ret;
    Fid *f = fid->aux;
    char *npath = NULL;
    Npqid qid;
    struct stat sb;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (mknod (npath, mode, makedev (major, minor)) < 0
                                        || lstat (npath, &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    _ustat2qid (&sb, &qid);
    if (!((ret = np_create_rmknod (&qid)))) {
        (void)unlink (npath);
        np_uerror (ENOMEM);
        goto error;
    }
    free (npath);
    return ret;
error:
    errn (np_rerror (), "diod_mknod %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          name->len, name->str);
error_quiet:
    if (npath)
        free (npath);
    return NULL;
}