Exemplo n.º 1
0
Spfcall *
sp_open(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->omode != (u16)~0) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (fid->type&Qtdir && tc->mode != Oread) {
		sp_werror(Eperm, EISDIR);
		goto done;
	}

	rc = (*conn->srv->open)(fid, tc->mode);
	fid->omode = tc->mode;
done:
//	sp_fid_decref(fid);
	return rc;
}
Exemplo n.º 2
0
Spfcall *
sp_create(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->omode != (u16)~0) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (!fid->type&Qtdir) {
		sp_werror(Enotdir, ENOTDIR);
		goto done;
	}

	if (tc->perm&Dmdir && tc->mode!=Oread) {
		sp_werror(Eperm, EPERM);
		goto done;
	}

	if (tc->perm&(Dmnamedpipe|Dmsymlink|Dmlink|Dmdevice|Dmsocket)
	&& !fid->conn->dotu) {
		sp_werror(Eperm, ENOTSUP);
		goto done;
	}

	rc = (*conn->srv->create)(fid, &tc->name, tc->perm, tc->mode, 
		&tc->extension);
	if (rc && rc->type == Rcreate) {
		fid->omode = tc->mode;
		fid->type = rc->qid.type;
	}

done:
//	sp_fid_decref(fid);
	return rc;
}
Exemplo n.º 3
0
Spfcall *
sp_write(Spreq *req, Spfcall *tc)
{
	int n;
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			n = conn->srv->auth->write(fid, tc->offset,
				tc->count, tc->data);
			if (n >= 0)
				rc = sp_create_rwrite(n);

			goto done;
		} else {
			sp_werror(Ebadusefid, EIO);
			goto done;
		}
	}

	if (fid->omode==(u16)~0 || fid->type&Qtdir || (fid->omode&3)==Oread) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (tc->count+IOHDRSZ > conn->msize) {
		sp_werror(Etoolarge, EIO);
		goto done;
	}

	rc = (*conn->srv->write)(fid, tc->offset, tc->count, tc->data, req);

done:
	return rc;
}
Exemplo n.º 4
0
Spfcall *
sp_clunk(Spreq *req, Spfcall *tc)
{
	int n;
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			n = conn->srv->auth->clunk(fid);
			if (n)
				rc = sp_create_rclunk();
		} else
			sp_werror(Ebadusefid, EIO);

		goto done;
	}

	if (fid->omode!=(u16)~0 && fid->omode==Orclose) {
		rc = (*conn->srv->remove)(fid);
		if (rc->type == Rerror)
			goto done;
		free(rc);
		rc = sp_create_rclunk();
	} else
		rc = (*conn->srv->clunk)(fid);

	if (rc && rc->type == Rclunk)
		sp_fid_decref(fid);

done:
	return rc;
}
Exemplo n.º 5
0
Spfcall *
sp_stat(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	rc = (*conn->srv->stat)(fid);

done:
//	sp_fid_decref(fid);
	return rc;
}
Exemplo n.º 6
0
Spfcall *
sp_wstat(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;
	Spstat *stat;

	rc = NULL;
	conn = req->conn;
	stat = &tc->stat;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (stat->type != (u16)~0 || stat->dev != (u32)~0
	|| stat->qid.version != (u32)~0
	|| stat->qid.path != (u64)~0 ) {
                sp_werror(Eperm, EPERM);
                goto done;
        }

	if ((fid->type&Qtdir && !stat->mode&Dmdir)
	|| (!fid->type&Qtdir&&stat->mode&Dmdir)) {
		sp_werror(Edirchange, EPERM);
		goto done;
	}

	rc = (*conn->srv->wstat)(fid, &tc->stat);
done:
//	sp_fid_decref(fid);
	return rc;
}
Exemplo n.º 7
0
Spfcall *
sp_remove(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	rc = (*conn->srv->remove)(fid);
	if (rc && rc->type == Rremove)
		sp_fid_decref(fid);

done:
	return rc;
}
Exemplo n.º 8
0
Spfcall *
sp_auth(Spreq *req, Spfcall *tc)
{
	int n;
	char *uname, *aname;
	Spconn *conn;
	Spsrv *srv;
	Spfid *afid;
	Spfcall *rc;
	Spuser *user;
	Spqid aqid;

	rc = NULL;
	aname = NULL;
	conn = req->conn;
	srv = conn->srv;
	afid = sp_fid_find(conn, tc->afid);
	if (afid) {
		sp_werror(Einuse, EIO);
		goto done;
	}

	afid = sp_fid_create(conn, tc->afid, NULL);
	if (!afid) 
		goto done;
	else
		sp_fid_incref(afid);

	if (tc->uname.len && tc->n_uname==~0) {
		uname = sp_strdup(&tc->uname);
		if (!uname) 
			goto done;

		user = (*srv->upool->uname2user)(srv->upool, uname);
		free(uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
		tc->n_uname = user->uid;
	} else {
		user = (*srv->upool->uid2user)(srv->upool, tc->n_uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
	}

	if (tc->aname.len) {
		aname = sp_strdup(&tc->aname);
		if (!aname)
			goto done;
	} else
		aname = NULL;

	afid->user = user;
	afid->type = Qtauth;
	if (srv->auth && srv->auth->startauth)
		n = (*srv->auth->startauth)(afid, aname, &aqid);
	else
		n = 0;

	if (n) {
		assert((aqid.type & Qtauth) != 0);
		rc = sp_create_rauth(&aqid);
	} else
		sp_werror(Enoauth, EIO);
done:
	free(aname);
	if (!rc)
		sp_fid_decref(afid);
	return rc;
}
Exemplo n.º 9
0
Spfcall *
sp_read(Spreq *req, Spfcall *tc)
{
	int n;
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (tc->count+IOHDRSZ > conn->msize) {
		sp_werror(Etoolarge, EIO);
		goto done;
	}

	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			rc = sp_alloc_rread(tc->count);
			if (!rc)
				goto done;

			n = conn->srv->auth->read(fid, tc->offset, tc->count, rc->data);
			if (n >= 0) 
				sp_set_rread_count(rc, n);
			else {
				free(rc);
				rc = NULL;
			}
		} else
			sp_werror(Ebadusefid, EIO);

		goto done;
	}

	if (fid->omode==(u16)~0 || (fid->omode&3)==Owrite) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (fid->type&Qtdir && tc->offset != fid->diroffset) {
		sp_werror(Ebadoffset, EIO);
		goto done;
	}
		
	rc = (*conn->srv->read)(fid, tc->offset, tc->count, req);

/*
	if (rc && rc->id==Rread && fid->type&Qtdir) {
		fid->diroffset = tc->offset + rc->count;
	}
*/

done:
	return rc;
}
Exemplo n.º 10
0
Spfcall *
sp_walk(Spreq *req, Spfcall *tc)
{
	int i;
	Spconn *conn;
	Spfid *fid, *newfid;
	Spfcall *rc;
	Spqid wqids[MAXWELEM];

	rc = NULL;
	conn = req->conn;
	newfid = NULL;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (!fid->type&Qtdir) {
		sp_werror(Enotdir, ENOTDIR);
		goto done;
	}

	if (fid->omode != (u16) ~0) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (tc->nwname > MAXWELEM) {
		sp_werror(Etoomanywnames, EIO);
		goto done;
	}

	if (tc->fid != tc->newfid) {
		newfid = sp_fid_find(conn, tc->newfid);
		if (newfid) {
			sp_werror(Einuse, EIO);
			goto done;
		}
		newfid = sp_fid_create(conn, tc->newfid, NULL);
		if (!newfid)
			goto done;

		if (!(*conn->srv->clone)(fid, newfid))
			goto done;

		sp_user_incref(fid->user);
		newfid->user = fid->user;
		newfid->type = fid->type;
	} else
		newfid = fid;

	sp_fid_incref(newfid);
	for(i = 0; i < tc->nwname;) {
		if (!(*conn->srv->walk)(newfid, &tc->wnames[i], &wqids[i]))
			break;

		newfid->type = wqids[i].type;
		i++;

		if (i<(tc->nwname) && !newfid->type&Qtdir)
			break;
	}

	if (i==0 && tc->nwname!=0)
		goto done;

	sp_werror(NULL, 0);
	if (tc->fid != tc->newfid)
		sp_fid_incref(newfid);
	rc = sp_create_rwalk(i, wqids);

done:
	sp_fid_decref(newfid);
	return rc;
}
Exemplo n.º 11
0
Spfcall *
sp_attach(Spreq *req, Spfcall *tc)
{
	char *uname, *aname;
	Spconn *conn;
	Spsrv *srv;
	Spfid *fid, *afid;
	Spfcall *rc;
	Spuser *user;

	rc = NULL;
	aname = NULL;
	conn = req->conn;
	srv = conn->srv;
	afid = NULL;
	fid = sp_fid_find(conn, tc->fid);
	if (fid) {
		sp_werror(Einuse, EIO);
		goto done;
	}

	fid = sp_fid_create(conn, tc->fid, NULL);
	if (!fid)
		goto done;
	else 
		sp_fid_incref(fid);

	req->fid = fid;
	afid = sp_fid_find(conn, tc->afid);
	if (!afid) {
		if (tc->afid!=NOFID) {
			sp_werror(Eunknownfid, EIO);
			goto done;
		}

		if (!afid->type&Qtauth) {
			sp_werror(Ebadusefid, EIO);
			goto done;
		}
	} else 
		sp_fid_incref(afid);

	if (tc->uname.len && tc->n_uname==~0) {
		uname = sp_strdup(&tc->uname);
		if (!uname) 
			goto done;

		user = srv->upool->uname2user(srv->upool, uname);
		free(uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}

		tc->n_uname = user->uid;
	} else {
		user = srv->upool->uid2user(srv->upool, tc->n_uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
	}

	fid->user = user;
	if (tc->aname.len) {
		aname = sp_strdup(&tc->aname);
		if (!aname)
			goto done;
	} else
		aname = NULL;

	if (conn->srv->auth && conn->srv->auth->checkauth
	&& !(*conn->srv->auth->checkauth)(fid, afid, aname))
		goto done;

	rc = (*conn->srv->attach)(fid, afid, &tc->uname, &tc->aname, tc->n_uname);

done:
	free(aname);
	sp_fid_decref(afid);
	return rc;
}
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;
}