示例#1
0
文件: fsys.c 项目: fr1tz/nadir
void
fsysproc(void *v)
{
	int n;
	Xfid *x;
	Fid *f;
	Fcall t;
	uchar *buf;

	threadsetname("fsysproc");

	USED(v);
	x = nil;
	for(;;){
		buf = emalloc(messagesize+UTFmax);	/* overflow for appending partial rune in xfidwrite */
		n = read9pmsg(sfd, buf, messagesize);
		if(n <= 0){
			if(closing)
				break;
			error("i/o error on server channel");
		}
		if(x == nil){
			sendp(cxfidalloc, nil);
			x = recvp(cxfidalloc);
		}
		x->buf = buf;
		if(convM2S(buf, n, &x->fcall) != n)
			error("convert error in convM2S");
		if(DEBUG)
			fprint(2, "%F\n", &x->fcall);
		if(fcall[x->fcall.type] == nil)
			x = respond(x, &t, "bad fcall type");
		else{
			switch(x->fcall.type){
			case Tversion:
			case Tauth:
			case Tflush:
				f = nil;
				break;
			case Tattach:
				f = newfid(x->fcall.fid);
				break;
			default:
				f = newfid(x->fcall.fid);
				if(!f->busy){
					x->f = f;
					x = respond(x, &t, "fid not in use");
					continue;
				}
				break;
			}
			x->f = f;
			x  = (*fcall[x->fcall.type])(x, f);
		}
	}
}
示例#2
0
文件: proto.c 项目: aberg001/plan9
static void
rwalk(Fcall *f)
{
    int i, j;
    Fcall r;
    Fid *fidp, *nf;
    char *err;

    fidp = newfid(f->fid);
    if(fidp->node && fidp->node->d.type == Dummynode) {
        reply(f, "can't walk an address node");
        return;
    }
    if(f->fid == f->newfid)
        nf = fidp;
    else {
        nf = newfid(f->newfid);
        nf->busy = 1;
        nf->node = fidp->node;
        nf->uid = fidp->uid;
        nf->name = fidp->name;
        if(debugfd >= 0)
            printfid(nf);
    }

    err = nil;
    for(i=0; i<f->nwname; i++) {
        err = walk(f->wname[i], nf);
        if(err)
            break;
        r.wqid[i] = nf->node->d.qid;
    }


    if(i < f->nwname && f->fid != f->newfid) {
        nf->busy = 0;
        nf->node = 0;
        nf->name = 0;
        nf->uid = 0;
    }
    if(i > 0 && i < f->nwname && f->fid == f->newfid) {
        /*
         * try to put things back;
         * we never get this sort of call from the kernel
         */
        for(j=0; j<i; j++)
            walk("..", nf);
    }
    memmove(f->wqid, r.wqid, sizeof f->wqid);
    f->nwqid = i;
    if(err && i==0)
        reply(f, err);
    else
        reply(f, 0);
}
示例#3
0
文件: proto.c 项目: aberg001/plan9
/*
 *	We don't have to do full permission checking because most files
 *	have restricted semantics:
 *		The ctl file is only writable
 *		All others, including directories, are only readable
 */
static void
ropen(Fcall *f)
{
    Fid *fidp;
    int mode;

    fidp = newfid(f->fid);

    if(debugfd >= 0)
        printfid(fidp);

    mode = f->mode&(OREAD|OWRITE|ORDWR);
    if(fidp->node->d.type == Ctlfile) {
        if(mode != OWRITE) {
            reply(f, "permission denied");
            return;
        }
    } else if (mode != OREAD) {
        reply(f, "permission denied or operation not supported");
        return;
    }

    f->qid = fidp->node->d.qid;
    fidp->open = 1;
    reply(f, 0);
}
示例#4
0
文件: proto.c 项目: aberg001/plan9
/*
 *	creates are only allowed in the "trusted" subdirectory
 *	we also assume that the groupid == the uid
 */
static void
rcreate(Fcall *f)
{
    Fid *fidp;
    Node *np;

    fidp = newfid(f->fid);
    np = fidp->node;
    if((np->d.mode&DMDIR) == 0) {
        reply(f, "not a directory");
        return;
    }

    if(!permitted(fidp, np, AWRITE)) {
        reply(f, "permission denied");
        return;
    }

    /* Ignore the supplied mode and force it to be non-writable */

    np = newnode(np, f->name, Trustedtemp, 0444, trustedqid++);
    if(trustedqid >= Qaddrfile)			/* wrap QIDs */
        trustedqid = Qtrustedfile;
    cidrparse(&np->ip, f->name);
    f->qid = np->d.qid;
    np->d.uid = fidp->uid;
    np->d.gid = np->d.uid;
    np->d.muid = np->d.muid;
    fidp->node = np;
    fidp->open = 1;
    reply(f, 0);
    return;
}
示例#5
0
文件: fs.c 项目: 00001/plan9port
void
io(void)
{
	char *err;
	int n, nerr;
	char buf[ERRMAX];

	errstr(buf, sizeof buf);
	for(nerr=0, buf[0]='\0'; nerr<100; nerr++){
		/*
		 * reading from a pipe or a network device
		 * will give an error after a few eof reads
		 * however, we cannot tell the difference
		 * between a zero-length read and an interrupt
		 * on the processes writing to us,
		 * so we wait for the error
		 */
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n==0)
			continue;
		if(n < 0){
			if(buf[0]=='\0')
				errstr(buf, sizeof buf);
			continue;
		}
		nerr = 0;
		buf[0] = '\0';
		if(convM2S(mdata, n, &rhdr) != n)
			error("convert error in convM2S");

		if(verbose)
			fprint(2, "tapefs: <=%F\n", &rhdr);/**/

		thdr.data = (char*)mdata + IOHDRSZ;
		thdr.stat = mdata + IOHDRSZ;
		if(!fcalls[rhdr.type])
			err = "bad fcall type";
		else
			err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
		if(err){
			thdr.type = Rerror;
			thdr.ename = err;
		}else{
			thdr.type = rhdr.type + 1;
			thdr.fid = rhdr.fid;
		}
		thdr.tag = rhdr.tag;
		n = convS2M(&thdr, mdata, messagesize);
		if(n <= 0)
			error("convert error in convS2M");
		if(verbose)
			fprint(2, "tapefs: =>%F\n", &thdr);/**/
		if(write(mfd[1], mdata, n) != n)
			error("mount write");
	}
	if(buf[0]=='\0' || strstr(buf, "hungup"))
		exits("");
	fprint(2, "%s: mount read: %s\n", argv0, buf);
	exits(buf);
}
示例#6
0
文件: proto.c 项目: aberg001/plan9
static void
rclone(Fcall *f)
{
    Fid *fidp, *nf;

    fidp = newfid(f->fid);
    if(fidp->node && fidp->node->d.type == Dummynode) {
        reply(f, "can't clone an address");
        return;
    }
    nf = newfid(f->newfid);
    nf->busy = 1;
    nf->node = fidp->node;
    nf->uid = fidp->uid;
    nf->name = fidp->name;
    if(debugfd >= 0)
        printfid(nf);
    reply(f,0);
}
示例#7
0
void
Xattach(Fsrpc *t)
{
	Fcall rhdr;
	Fid *f;

	f = newfid(t->work.fid);
	if(f == 0) {
		reply(&t->work, &rhdr, Ebadfid);
		t->busy = 0;
		return;
	}

	if(srvfd >= 0){
/*
		if(psmpt == 0){
		Nomount:
			reply(&t->work, &rhdr, Enopsmt);
			t->busy = 0;
			freefid(t->work.fid);
			return;
		}
		for(i=0; i<Npsmpt; i++)
			if(psmap[i] == 0)
				break;
		if(i >= Npsmpt)
			goto Nomount;
		sprint(buf, "%d", i);
		f->f = file(psmpt, buf);
		if(f->f == nil)
			goto Nomount;
		sprint(buf, "/mnt/exportfs/%d", i);
		nfd = dup(srvfd, -1);
		if(amount(nfd, buf, MREPL|MCREATE, t->work.aname) < 0){
			errstr(buf, sizeof buf);
			reply(&t->work, &rhdr, buf);
			t->busy = 0;
			freefid(t->work.fid);
			close(nfd);
			return;
		}
		psmap[i] = 1;
		f->mid = i;
*/
	}else{
		f->f = root;
		f->f->ref++;
	}

	rhdr.qid = f->f->qid;
	reply(&t->work, &rhdr, 0);
	t->busy = 0;
}
示例#8
0
文件: proto.c 项目: aberg001/plan9
static void
rclunk(Fcall *f)
{
    Fid *fidp;

    fidp = newfid(f->fid);
    fidp->open = 0;
    fidp->busy = 0;
    fidp->node = 0;
    fidp->name = 0;
    fidp->uid = 0;
    reply(f, 0);
}
示例#9
0
static int
remov(int n, Rpccall *cmd, Rpccall *reply)
{
	Session *s;
	Xfile *xp;
	Xfid *xf, *newxf;
	String elem;
	Fid *nfid;
	uchar *argptr = cmd->args;
	uchar *dataptr = reply->results;

	if(n <= FHSIZE)
		return garbage(reply, "count too small");
	xf = rpc2xfid(cmd, 0);
	argptr += FHSIZE;
	argptr += string2S(argptr, &elem);
	if(argptr != &((uchar *)cmd->args)[n])
		return garbage(reply, "bad count");
	if(xf == 0)
		return error(reply, NFSERR_STALE);
	xp = xf->xp;
	if(!(xp->qid.type & QTDIR))
		return error(reply, NFSERR_NOTDIR);
	chat("%s/%.*s...", xp->name, utfnlen(elem.s, elem.n), elem.s);
	if(xp->s->noauth == 0 && xp->parent == xp && elem.s[0] == '#')
		return error(reply, NFSERR_PERM);
	newxf = xfwalkcr(Twalk, xf, &elem, 0);
	if(newxf == 0)
		return error(reply, NFSERR_NOENT);
	s = xp->s;
	nfid = newfid(s);
	setfid(s, newxf->urfid);
	s->f.newfid = nfid - s->fids;
	s->f.nwname = 0;
	if(xmesg(s, Twalk) < 0){
		putfid(s, nfid);
		return error(reply, NFSERR_IO);
	}
	s->f.fid = nfid - s->fids;
	if(xmesg(s, Tremove) < 0){
		putfid(s, nfid);
		return error(reply, NFSERR_PERM);
	}
	putfid(s, nfid);
	xpclear(newxf->xp);
	PLONG(NFS_OK);
	chat("OK\n");
	return dataptr - (uchar *)reply->results;
}
示例#10
0
文件: proto.c 项目: aberg001/plan9
static void
rwrite(Fcall *f)
{
    Fid *fidp;
    int n;
    char *err, *argv[10];

    fidp = newfid(f->fid);
    if(fidp->node->d.mode & DMDIR) {
        reply(f, "directories are not writable");
        return;
    }
    if(fidp->open == 0) {
        reply(f, "file not open");
        return;
    }

    if (!permitted(fidp, fidp->node, AWRITE)) {
        reply(f, "permission denied");
        return;
    }

    f->data[f->count] = 0;			/* the extra byte in rbuf leaves room */
    n = tokenize(f->data, argv, 10);
    err = 0;
    switch(findkey(argv[0], cmds)) {
    case RELOAD:
        getconf();
        reload();
        break;
    case RDEBUG:
        if(n > 1) {
            debugfd = create(argv[1], OWRITE, 0666);
            if(debugfd < 0)
                err = "create failed";
        } else
            debugfd = 2;
        break;
    case RNODEBUG:
        if(debugfd >= 0)
            close(debugfd);
        debugfd = -1;
        break;
    default:
        err = "unknown command";
        break;
    }
    reply(f, err);
}
示例#11
0
文件: dns.c 项目: 00001/plan9port
Mfile*
copyfid(Mfile *mf, int fid)
{
	Mfile *nmf;

	nmf = newfid(fid, 1);
	if(nmf == nil)
		return nil;
	nmf->fid = fid;
	nmf->user = estrdup(mf->user);
	nmf->qid.type = mf->qid.type;
	nmf->qid.path = mf->qid.path;
	nmf->qid.vers = vers++;
	return nmf;
}
示例#12
0
文件: proto.c 项目: aberg001/plan9
static void
rstat(Fcall *f)
{
    Fid *fidp;

    fidp = newfid(f->fid);
    if (fidp->node->d.type == Dummynode)
        dummy.d.name = fidp->name;
    f->stat = (uchar*)rbuf+4+1+2+2;	/* knows about stat(5) */
    f->nstat = convD2M(&fidp->node->d, f->stat, MAXRPC);
    if(f->nstat <= BIT16SZ)
        reply(f, "ratfs: convD2M");
    else
        reply(f, 0);
    return;
}
示例#13
0
文件: fsys.c 项目: npe9/harvey
static
void
filsysproc(void *arg)
{
	int n;
	Xfid *x;
	Fid *f;
	Fcall t;
	uint8_t *buf;
	Filsys *fs;

	threadsetname("FILSYSPROC");
	fs = arg;
	fs->pid = getpid();
	x = nil;
	for(;;){
		buf = emalloc(messagesize+UTFmax);	/* UTFmax for appending partial rune in xfidwrite */
		n = read9pmsg(fs->sfd, buf, messagesize);
		if(n <= 0){
			yield();	/* if threadexitsall'ing, will not return */
			fprint(2, "rio: %d: read9pmsg: %d %r\n", getpid(), n);
			errorshouldabort = 0;
			error("eof or i/o error on server channel");
		}
		if(x == nil){
			send(fs->cxfidalloc, nil);
			recv(fs->cxfidalloc, &x);
			x->fs = fs;
		}
		x->buf = buf;
		if(convM2S(buf, n, x) != n)
			error("convert error in convM2S");
		if(DEBUG)
			fprint(2, "rio:<-%F\n", &x->Fcall);
		if(fcall[x->type] == nil)
			x = filsysrespond(fs, x, &t, Ebadfcall);
		else{
			if(x->type==Tversion || x->type==Tauth)
				f = nil;
			else
				f = newfid(fs, x->fid);
			x->f = f;
			x  = (*fcall[x->type])(fs, x, f);
		}
		firstmessage = 0;
	}
}
示例#14
0
文件: vacfs.c 项目: 00001/plan9port
void
io(void)
{
	char *err;
	int n;

	for(;;){
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n <= 0)
			break;
		if(convM2S(mdata, n, &rhdr) != n)
			sysfatal("convM2S conversion error");

		if(dflag)
			fprint(2, "vacfs:<-%F\n", &rhdr);

		thdr.data = (char*)mdata + IOHDRSZ;
		if(!fcalls[rhdr.type])
			err = "bad fcall type";
		else
			err = (*fcalls[rhdr.type])(newfid(rhdr.fid));
		if(err){
			thdr.type = Rerror;
			thdr.ename = err;
#ifdef PLAN9PORT
			thdr.errornum = 0;
#endif
		}else{
			thdr.type = rhdr.type + 1;
			thdr.fid = rhdr.fid;
		}
		thdr.tag = rhdr.tag;
		if(dflag)
			fprint(2, "vacfs:->%F\n", &thdr);
		n = convS2M(&thdr, mdata, messagesize);
		if(n <= BIT16SZ)
			sysfatal("convS2M conversion error");
		if(err)
			vtfree(err);

		if(write(mfd[1], mdata, n) != n)
			sysfatal("mount write: %r");
	}
}
示例#15
0
文件: proto.c 项目: aberg001/plan9
/*
 *	only directories can be read.  everthing else returns EOF.
 */
static void
rread(Fcall *f)
{
    long cnt;
    Fid *fidp;

    cnt = f->count;
    f->count = 0;
    fidp = newfid(f->fid);
    f->data = (char*)rbuf+IOHDRSZ;
    if(fidp->open == 0) {
        reply(f, "file not open");
        return;
    }
    if ((fidp->node->d.mode&DMDIR) == 0) {
        reply(f, 0);				/*EOF*/
        return;
    }
    if(cnt > MAXRPC)
        cnt = MAXRPC;

    if(f->offset == 0)
        fidp->dirindex = 0;

    switch(fidp->node->d.type) {
    case Directory:
    case Addrdir:
    case Trusted:
        f->count = dread(fidp, cnt);
        break;
    case IPaddr:
    case Acctaddr:
        f->count = hread(fidp, cnt);
        break;
    default:
        reply(f, "can't read this type of file");
        return;
    }
    reply(f, 0);
}
示例#16
0
Xfid *
setuser(Xfile *xp, char *user)
{
	Xfid *xf, *xpf;
	Session *s;

	xf = xfid(user, xp, 1);
	if(xf->urfid)
		return xf;
	if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */
		return xfid(user, xp, -1);
	s = xp->s;
	xf->urfid = newfid(s);
	xf->urfid->owner = &xf->urfid;
	setfid(s, xpf->urfid);
	s->f.newfid = xf->urfid - s->fids;
	s->f.nwname = 1;
	s->f.wname[0] = xp->name;
	if(xmesg(s, Twalk) || s->f.nwqid != 1)
		return xfid(user, xp, -1);
	return xf;
}
示例#17
0
文件: proto.c 项目: aberg001/plan9
static void
rattach(Fcall *f)
{
    Fid *fidp;
    Dir *d;

    if((d=dirstat(conffile)) != nil && d->mtime > lastconftime)
        getconf();
    free(d);
    if((d=dirstat(ctlfile)) != nil && d->mtime > lastctltime)
        reload();
    free(d);
    cleantrusted();

    fidp = newfid(f->fid);
    fidp->busy = 1;
    fidp->node = root;
    fidp->name = root->d.name;
    fidp->uid = atom(f->uname);
    f->qid = root->d.qid;
    reply(f,0);
}
示例#18
0
文件: proto.c 项目: aberg001/plan9
/*
 *  no files or directories are removable; this becomes clunk;
 */
static void
rremove(Fcall *f)
{
    Fid *fidp;
    Node *dir, *np;

    fidp = newfid(f->fid);

    /*
     * only trusted temporary files can be removed
     * and only by their owner.
     */
    if(fidp->node->d.type != Trustedtemp) {
        reply(f, "can't be removed");
        return;
    }
    if(fidp->uid != fidp->node->d.uid) {
        reply(f, "permission denied");
        return;
    }
    dir = fidp->node->parent;
    for(np = dir->children; np; np = np->sibs)
        if(np->sibs == fidp->node)
            break;
    if(np)
        np->sibs = fidp->node->sibs;
    else
        dir->children = fidp->node->sibs;
    dir->count--;
    free(fidp->node);
    fidp->node = 0;
    fidp->open = 0;
    fidp->busy = 0;
    fidp->name = 0;
    fidp->uid = 0;
    reply(f, 0);
}
示例#19
0
文件: vacfs.c 项目: npe9/harvey
char*
rwalk(Fid *f)
{
	VacFile *file, *nfile;
	Fid *nf;
	int nqid, nwname;
	Qid qid;
	char *err = nil;

	if(f->busy == 0)
		return Enotexist;
	nf = nil;
	if(rhdr.fid != rhdr.newfid){
		if(f->open)
			return vtstrdup(Eisopen);
		if(f->busy == 0)
			return vtstrdup(Enotexist);
		nf = newfid(rhdr.newfid);
		if(nf->busy)
			return vtstrdup(Eisopen);
		nf->busy = 1;
		nf->open = 0;
		nf->qid = f->qid;
		nf->file = vacfileincref(f->file);
		nf->user = vtstrdup(f->user);
		f = nf;
	}

	nwname = rhdr.nwname;

	/* easy case */
	if(nwname == 0) {
		thdr.nwqid = 0;
		return 0;
	}

	file = f->file;
	vacfileincref(file);
	qid = f->qid;

	for(nqid = 0; nqid < nwname; nqid++){
		if((qid.type & QTDIR) == 0){
			err = Enotdir;
			break;
		}
		if(!permf(file, f->user, Pexec)) {
			err = Eperm;
			break;
		}
		nfile = vacfilewalk(file, rhdr.wname[nqid]);
		if(nfile == nil)
			break;
		vacfiledecref(file);
		file = nfile;
		qid.type = QTFILE;
		if(vacfileisdir(file))
			qid.type = QTDIR;
		qid.vers = vacfilegetmcount(file);
		qid.path = vacfilegetid(file);
		thdr.wqid[nqid] = qid;
	}

	thdr.nwqid = nqid;

	if(nqid == nwname){
		/* success */
		f->qid = thdr.wqid[nqid-1];
		vacfiledecref(f->file);
		f->file = file;
		return 0;
	}

	vacfiledecref(file);
	if(nf != nil)
		rclunk(nf);

	/* only error on the first element */
	if(nqid == 0)
		return vtstrdup(err);

	return 0;
}
示例#20
0
文件: fs.c 项目: 00001/plan9port
char*
rwalk(Fid *f)
{
	Fid *nf;
	Ram *r;
	char *err;
	char *name;
	Ram *dir;
	int i;

	nf = nil;
	if(f->ram->busy == 0)
		return Enotexist;
	if(f->open)
		return Eisopen;
	if(rhdr.newfid != rhdr.fid){
		nf = newfid(rhdr.newfid);
		nf->busy = 1;
		nf->open = 0;
		nf->rclose = 0;
		nf->ram = f->ram;
		nf->user = f->user;	/* no ref count; the leakage is minor */
		f = nf;
	}

	thdr.nwqid = 0;
	err = nil;
	r = f->ram;

	if(rhdr.nwname > 0){
		for(i=0; i<rhdr.nwname; i++){
			if((r->qid.type & QTDIR) == 0){
				err = Enotdir;
				break;
			}
			if(r->busy == 0){
				err = Enotexist;
				break;
			}
			r->atime = time(0);
			name = rhdr.wname[i];
			dir = r;
			if(!perm(Pexec)){
				err = Eperm;
				break;
			}
			if(strcmp(name, "..") == 0){
				r = dir->parent;
   Accept:
				if(i == MAXWELEM){
					err = "name too long";
					break;
				}
 				thdr.wqid[thdr.nwqid++] = r->qid;
				continue;
			}
			if(!dir->replete)
				popdir(dir);
			for(r=dir->child; r; r=r->next)
				if(r->busy && strcmp(name, r->name)==0)
					goto Accept;
			break;	/* file not found */
		}

		if(i==0 && err == nil)
			err = Enotexist;
	}

	if(err!=nil || thdr.nwqid<rhdr.nwname){
		if(nf){
			nf->busy = 0;
			nf->open = 0;
			nf->ram = 0;
		}
	}else if(thdr.nwqid  == rhdr.nwname)
		f->ram = r;

	return err;

}
示例#21
0
文件: fsys.c 项目: npe9/harvey
static
Xfid*
filsyswalk(Filsys *fs, Xfid *x, Fid *f)
{
	Fcall t;
	Fid *nf;
	int i, id;
	uint8_t type;
	uint32_t path;
	Dirtab *d, *dir;
	Window *w;
	char *err;
	Qid qid;

	if(f->open)
		return filsysrespond(fs, x, &t, "walk of open file");
	nf = nil;
	if(x->fid  != x->newfid){
		/* BUG: check exists */
		nf = newfid(fs, x->newfid);
		if(nf->busy)
			return filsysrespond(fs, x, &t, "clone to busy fid");
		nf->busy = TRUE;
		nf->open = FALSE;
		nf->dir = f->dir;
		nf->qid = f->qid;
		nf->w = f->w;
		incref(f->w);
		nf->nrpart = 0;	/* not open, so must be zero */
		f = nf;	/* walk f */
	}

	t.nwqid = 0;
	err = nil;

	/* update f->qid, f->dir only if walk completes */
	qid = f->qid;
	dir = f->dir;

	if(x->nwname > 0){
		for(i=0; i<x->nwname; i++){
			if((qid.type & QTDIR) == 0){
				err = Enotdir;
				break;
			}
			if(strcmp(x->wname[i], "..") == 0){
				type = QTDIR;
				path = Qdir;
				dir = dirtab;
				if(FILE(qid) == Qwsysdir)
					path = Qwsys;
				id = 0;
    Accept:
				if(i == MAXWELEM){
					err = "name too long";
					break;
				}
				qid.type = type;
				qid.vers = 0;
				qid.path = QID(id, path);
				t.wqid[t.nwqid++] = qid;
				continue;
			}

			if(qid.path == Qwsys){
				/* is it a numeric name? */
				if(!numeric(x->wname[i]))
					break;
				/* yes: it's a directory */
				id = atoi(x->wname[i]);
				qlock(&all);
				w = wlookid(id);
				if(w == nil){
					qunlock(&all);
					break;
				}
				path = Qwsysdir;
				type = QTDIR;
				qunlock(&all);
				incref(w);
				sendp(winclosechan, f->w);
				f->w = w;
				dir = dirtab;
				goto Accept;
			}
		
			if(snarffd>=0 && strcmp(x->wname[i], "snarf")==0)
				break;	/* don't serve /dev/snarf if it's provided in the environment */
			id = WIN(f->qid);
			d = dirtab;
			d++;	/* skip '.' */
			for(; d->name; d++)
				if(strcmp(x->wname[i], d->name) == 0){
					path = d->qid;
					type = d->type;
					dir = d;
					goto Accept;
				}

			break;	/* file not found */
		}

		if(i==0 && err==nil)
			err = Eexist;
	}

	if(err!=nil || t.nwqid<x->nwname){
		if(nf){
			if(nf->w)
				sendp(winclosechan, nf->w);
			nf->open = FALSE;
			nf->busy = FALSE;
		}
	}else if(t.nwqid == x->nwname){
		f->dir = dir;
		f->qid = qid;
	}

	return filsysrespond(fs, x, &t, err);
}
示例#22
0
文件: dns.c 项目: Earnestly/plan9
void
io(void)
{
	volatile long n;
	volatile uchar mdata[IOHDRSZ + Maxfdata];
	Job *volatile job;
	Mfile *volatile mf;
	volatile Request req;

	memset(&req, 0, sizeof req);
	/*
	 *  a slave process is sometimes forked to wait for replies from other
	 *  servers.  The master process returns immediately via a longjmp
	 *  through 'mret'.
	 */
	if(setjmp(req.mret))
		putactivity(0);
	req.isslave = 0;
	stop = 0;
	while(!stop){
		procsetname("%d %s/dns Twrites of %d 9p rpcs read; %d alarms",
			stats.qrecvd9p, mntpt, stats.qrecvd9prpc, stats.alarms);
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n<=0){
			dnslog("error reading 9P from %s: %r", mntpt);
			sleep(2000);	/* don't thrash after read error */
			return;
		}

		stats.qrecvd9prpc++;
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			freejob(job);
			continue;
		}
		mf = newfid(job->request.fid, 0);
		if(debug)
			dnslog("%F", &job->request);

		getactivity(&req, 0);
		req.aborttime = timems() + Maxreqtm;
		req.from = "9p";

		switch(job->request.type){
		default:
			warning("unknown request type %d", job->request.type);
			break;
		case Tversion:
			rversion(job);
			break;
		case Tauth:
			rauth(job);
			break;
		case Tflush:
			rflush(job);
			break;
		case Tattach:
			rattach(job, mf);
			break;
		case Twalk:
			rwalk(job, mf);
			break;
		case Topen:
			ropen(job, mf);
			break;
		case Tcreate:
			rcreate(job, mf);
			break;
		case Tread:
			rread(job, mf);
			break;
		case Twrite:
			/* &req is handed to dnresolve() */
			rwrite(job, mf, &req);
			break;
		case Tclunk:
			rclunk(job, mf);
			break;
		case Tremove:
			rremove(job, mf);
			break;
		case Tstat:
			rstat(job, mf);
			break;
		case Twstat:
			rwstat(job, mf);
			break;
		}

		freejob(job);

		/*
		 *  slave processes die after replying
		 */
		if(req.isslave){
			putactivity(0);
			_exits(0);
		}

		putactivity(0);
	}
	/* kill any udp server, notifier, etc. processes */
	postnote(PNGROUP, getpid(), "die");
	sleep(1000);
}
示例#23
0
/* returns 0 if auth succeeded (or unneeded), -1 otherwise */
int
authhostowner(Session *s)
{
	Fid *af, *f;
	int rv = -1;
	int afd;
	AuthInfo *ai;
	AuthRpc *rpc;

	/* get a fid to authenticate over */
	f = nil;
	af = newfid(s);
	s->f.afid = af - s->fids;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tauth)){
		/* not needed */
		rv = 0;
		goto out;
	}

	quotefmtinstall();	/* just in case */

	afd = open("/mnt/factotum/rpc", ORDWR);
	if(afd < 0){
		werrstr("opening /mnt/factotum/rpc: %r");
		goto out;
	}

	rpc = auth_allocrpc(afd);
	if(rpc == nil)
		goto out;

	ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client");
	if(ai != nil){
		rv = 0;
		auth_freeAI(ai);
	}
	auth_freerpc(rpc);
	close(afd);

	/* try attaching with the afid */
	chat("attaching as hostowner...");
	f = newfid(s);
	s->f.fid = f - s->fids;
	s->f.afid = af - s->fids;;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tattach) == 0)
		rv = 0;
out:
	if(af != nil){
		putfid(s, af);
		s->f.fid = af - s->fids;
		xmesg(s, Tclunk);
	}
	if(f != nil){
		putfid(s, f);
		s->f.fid = f - s->fids;
		xmesg(s, Tclunk);
	}

	return rv;
}
示例#24
0
文件: dns.c 项目: 00001/plan9port
void
ioproc0(void *v)
{
	long n;
	Mfile *mf;
	uchar mdata[IOHDRSZ + Maxfdata];
	Request req;
	Job *job;

	USED(v);

	for(;;){
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n <= 0){
			syslog(0, logfile, "error reading mntpt: %r");
			break;
		}
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			freejob(job);
			continue;
		}
		if(debug)
			syslog(0, logfile, "%F", &job->request);

		getactivity(&req);
		req.aborttime = now + 60;	/* don't spend more than 60 seconds */

		mf = nil;
		switch(job->request.type){
		case Tversion:
		case Tauth:
		case Tflush:
			break;
		case Tattach:
			mf = newfid(job->request.fid, 1);
			if(mf == nil){
				sendmsg(job, "fid in use");
				goto skip;
			}
			break;
		default:
			mf = newfid(job->request.fid, 0);
			if(mf == nil){
				sendmsg(job, "unknown fid");
				goto skip;
			}
			break;
		}

		switch(job->request.type){
		default:
			syslog(1, logfile, "unknown request type %d", job->request.type);
			break;
		case Tversion:
			rversion(job);
			break;
		case Tauth:
			rauth(job);
			break;
		case Tflush:
			rflush(job);
			break;
		case Tattach:
			rattach(job, mf);
			break;
		case Twalk:
			rwalk(job, mf);
			break;
		case Topen:
			ropen(job, mf);
			break;
		case Tcreate:
			rcreate(job, mf);
			break;
		case Tread:
			rread(job, mf);
			break;
		case Twrite:
			rwrite(job, mf, &req);
			break;
		case Tclunk:
			rclunk(job, mf);
			break;
		case Tremove:
			rremove(job, mf);
			break;
		case Tstat:
			rstat(job, mf);
			break;
		case Twstat:
			rwstat(job, mf);
			break;
		}
skip:
		freejob(job);
		putactivity();
	}
}
示例#25
0
文件: nfsmount.c 项目: 99years/plan9
void
srvinit(int fd, char *file, char *addr)
{
	char fdservice[16], *naddr;
	Session *s;
	Xfile *xp;
	Xfid *xf;
	Fid *f;

	s = calloc(1, sizeof(Session));
	s->spec = "";
	s->fd = -1;
	if(fd >= 0){
		s->fd = fd;
		sprint(fdservice, "/fd/%d", s->fd);
		s->service = strstore(fdservice);
		chat("fd = %d\n", s->fd);
	}else if(file){
		chat("file = \"%s\"\n", file);
		s->service = file;
		s->fd = open(file, ORDWR);
		if(s->fd < 0){
			clog("can't open %s: %r\n", file);
			goto error;
		}
	}else if(addr){
		chat("addr = \"%s\"\n", addr);
		naddr = netmkaddr(addr, 0, "9fs");
		s->service = addr;
		s->fd = dial(naddr, 0, 0, 0);
		if(s->fd < 0){
			clog("can't dial %s: %r\n", naddr);
			goto error;
		}
	}

	chat("version...");
	s->tag = NOTAG-1;
	s->f.msize = Maxfdata+IOHDRSZ;
	s->f.version = "9P2000";
	xmesg(s, Tversion);
	messagesize = IOHDRSZ+s->f.msize;
	chat("version spec %s size %d\n", s->f.version, s->f.msize);

	s->tag = 0;

	chat("authenticate...");
	if(authhostowner(s) < 0){
		clog("auth failed %r\n");
		goto error;
	}

	chat("attach as none...");
	f = newfid(s);
	s->f.fid = f - s->fids;
	s->f.afid = ~0x0UL;
	s->f.uname = "none";
	s->f.aname = s->spec;
	if(xmesg(s, Tattach)){
		clog("attach failed\n");
		goto error;
	}

	xp = xfile(&s->f.qid, s, 1);
	s->root = xp;
	xp->parent = xp;
	xp->name = "/";
	xf = xfid("none", xp, 1);
	xf->urfid = f;
	clog("service=%s uid=%s fid=%ld\n",
		s->service, xf->uid, xf->urfid - s->fids);
	if(tail)
		tail->next = s;
	else
		head = s;
	tail = s;
	return;

error:
	if(s->fd >= 0)
		close(s->fd);
	free(s);
}
示例#26
0
文件: cs.c 项目: brho/akaros
static void *job_thread(void *arg)
{
	struct mfile *mf;
	struct job *job = arg;

	spinlock_lock(&dblock);
	mf = newfid(job->request.fid);

	if (debug)
		fprintf(stderr, "CS:%F", &job->request);
	switch (job->request.type) {
	default:
		fprintf(stderr, "CS:unknown request type %d", job->request.type);
		break;
	case Tversion:
		rversion(job);
		break;
	case Tauth:
		rauth(job);
		break;
	case Tflush:
		rflush(job);
		break;
	case Tattach:
		rattach(job, mf);
		break;
	case Twalk:
		rwalk(job, mf);
		break;
	case Topen:
		ropen(job, mf);
		break;
	case Tcreate:
		rcreate(job, mf);
		break;
	case Tread:
		rread(job, mf);
		break;
	case Twrite:
		rwrite(job, mf);
		break;
	case Tclunk:
		rclunk(job, mf);
		break;
	case Tremove:
		rremove(job, mf);
		break;
	case Tstat:
		rstat(job, mf);
		break;
	case Twstat:
		rwstat(job, mf);
		break;
	}
	spinlock_unlock(&dblock);

	freejob(job);

	if (debug)
		fprintf(stderr, "CS:Job done\n");
	return 0;
}
示例#27
0
文件: fsys.c 项目: npe9/harvey
static
Xfid*
fsyswalk(Xfid *x, Fid *f)
{
    Fcall t;
    int c, i, j, id;
    Qid q;
    uint8_t type;
    uint32_t path;
    Fid *nf;
    Dirtab *d, *dir;
    Window *w;
    char *err;

    nf = nil;
    w = nil;
    if(f->open)
        return respond(x, &t, "walk of open file");
    if(x->fid != x->newfid) {
        nf = newfid(x->newfid);
        if(nf->busy)
            return respond(x, &t, "newfid already in use");
        nf->busy = TRUE;
        nf->open = FALSE;
        nf->mntdir = f->mntdir;
        if(f->mntdir)
            f->mntdir->ref++;
        nf->dir = f->dir;
        nf->qid = f->qid;
        nf->w = f->w;
        nf->nrpart = 0;	/* not open, so must be zero */
        if(nf->w)
            incref(nf->w);
        f = nf;	/* walk f */
    }

    t.nwqid = 0;
    err = nil;
    dir = nil;
    id = WIN(f->qid);
    q = f->qid;

    if(x->nwname > 0) {
        for(i=0; i<x->nwname; i++) {
            if((q.type & QTDIR) == 0) {
                err = Enotdir;
                break;
            }

            if(strcmp(x->wname[i], "..") == 0) {
                type = QTDIR;
                path = Qdir;
                id = 0;
                if(w) {
                    winclose(w);
                    w = nil;
                }
Accept:
                if(i == MAXWELEM) {
                    err = "name too long";
                    break;
                }
                q.type = type;
                q.vers = 0;
                q.path = QID(id, path);
                t.wqid[t.nwqid++] = q;
                continue;
            }

            /* is it a numeric name? */
            for(j=0; (c=x->wname[i][j]); j++)
                if(c<'0' || '9'<c)
                    goto Regular;
            /* yes: it's a directory */
            if(w)	/* name has form 27/23; get out before losing w */
                break;
            id = atoi(x->wname[i]);
            qlock(&row);
            w = lookid(id, FALSE);
            if(w == nil) {
                qunlock(&row);
                break;
            }
            incref(w);	/* we'll drop reference at end if there's an error */
            path = Qdir;
            type = QTDIR;
            qunlock(&row);
            dir = dirtabw;
            goto Accept;

Regular:
//			if(FILE(f->qid) == Qacme)	/* empty directory */
//				break;
            if(strcmp(x->wname[i], "new") == 0) {
                if(w)
                    error("w set in walk to new");
                sendp(cnewwindow, nil);	/* signal newwindowthread */
                w = recvp(cnewwindow);	/* receive new window */
                incref(w);
                type = QTDIR;
                path = QID(w->id, Qdir);
                id = w->id;
                dir = dirtabw;
                goto Accept;
            }

            if(id == 0)
                d = dirtab;
            else
                d = dirtabw;
            d++;	/* skip '.' */
            for(; d->name; d++)
                if(strcmp(x->wname[i], d->name) == 0) {
                    path = d->qid;
                    type = d->type;
                    dir = d;
                    goto Accept;
                }

            break;	/* file not found */
        }

        if(i==0 && err == nil)
            err = Eexist;
    }

    if(err!=nil || t.nwqid<x->nwname) {
        if(nf) {
            nf->busy = FALSE;
            fsysdelid(nf->mntdir);
        }
    } else if(t.nwqid  == x->nwname) {
        if(w) {
            f->w = w;
            w = nil;	/* don't drop the reference */
        }
        if(dir)
            f->dir = dir;
        f->qid = q;
    }

    if(w != nil)
        winclose(w);

    return respond(x, &t, err);
}
示例#28
0
文件: cs.c 项目: brho/akaros
static char *rwalk(struct job *job, struct mfile *mf)
{
	char *err;
	char **elems;
	int nelems;
	int i;
	struct mfile *nmf;
	struct qid qid;

	err = 0;
	nmf = NULL;
	elems = job->request.wname;
	nelems = job->request.nwname;
	job->reply.nwqid = 0;

	if (job->request.newfid != job->request.fid) {
		/* clone fid */
		nmf = newfid(job->request.newfid);
		if (nmf->busy) {
			nmf = NULL;
			err = "clone to used channel";
			goto send;
		}
		*nmf = *mf;
		nmf->user = estrdup(mf->user);
		nmf->fid = job->request.newfid;
		nmf->qid.vers = vers++;
		mf = nmf;
	}
	/* else nmf will be nil */

	qid = mf->qid;
	if (nelems > 0) {
		/* walk fid */
		for (i = 0; i < nelems && i < MAXWELEM; i++) {
			if ((qid.type & QTDIR) == 0) {
				err = "not a directory";
				break;
			}
			if (strcmp(elems[i], "..") == 0
			    || strcmp(elems[i], ".") == 0) {
				qid.type = QTDIR;
				qid.path = Qdir;
Found:
				job->reply.wqid[i] = qid;
				job->reply.nwqid++;
				continue;
			}
			if (strcmp(elems[i], "cs") == 0) {
				qid.type = QTFILE;
				qid.path = Qcs;
				goto Found;
			}
			err = "file does not exist";
			break;
		}
	}

send:
	if (nmf != NULL && (err != NULL || job->reply.nwqid < nelems)) {
		cleanmf(nmf);
		free(nmf->user);
		nmf->user = 0;
		nmf->busy = 0;
		nmf->fid = 0;
	}
	if (err == NULL)
		mf->qid = qid;
	sendmsg(job, err);
	return err;
}