Exemplo n.º 1
0
static Spfcall*
npfs_open(Spfid *fid, u8 mode)
{
	int err;
	Fid *f;
	Spqid qid;

	f = fid->aux;
	npfs_change_user(fid->user);
	if ((err = fidstat(f)) < 0)
		create_rerror(err);

	if (S_ISDIR(f->stat.st_mode)) {
		f->dir = opendir(f->path);
		if (!f->dir)
			create_rerror(errno);
	} else {
		f->fd = open(f->path, omode2uflags(mode));
		if (f->fd < 0)
			create_rerror(errno);
	}

	err = fidstat(f);
	if (err < 0)
		create_rerror(err);

	f->omode = mode;
	ustat2qid(&f->stat, &qid);
	return sp_create_ropen(&qid, 0);
}
Exemplo n.º 2
0
static int
npfs_walk(Spfid *fid, Spstr* wname, Spqid *wqid)
{
	int n;
	Fid *f;
	struct stat st;
	char *path;

	f = fid->aux;
	npfs_change_user(fid->user);
	n = fidstat(f);
	if (n < 0)
		create_rerror(n);

	n = strlen(f->path);
	path = malloc(n + wname->len + 2);
	memcpy(path, f->path, n);
	path[n] = '/';
	memcpy(path + n + 1, wname->str, wname->len);
	path[n + wname->len + 1] = '\0';

	if (lstat(path, &st) < 0) {
		free(path);
		create_rerror(errno);
		return 0;
	}

	free(f->path);
	f->path = path;
	ustat2qid(&st, wqid);

	return 1;
}
Exemplo n.º 3
0
static Spfcall*
ufs_read(Spfid *fid, u64 offset, u32 count, Spreq *req)
{
    int n;
    Fid *f;
    Spfcall *ret;

    f = fid->aux;
    ret = sp_alloc_rread(count);
    if (f->dir)
        n = ufs_read_dir(fid, ret->data, offset, count, fid->conn->dotu);
    else {
        n = pread(f->fd, ret->data, count, offset);
        if (n < 0)
            create_rerror(errno);
    }

    if (sp_haserror()) {
        free(ret);
        ret = NULL;
    } else
        sp_set_rread_count(ret, n);

    return ret;
}
Exemplo n.º 4
0
static Spfcall*
npfs_read(Spfid *fid, u64 offset, u32 count, Spreq *req)
{
	int n;
	Fid *f;
	Spfcall *ret;

	f = fid->aux;
	ret = sp_alloc_rread(count);
	npfs_change_user(fid->user);
	if (f->dir)
		n = npfs_read_dir(f, ret->data, offset, count, fid->conn->dotu);
	else {
		if(mmapreads) {
			struct stat s;
			n = count;
			if(!f->aux) {
				fstat(f->fd, &s);
				f->aux=mmap(0, s.st_size, PROT_READ, 
						MAP_SHARED, f->fd, 0);
				if(f->aux < 0) {
					create_rerror(errno);
					goto error;	
				}
			}
			if(offset+count > s.st_size)
				n = s.st_size-offset;
			if(n>0)
				memcpy(ret->data, f->aux+offset, n);
			else 
				n = 0;
		} else {
			n = pread(f->fd, ret->data, count, offset);
			if (n < 0)
				create_rerror(errno);
		}
	}

error:
	if (sp_haserror()) {
		free(ret);
		ret = NULL;
	} else
		sp_set_rread_count(ret, n);

	return ret;
}
Exemplo n.º 5
0
static Spfcall*
ufs_write(Spfid *fid, u64 offset, u32 count, u8 *data, Spreq *req)
{
    int n;
    Fid *f;

    f = fid->aux;
    n = pwrite(f->fd, data, count, offset);
    if (n < 0)
        create_rerror(errno);

    return sp_create_rwrite(n);
}
Exemplo n.º 6
0
static Spfcall*
npfs_remove(Spfid *fid)
{
	Fid *f;
	Spfcall *ret;

	ret = NULL;
	f = fid->aux;
	npfs_change_user(fid->user);
	if (remove(f->path) < 0) {
		create_rerror(errno);
		goto out;
	}

	ret = sp_create_rremove();

out:
//	sp_fid_decref(fid);
	return ret;
}
Exemplo n.º 7
0
static Spfcall*
ufs_stat(Spfid *fid)
{
    int err;
    Fid *f;
    Spfcall *ret;
    Spwstat wstat;

    f = fid->aux;
    err = fidstat(f);
    if (err < 0)
        create_rerror(err);

    ustat2npwstat(f->path, &f->stat, &wstat, fid->conn->dotu, fid->conn->srv->upool);

    ret = sp_create_rstat(&wstat, fid->conn->dotu);
    free(wstat.extension);

    return ret;
}
Exemplo n.º 8
0
static Spfcall*
npfs_attach(Spfid *nfid, Spfid *nafid, Spstr *uname, Spstr *aname, u32 n_uname)
{
	int err;
	Spfcall* ret;
	Fid *fid;
	Spqid qid;
	char *user;

	user = NULL;
	ret = NULL;

	if (nafid != NULL) {
		sp_werror(Enoauth, EIO);
		goto done;
	}

	fid = npfs_fidalloc();
	fid->omode = -1;
	npfs_change_user(nfid->user);

	fid->omode = -1;
	if (aname->len==0 || *aname->str!='/')
		fid->path = strdup("/");
	else
		fid->path = sp_strdup(aname);
	
	nfid->aux = fid;
	err = fidstat(fid);
	if (err < 0) {
		create_rerror(err);
		goto done;
	}

	ustat2qid(&fid->stat, &qid);
	ret = sp_create_rattach(&qid);
	sp_fid_incref(nfid);

done:
	return ret;
}
Exemplo n.º 9
0
static Spfcall*
npfs_wstat(Spfid *fid, Spstat *stat)
{
	int err;
	Fid *f;
	Spfcall *ret;
	uid_t uid;
	gid_t gid;
	char *npath, *p, *s;
	Spuser *user;
	Spgroup *group;
	struct utimbuf tb;

	ret = NULL;
	f = fid->aux;
	npfs_change_user(fid->user);
	err = fidstat(f);
	if (err < 0) {
		create_rerror(err);
		goto out;
	}

	if (fid->conn->dotu) {
		uid = stat->n_uid;
		gid = stat->n_gid;
	} else {
		uid = (uid_t) -1;
		gid = (gid_t) -1;
	}

	if (uid == -1 && stat->uid.len) {
		s = sp_strdup(&stat->uid);
		user = sp_uname2user(s);
		free(s);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto out;
		}

		uid = user->uid;
	}

	if (gid == -1 && stat->gid.len) {
		s = sp_strdup(&stat->gid);
		group = sp_gname2group(s);
		free(s);
		if (!group) {
			sp_werror(Eunknownuser, EIO);
			goto out;
		}

		gid = group->gid;
	}

	if (stat->mode != (u32)~0) {
		if (stat->mode&Dmdir && !S_ISDIR(f->stat.st_mode)) {
			sp_werror(Edirchange, EIO);
			goto out;
		}

		if (chmod(f->path, npstat2umode(stat, fid->conn->dotu)) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (stat->mtime != (u32)~0) {
		tb.actime = 0;
		tb.modtime = stat->mtime;
		if (utime(f->path, &tb) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (gid != -1) {
		if (chown(f->path, uid, gid) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (stat->name.len != 0) {
		p = strrchr(f->path, '/');
		if (!p)
			p = f->path + strlen(f->path);

		npath = malloc(stat->name.len + (p - f->path) + 2);
		memcpy(npath, f->path, p - f->path);
		npath[p - f->path] = '/';
		memcpy(npath + (p - f->path) + 1, stat->name.str, stat->name.len);
		npath[(p - f->path) + 1 + stat->name.len] = 0;
		if (strcmp(npath, f->path) != 0) {
			if (rename(f->path, npath) < 0) {
				create_rerror(errno);
				goto out;
			}

			free(f->path);
			f->path = npath;
		}
	}

	if (stat->length != ~0) {
		if (truncate(f->path, stat->length) < 0) {
			create_rerror(errno);
			goto out;
		}
	}
	ret = sp_create_rwstat();
	
out:
	return ret;
}
Exemplo n.º 10
0
static u32
npfs_read_dir(Fid *f, u8* buf, u64 offset, u32 count, int dotu)
{
	int i, n, plen;
	char *dname, *path;
	struct dirent *dirent;
	struct stat st;
	Spwstat wstat;

	if (offset == 0) {
		rewinddir(f->dir);
		f->diroffset = 0;
	}

	plen = strlen(f->path);
	n = 0;
	dirent = NULL;
	dname = f->direntname;
	while (n < count) {
		if (!dname) {
			dirent = readdir(f->dir);
			if (!dirent)
				break;

			if (strcmp(dirent->d_name, ".") == 0
			|| strcmp(dirent->d_name, "..") == 0)
				continue;

			dname = dirent->d_name;
		}

		path = malloc(plen + strlen(dname) + 2);
		sprintf(path, "%s/%s", f->path, dname);
		
		if (lstat(path, &st) < 0) {
			free(path);
			create_rerror(errno);
			return 0;
		}

		ustat2npwstat(path, &st, &wstat, dotu);
		i = sp_serialize_stat(&wstat, buf + n, count - n - 1, dotu);
		free(wstat.extension);
		free(path);
		path = NULL;
		if (i==0)
			break;

		dname = NULL;
		n += i;
	}

	if (f->direntname) {
		free(f->direntname);
		f->direntname = NULL;
	}

	if (dirent)
		f->direntname = strdup(dirent->d_name);

	f->diroffset += n;
	return n;
}
Exemplo n.º 11
0
static Spfcall*
npfs_create(Spfid *fid, Spstr *name, u32 perm, u8 mode, Spstr *extension)
{
	int n, err, omode;
	Fid *f;
	Spfcall *ret;
	Spqid qid;
	char *npath;
	struct stat st;

	ret = NULL;
	omode = mode;
	f = fid->aux;
	if ((err = fidstat(f)) < 0)
		create_rerror(err);

	n = strlen(f->path);
	npath = malloc(n + name->len + 2);
	memmove(npath, f->path, n);
	npath[n] = '/';
	memmove(npath + n + 1, name->str, name->len);
	npath[n + name->len + 1] = '\0';

	if (lstat(npath, &st)==0 || errno!=ENOENT) {
		sp_werror(Eexist, EEXIST);
		goto out;
	}

	if (perm & Dmdir) {
		if (mkdir(npath, perm & 0777) < 0) {
			create_rerror(errno);
			goto out;
		}

		if (lstat(npath, &f->stat) < 0) {
			create_rerror(errno);
			rmdir(npath);
			goto out;
		}
		
		f->dir = opendir(npath);
		if (!f->dir) {
			create_rerror(errno);
			remove(npath);
			goto out;
		}
	} else if (perm & (Dmnamedpipe|Dmsymlink|Dmlink|Dmdevice)) {
		if (npfs_create_special(fid, npath, perm, extension) < 0)
			goto out;

		if (lstat(npath, &f->stat) < 0) {
			create_rerror(errno);
			remove(npath);
			goto out;
		}
	} else {
		f->fd = open(npath, O_CREAT|omode2uflags(mode), 
			perm & 0777);
		if (f->fd < 0) {
			create_rerror(errno);
			goto out;
		}

		if (lstat(npath, &f->stat) < 0) {
			create_rerror(errno);
			remove(npath);
			goto out;
		}
	}

	free(f->path);
	f->path = npath;
	f->omode = omode;
	npath = NULL;
	ustat2qid(&f->stat, &qid);
	ret = sp_create_rcreate(&qid, 0);

out:
	free(npath);
	return ret;
}
Exemplo n.º 12
0
static int
npfs_create_special(Spfid *fid, char *path, u32 perm, Spstr *extension)
{
	int nfid, err;
	int nmode, major, minor;
	char ctype;
	mode_t umode;
	Spfid *ofid;
	Fid *f, *of;
	char *ext;

	f = fid->aux;
	if (!perm&Dmnamedpipe && !extension->len) {
		sp_werror(Enoextension, EIO);
		return -1;
	}

	umode = np2umode(perm, extension, fid->conn->dotu);
	ext = sp_strdup(extension);
	if (perm & Dmsymlink) {
		if (symlink(ext, path) < 0) {
			err = errno;
			fprintf(stderr, "symlink %s %s %d\n", ext, path, err);
			create_rerror(err);
			goto error;
		}
	} else if (perm & Dmlink) {
		if (sscanf(ext, "%d", &nfid) == 0) {
			sp_werror(Eformat, EIO);
			goto error;
		}

		ofid = sp_fid_find(fid->conn, nfid);
		if (!ofid) {
			sp_werror(Eunknownfid, EIO);
			goto error;
		}

		of = ofid->aux;
		if (link(of->path, path) < 0) {
			create_rerror(errno);
			goto error;
		}
	} else if (perm & Dmdevice) {
		if (sscanf(ext, "%c %u %u", &ctype, &major, &minor) != 3) {
			sp_werror(Eformat, EIO);
			goto error;
		}

		nmode = 0;
		switch (ctype) {
		case 'c':
			nmode = S_IFCHR;
			break;

		case 'b':
			nmode = S_IFBLK;
			break;

		default:
			sp_werror(Eformat, EIO);
			goto error;
		}

		nmode |= perm & 0777;
		if (mknod(path, nmode, makedev(major, minor)) < 0) {
			create_rerror(errno);
			goto error;
		}
	} else if (perm & Dmnamedpipe) {
		if (mknod(path, S_IFIFO | (umode&0777), 0) < 0) {
			create_rerror(errno);
			goto error;
		}
	}

	f->omode = 0;
	if (!perm&Dmsymlink && chmod(path, umode)<0) {
		create_rerror(errno);
		goto error;
	}

	free(ext);
	return 0;

error:
	free(ext);
	return -1;
}