Ejemplo n.º 1
0
Archivo: pool.c Proyecto: nuxlli/npfs
Npcpool *
npc_create_pool(u32 maxid)
{
	Npcpool *p;

	p = malloc(sizeof(*p));
	if (!p) {
		np_werror(Ennomem, ENOMEM);
		return NULL;
	}

	p->maxid = maxid;
	pthread_mutex_init(&p->lock, NULL);
	pthread_cond_init(&p->cond, NULL);
	p->msize = 32;	/* 256 ids */
	p->map = malloc(p->msize);
	if (!p->map) {
		np_werror(Ennomem, ENOMEM);
		free(p);
		return NULL;
	}

	memset(p->map, 0, p->msize);
	return p;
}
Ejemplo n.º 2
0
static Npfcall *
np_auth(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *afid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	afid = np_fid_find(conn, tc->afid);
	if (afid) {
		np_werror(Einuse, EIO);
		goto done;
	}

	afid = np_fid_create(conn, tc->afid, NULL);
	if (!afid) {
		np_werror(Enomem, ENOMEM);
		goto done;
	}

	if (conn->srv->auth)
		rc = (*conn->srv->auth->auth)(afid, &tc->uname, &tc->aname);
	else
		np_werror(Enoauth, EIO);

	afid->type = Qtauth;
done:
	np_fid_decref(afid);
	return rc;
}
Ejemplo n.º 3
0
static Npfcall*
np_default_version(Npconn *conn, u32 msize, Npstr *version) 
{
	int dotu;
	char *ver;
	Npfcall *rc;

	if (msize > conn->srv->msize)
		msize = conn->srv->msize;

	dotu = 0;
	if (np_strcmp(version, "9P2000.u")==0 && conn->srv->dotu) {
		ver = "9P2000.u";
		dotu = 1;
	} else if (np_strncmp(version, "9P2000", 6) == 0)
		ver = "9P2000";
	else
		ver = NULL;

	if (msize < IOHDRSZ)
		np_werror("msize too small", EIO);
	else if (ver) {
		np_conn_reset(conn, msize, dotu);
		rc = np_create_rversion(msize, ver);
	} else
		np_werror("unsupported 9P version", EIO);

	return rc;
}
Ejemplo n.º 4
0
static Npfcall *
np_open(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

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

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

	rc = (*conn->srv->open)(fid, tc->mode);
	fid->omode = tc->mode;
done:
	np_fid_decref(fid);
	return rc;
}
Ejemplo n.º 5
0
static Npfcall *
np_attach(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid, *afid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	afid = NULL;

	/* the fid that the connecting client wants to call root  */
	fid = np_fid_find(conn, tc->fid);

	/* if this fid exists then report error  */
	if (fid) {
		np_werror(Einuse, EIO);
		goto done;
	}

	/* create a fid structure for the root   */
	fid = np_fid_create(conn, tc->fid, NULL);
	if (!fid) {
		np_werror(Enomem, ENOMEM);
		goto done;
	} else 
	  /* maintain a reference count for fid   */
		np_fid_incref(fid);

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

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

	if (conn->srv->auth) {
		rc = (*conn->srv->auth->attach)(afid, &tc->uname, &tc->aname);
		if (rc)
			goto done;
	}

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

done:
	np_fid_decref(fid);
	np_fid_decref(afid);
	return rc;
}
Ejemplo n.º 6
0
static Npfcall *
np_read(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto error;
	} else 
		np_fid_incref(fid);

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

	if (fid->type&Qtauth) {
		if (conn->srv->auth)
			rc = conn->srv->auth->read(fid, tc->offset, tc->count);
		else
			np_werror(Ebadusefid, EIO);

		goto error;
	}

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

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

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

	return rc;

error:
	np_fid_decref(fid);
	return NULL;
}
Ejemplo n.º 7
0
static Npfcall *
np_create(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

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

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

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

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

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

done:
	np_fid_decref(fid);
	return rc;
}
Ejemplo n.º 8
0
static Npfcall *
np_write(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto error;
	} else 
		np_fid_incref(fid);

	req->fid = fid;
	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			rc = conn->srv->auth->write(fid, tc->offset, 
				tc->count, tc->data);
			np_fid_decref(fid);
			return rc;
		} else {
			np_werror(Ebadusefid, EIO);
			goto error;
		}
	}

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

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

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

	return rc;

error:
	np_fid_decref(fid);
	return NULL;
}
Ejemplo n.º 9
0
void
np_uerror(int ecode)
{
	char buf[256];

	strerror_r(ecode, buf, sizeof(buf));
	np_werror(buf, ecode);
}
Ejemplo n.º 10
0
void
np_suerror(char *s, int ecode)
{
	char err[256];
	char buf[512];

	strerror_r(ecode, err, sizeof(err));
	snprintf(buf, sizeof(buf), "%s: %s", s, err);
	np_werror(buf, ecode);
}
Ejemplo n.º 11
0
void *
np_malloc(int size)
{
	void *ret;

	ret = malloc(size);
	if (!ret)
		np_werror(Ennomem, ENOMEM);

	return ret;
}
Ejemplo n.º 12
0
static Npfcall *
np_clunk(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

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

		goto done;
	}

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

done:
	np_fid_decref(fid);
	return rc;
}
Ejemplo n.º 13
0
static Npfcall *
np_wstat(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;
	Npstat *stat;

	rc = NULL;
	conn = req->conn;
	stat = &tc->stat;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_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 ) {
                np_werror(Eperm, EPERM);
                goto done;
        }

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

	rc = (*conn->srv->wstat)(fid, &tc->stat);
done:
	np_fid_decref(fid);
	return rc;
}
Ejemplo n.º 14
0
static Npfcall*
np_process_request(Npreq *req)
{
	Npconn *conn;
	Npfcall *tc, *rc;
	np_fcall f;
	char *ename;
	int ecode;

	conn = req->conn;
	rc = NULL;
	tc = req->tcall;

	f = NULL;
	if (tc->id<Tfirst && tc->id>Rlast)
		np_werror("unknown message type", ENOSYS);
	else {
	  //	  printf("MAINLOOP rcvd msg of type <%d>\n",tc->id);
	  f = np_fcalls[(tc->id-Tfirst)/2];
	}

	np_werror(NULL, 0);
	if (f)
		rc = (*f)(req, tc);
	else
		np_werror("unsupported message", ENOSYS);

	np_rerror(&ename, &ecode);
	if (ename != NULL) {
		if (rc)
			free(rc);
		rc = np_create_rerror(ename, ecode, conn->dotu);
	}

	return rc;
}
Ejemplo n.º 15
0
Npcfsys*
npc_mount(int fd, char *aname, char *uname)
{
	Npcfsys *fs;
	Npfcall *tc, *rc;

	fs = npc_create_fsys(fd, 8216);
	if (!fs)
		return NULL;

	tc = np_create_tversion(8216, "9P2000.u");
	if (npc_rpc(fs, tc, &rc) < 0)
		goto error;

	if (rc->version.len==8 && !memcmp(rc->version.str, "9P2000.u", 8)) {
		fs->dotu = 1;
	} else if (rc->version.len==6 && !memcmp(rc->version.str, "9P2000", 6)) {
		fs->dotu = 0;
	} else {
		np_werror("unsupported 9P version", EIO);
		goto error;
	}
	free(tc);
	free(rc);
	tc = rc = NULL;

	fs->root = npc_fid_alloc(fs);
	if (!fs->root) 
		goto error;

	tc = np_create_tattach(fs->root->fid, NOFID, uname, aname);
	if (npc_rpc(fs, tc, &rc) < 0)
		goto error;

	free(tc);
	free(rc);
	return fs;

error:
	free(tc);
	free(rc);
	npc_disconnect_fsys(fs);
	npc_decref_fsys(fs);

	return NULL;
}
Ejemplo n.º 16
0
Archivo: fid.c Proyecto: nuxlli/npfs
Npcfid *
npc_fid_alloc(Npcfsys *fs)
{
    Npcfid *ret;

    ret = malloc(sizeof(*ret));
    if (!ret) {
        np_werror(Ennomem, ENOMEM);
        return NULL;
    }

    ret->fsys = fs;
    ret->fid = npc_get_id(fs->fidpool);
    ret->offset = 0;
    ret->iounit = 0;

    npc_incref_fsys(fs);
    return ret;
}
Ejemplo n.º 17
0
static Npfcall *
np_remove(Npreq *req, Npfcall *tc)
{
	Npconn *conn;
	Npfid *fid;
	Npfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

	req->fid = fid;
	rc = (*conn->srv->remove)(fid);
done:
	np_fid_decref(fid);
	return rc;
}
Ejemplo n.º 18
0
static Npfcall*
np_default_write(Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *req)
{
	np_werror(Enotimpl, ENOSYS);
	return NULL;
}
Ejemplo n.º 19
0
static int
np_default_walk(Npfid *fid, Npstr* wname, Npqid *wqid)
{
	np_werror(Enotimpl, ENOSYS);
	return 0;
}
Ejemplo n.º 20
0
static Npfcall*
np_default_open(Npfid *fid, u8 perm)
{
	np_werror(Enotimpl, ENOSYS);
	return NULL;
}
Ejemplo n.º 21
0
static Npfcall*
np_default_create(Npfid *fid, Npstr *name, u32 mode, u8 perm, Npstr *extension)
{
	np_werror(Enotimpl, ENOSYS);
	return NULL;
}
Ejemplo n.º 22
0
int
npc_dirread(Npcfid *fid, Npwstat **statpp)
{
	int i, n, m, buflen, statsz, slen, count;
	u8 *buf;
	char *sbuf;
	Npstat stat;
	Npwstat *statp;

	buflen = fid->fsys->msize - IOHDRSZ;
	buf = malloc(buflen);
	if (!buf)
		return -1;

	n = npc_read(fid, buf, buflen, fid->offset);
	if (n < 0) {
		free(buf);
		return n;
	}

	fid->offset += n;
	count = 0;
	i = 0;
	slen = 0;
	while (i < n) {
		statsz = np_deserialize_stat(&stat, buf + i, buflen - i, fid->fsys->dotu);
		if (!statsz) {
			np_werror("stat error", EIO);
			free(buf);
			return -1;
		}

		count++;
		slen += npc_wstatlen(&stat);
		i += statsz;
	}

	statp = malloc(slen);
	if (!statp) {
		np_werror(Ennomem, ENOMEM);
		free(buf);
	}

	sbuf = ((char *) statp) + count * sizeof(Npwstat);
	i = 0;
	m = 0;
	while (i < n) {
		statsz = np_deserialize_stat(&stat, buf + i, buflen - i, fid->fsys->dotu);
		if (!statsz)
			break;

		npc_stat2wstat(&stat, &statp[m], &sbuf);
		m++;
		i += statsz;
	}

	free(buf);
	*statpp = statp;

	return count;
}
Ejemplo n.º 23
0
static Npfcall *
np_walk(Npreq *req, Npfcall *tc)
{
	int i;
	Npconn *conn;
	Npfid *fid, *newfid;
	Npfcall *rc;
	Npqid wqids[MAXWELEM];

	rc = NULL;
	conn = req->conn;
	newfid = NULL;
	fid = np_fid_find(conn, tc->fid);
	if (!fid) {
		np_werror(Eunknownfid, EIO);
		goto done;
	} else 
		np_fid_incref(fid);

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

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

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

	if (tc->fid != tc->newfid) {
		newfid = np_fid_find(conn, tc->newfid);
		if (newfid) {
			np_werror(Einuse, EIO);
			goto done;
		}
		newfid = np_fid_create(conn, tc->newfid, NULL);
		if (!newfid) {
			np_werror(Enomem, ENOMEM);
			goto done;
		}

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

		newfid->user = fid->user;
		newfid->type = fid->type;
	} else
		newfid = fid;

	np_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;

	np_werror(NULL, 0);
	if (tc->fid != tc->newfid)
		np_fid_incref(newfid);
	rc = np_create_rwalk(i, wqids);

done:
	np_fid_decref(fid);
	np_fid_decref(newfid);
	return rc;
}
Ejemplo n.º 24
0
static Npfcall*
np_default_remove(Npfid *fid)
{
	np_werror(Enotimpl, ENOSYS);
	return NULL;
}
Ejemplo n.º 25
0
static Npfcall*
np_default_wstat(Npfid *fid, Npstat *stat)
{
	np_werror(Enotimpl, ENOSYS);
	return NULL;
}
Ejemplo n.º 26
0
static Npfcall*
np_default_attach(Npfid *fid, Npfid *afid, Npstr *uname, Npstr *aname)
{
	np_werror(Enotimpl, EIO);
	return NULL;
}
Ejemplo n.º 27
0
Npcfsys*
npc_mount(int fd, char *aname, Npuser *user, 
	int (*auth)(Npcfid *afid, Npuser *user, void *aux), void *aux)
{
	Npcfsys *fs;
	Npfcall *tc, *rc;

	fs = npc_create_fsys(fd, 8216);
	if (!fs)
		return NULL;

	tc = np_create_tversion(8216, "9P2000.u");
	if (npc_rpc(fs, tc, &rc) < 0)
		goto error;

	if (rc->version.len==8 && !memcmp(rc->version.str, "9P2000.u", 8)) {
		fs->dotu = 1;
	} else if (rc->version.len==6 && !memcmp(rc->version.str, "9P2000", 6)) {
		fs->dotu = 0;
	} else {
		np_werror("unsupported 9P version", EIO);
		goto error;
	}
	free(tc);
	free(rc);
	tc = rc = NULL;

	if (auth) {
		fs->afid = npc_fid_alloc(fs);
		if (!fs->afid)
			goto error;

		tc = np_create_tauth(fs->afid->fid, user?user->uname:NULL, aname, 
			user?user->uid:-1, fs->dotu);
		if (npc_rpc(fs, tc, &rc) < 0) {
			npc_fid_free(fs->afid);
			fs->afid = NULL;
		} else if ((*auth)(fs->afid, user, aux) < 0)
				goto error;

		free(tc);
		free(rc);
		tc = rc = NULL;
	}

	fs->root = npc_fid_alloc(fs);
	if (!fs->root) 
		goto error;

	tc = np_create_tattach(fs->root->fid, fs->afid?fs->afid->fid:NOFID, 
		user->uname, aname, user->uid, fs->dotu);
	if (npc_rpc(fs, tc, &rc) < 0)
		goto error;

	free(tc);
	free(rc);
	return fs;

error:
	free(tc);
	free(rc);
	npc_disconnect_fsys(fs);
	npc_decref_fsys(fs);

	return NULL;
}