Пример #1
0
static long
dsoconcatread(MyFiles *f, void *a, long n, vlong offset){
	int nfiles = f->nfiles;
	long leido = 0, aux_leido;
	vlong newoff = offset;
	Dir* fs;
	int tamb = 1024;
	int i = 0, j;
	long toread;
	uchar* buffer = (uchar*)malloc(sizeof(uchar)*tamb);

	// Posicionamos el offset
	
	Chan* file = f->files[i];

	if (offset >= f->size)
		return 0;
	if ((offset + n) > f->size)
		n = f->size - offset;
	if (n == 0)
		return 0;

	fs = &(f->info[i]);

	devtab[file->type]->stat(file,buffer,tamb);
	convM2D(buffer, tamb, fs, 0);

	for(; (newoff > fs->length) && (i < nfiles);){
		newoff -= fs->length;
		file = f->files[++i];
		devtab[file->type]->stat(file,buffer,tamb);
		convM2D(buffer, tamb, fs, 0);
	}

	// Vamos leyendo hasta terminar
	if(i < nfiles){
		toread = fs->length - newoff;
		leido += devtab[file->type]->read(file, a, toread, newoff);
		a = (char*)a + leido;
		for(j = i+1; (leido < n) && (j < nfiles); j++){
			file = f->files[j];
			fs = &(f->info[j]);
			devtab[file->type]->stat(file,buffer,tamb);
			convM2D(buffer, tamb, fs, 0);	

			if((leido + fs->length) < n)
				toread = fs->length;
			else
				toread = n-leido; 

			aux_leido = devtab[file->type]->read(file, a, toread, 0);
			
			a = (char*)a + aux_leido;
			leido += aux_leido;
		}
	}

	return leido;
}
Пример #2
0
void
setswapchan(Chan *c)
{
	uchar dirbuf[sizeof(Dir)+100];
	Dir d;
	int n;

	if(swapimage.c) {
		if(swapalloc.free != conf.nswap){
			cclose(c);
			error(Einuse);
		}
		cclose(swapimage.c);
	}

	/*
	 *  if this isn't a file, set the swap space
	 *  to be at most the size of the partition
	 */
	if(devtab[c->type]->dc != L'M'){
		n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
		if(n <= 0){
			cclose(c);
			error("stat failed in setswapchan");
		}
		convM2D(dirbuf, n, &d, nil);
		if(d.length < conf.nswap*BY2PG){
			conf.nswap = d.length/BY2PG;
			swapalloc.top = &swapalloc.swmap[conf.nswap];
			swapalloc.free = conf.nswap;
		}
	}

	swapimage.c = c;
}
Пример #3
0
static int
sdwstat(Chan* c, uchar* dp, int n)
{
	Dir *d;
	SDpart *pp;
	SDperm *perm;
	SDunit *unit;
	SDev *sdev;

	if(c->qid.type & QTDIR)
		error(Eperm);

	sdev = sdgetdev(DEV(c->qid));
	if(sdev == nil)
		error(Enonexist);
	unit = sdev->unit[UNIT(c->qid)];
	qlock(&unit->ctl);
	d = nil;
	if(waserror()){
		free(d);
		qunlock(&unit->ctl);
		decref(&sdev->r);
		nexterror();
	}

	switch(TYPE(c->qid)){
	default:
		error(Eperm);
	case Qctl:
		perm = &unit->ctlperm;
		break;
	case Qraw:
		perm = &unit->rawperm;
		break;
	case Qpart:
		pp = &unit->part[PART(c->qid)];
		if(unit->vers+pp->vers != c->qid.vers)
			error(Enonexist);
		perm = &pp->SDperm;
		break;
	}

	if(strcmp(up->env->user, perm->user) && !iseve())
		error(Eperm);

	d = smalloc(sizeof(Dir)+n);
	n = convM2D(dp, n, &d[0], (char*)&d[1]);
	if(n == 0)
		error(Eshortstat);
	if(!emptystr(d[0].uid))
		kstrdup(&perm->user, d[0].uid);
	if(d[0].mode != ~0UL)
		perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777);

	free(d);
	qunlock(&unit->ctl);
	decref(&sdev->r);
	poperror();
	return n;
}
Пример #4
0
static int
progwstat(Chan *c, uchar *db, int n)
{
	Dir d;
	Prog *p;
	char *u;
	Osenv *o;

	if(c->qid.type&QTDIR)
		error(Eperm);
	acquire();
	p = progpid(PID(c->qid));
	if(p == nil) {
		release();
		error(Ethread);
	}

	u = up->env->user;
	o = p->osenv;
	if(strcmp(u, o->user) != 0 && strcmp(u, eve) != 0) {
		release();
		error(Eperm);
	}

	n = convM2D(db, n, &d, nil);
	if(n == 0){
		release();
		error(Eshortstat);
	}
	if(d.mode != ~0UL)
		o->pgrp->progmode = d.mode&0777;
	release();
	return n;
}
Пример #5
0
static long
dsopartwrite(MyFiles *f, void *a, long n, vlong offset){
	Chan* file = f->files[0];
	int tamb = 1024;
	Dir* fs;
	int r;
	uchar* buffer = (uchar*)malloc(sizeof(uchar)*tamb);

	if (offset >= f->size)
		return 0;
	if ((offset + n) > f->size)
		n = f->size - offset;
	if (n == 0)
		return 0;

	r = devtab[file->type]->write(file, a, n, (offset + f->offset));

	fs = &(f->info[0]);

	devtab[file->type]->stat(file,buffer,tamb);
	convM2D(buffer, tamb, fs, 0);
	f->mdate[0] = fs->mtime;

	return r;
}
Пример #6
0
static int
segmentwstat(Chan *c, uchar *dp, int n)
{
	Globalseg *g;
	Dir *d;

	if(c->qid.type == QTDIR)
		error(Eperm);

	g = getgseg(c);
	if(waserror()){
		putgseg(g);
		nexterror();
	}

	if(strcmp(g->uid, up->user) && !iseve())
		error(Eperm);
	d = smalloc(sizeof(Dir)+n);
	n = convM2D(dp, n, &d[0], (char*)&d[1]);
	g->perm = d->mode & 0777;

	putgseg(g);
	poperror();

	free(d);
	return n;
}
Пример #7
0
static int
ipwstat(Chan *c, uchar *dp, int n)
{
	Dir d;
	Conv *cv;
	Fs *f;
	Proto *p;

	f = ipfs[c->dev];
	switch(TYPE(c->qid)) {
	default:
		error(Eperm);
		break;
	case Qctl:
	case Qdata:
		break;
	}

	n = convM2D(dp, n, &d, nil);
	if(n > 0){
		p = f->p[PROTO(c->qid)];
		cv = p->conv[CONV(c->qid)];
		if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
			error(Eperm);
		if(d.uid[0])
			kstrdup(&cv->owner, d.uid);
		cv->perm = d.mode & 0777;
	}
	return n;
}
Пример #8
0
int32_t
netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n)
{
	Proc *up = externup();
	Dir *dir;
	Netfile *f;
	int l;

	f = nif->f[NETID(c->qid.path)];
	if(f == 0)
		error(Enonexist);

	if(netown(f, up->user, OWRITE) < 0)
		error(Eperm);

	dir = smalloc(sizeof(Dir)+n);
	l = convM2D(db, n, &dir[0], (char*)&dir[1]);
	if(l == 0){
		free(dir);
		error(Eshortstat);
	}
	if(!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if(dir[0].mode != (uint32_t)~0UL)
		f->mode = dir[0].mode;
	free(dir);
	return l;
}
Пример #9
0
static int pipewstat(struct chan *c, uint8_t *dp, int n)
{
	ERRSTACK(2);
	struct dir *d;
	Pipe *p;
	int d1;

	if (c->qid.type & QTDIR)
		error(EPERM, ERROR_FIXME);
	p = c->aux;
	if (strcmp(current->user, p->user) != 0)
		error(EPERM, ERROR_FIXME);
	d = kzmalloc(sizeof(*d) + n, 0);
	if (waserror()) {
		kfree(d);
		nexterror();
	}
	n = convM2D(dp, n, d, (char *)&d[1]);
	if (n == 0)
		error(ENODATA, ERROR_FIXME);
	d1 = NETTYPE(c->qid.path) == Qdata1;
	if (!emptystr(d->name)) {
		validwstatname(d->name);
		if (strlen(d->name) >= KNAMELEN)
			error(ENAMETOOLONG, ERROR_FIXME);
		if (strncmp(p->pipedir[1 + !d1].name, d->name, KNAMELEN) == 0)
			error(EEXIST, ERROR_FIXME);
		strncpy(p->pipedir[1 + d1].name, d->name, KNAMELEN);
	}
	if (d->mode != ~0UL)
		p->pipedir[d1 + 1].perm = d->mode & 0777;
	poperror();
	kfree(d);
	return n;
}
Пример #10
0
/* must call with c qlocked */
static void
identify(Ctlr *c, SDunit *u)
{
	int n;
	uvlong s, osectors;
	uchar buf[sizeof(Dir) + 100];
	Dir dir;

	if(waserror()){
		iprint("sdloop: identify: %s\n", up->errstr);
		nexterror();
	}
	osectors = c->sectors;
	n = devtab[c->c->type]->stat(c->c, buf, sizeof buf);
	if(convM2D(buf, n, &dir, nil) == 0)
		error("internal error: stat error in seek");
	s = dir.length / c->sectsize;
	poperror();

	memset(u->inquiry, 0, sizeof u->inquiry);
	u->inquiry[2] = 2;
	u->inquiry[3] = 2;
	u->inquiry[4] = sizeof u->inquiry - 4;
	memmove(u->inquiry+8, c->path, 40);

	if(osectors == 0 || osectors != s){
		c->sectors = s;
		c->drivechange = 1;
		c->vers++;
	}
}
Пример #11
0
long
sys_stat(uint32 *arg)
{
	Chan *c;
	uint l;
	uchar buf[128];	/* old DIRLEN plus a little should be plenty */
	char strs[128], *name, *elem;
	Dir d;
	char old[] = "old stat system call - recompile";
	uchar *p;

	p = uvalidaddr(arg[1], 116, 1);
	name = uvalidaddr(arg[0], 1, 0);
	c = namec(name, Aaccess, 0, 0);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	l = devtab[c->type]->stat(c, buf, sizeof buf);
	/* buf contains a new stat buf; convert to old. yuck. */
	if(l <= BIT16SZ)	/* buffer too small; time to face reality */
		error(old);
	elem = pathlast(c->path);
	if(elem)
		l = dirsetname(elem, strlen(elem), buf, l, sizeof buf);
	l = convM2D(buf, l, &d, strs);
	if(l == 0)
		error(old);
	packoldstat(p, &d);
	
	poperror();
	cclose(c);
	return 0;
}
Пример #12
0
Dir*
dirfstat(int fd)
{
	Dir *d;
	uint8_t *buf;
	int n, nd, i;

	nd = DIRSIZE;
	for(i=0; i<2; i++){	/* should work by the second try */
		d = malloc(sizeof(Dir) + BIT16SZ + nd);
		if(d == nil)
			return nil;
		buf = (uint8_t*)&d[1];
		n = fstat(fd, buf, BIT16SZ+nd);
		if(n < BIT16SZ){
			free(d);
			return nil;
		}
		nd = GBIT16(buf);	/* upper bound on size of Dir + strings */
		if(nd <= n){
			convM2D(buf, n, d, (char*)&d[1]);
			return d;
		}
		/* else sizeof(Dir)+BIT16SZ+nd is plenty */
		free(d);
	}
	return nil;
}
Пример #13
0
/*
 * Cannot error.
 * Check that unit is online.
 * If media changed, return 2.
 * If ready, return 1.
 * If not ready, return 0.
 */
static int
looponline(SDunit *unit)
{
	uchar buf[sizeof(Dir)+100];
	Chan *c;
	SDev *sdev;
	Ctlr *ctlr;
	Dir dir;
	long n;
	
	if(waserror())
		return 0;

	sdev = unit->dev;
	ctlr = sdev->ctlr;
	c = ctlr->c;
	n = devtab[c->type]->stat(c, buf, sizeof buf);
	if(convM2D(buf, n, &dir, nil) == 0)
		error("internal error: stat error in looponline");
	if(ctlr->qidpath != dir.qid.path){
		unit->sectors = dir.length/512;
		unit->secsize = 512;
		ctlr->qidpath = dir.qid.path;
		poperror();
		return 2;
	}
	poperror();
	return 1;
}
Пример #14
0
long
sys_fstat(ulong *arg)
{
	Chan *c;
	char *name;
	uint l;
	uchar buf[128];	/* old DIRLEN plus a little should be plenty */
	char strs[128];
	Dir d;
	char old[] = "old fstat system call - recompile";

	validaddr(arg[1], 116, 1);
	c = fdtochan(arg[0], -1, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	l = devtab[c->type]->stat(c, buf, sizeof buf);
	/* buf contains a new stat buf; convert to old. yuck. */
	if(l <= BIT16SZ)	/* buffer too small; time to face reality */
		error(old);
	name = pathlast(c->path);
	if(name)
		l = dirsetname(name, strlen(name), buf, l, sizeof buf);
	l = convM2D(buf, l, &d, strs);
	if(l == 0)
		error(old);
	packoldstat((uchar*)arg[1], &d);
	
	poperror();
	cclose(c);
	return 0;
}
Пример #15
0
__private_extern__ int
stat_9p(mount_9p *nmp, fid_9p fid, dir_9p **dpp)
{
	Fcall tx, rx;
	Dir *dp;
	void *p;
	int e, n;
	
	TRACE();
	p = NULL;
	dp = NULL;
	tx.type = Tstat;
	tx.fid = fid;
	if ((e=rpc_9p(nmp, &tx, &rx, &p)))
		return e;

	n = GBIT16((uint8_t*)p);
	dp = malloc_9p(sizeof(Dir) + BIT16SZ + n);
	if (dp == NULL) {
		e = ENOMEM;
		goto error;
	}

	if(convM2D(rx.stat, rx.nstat, dp, (char*)&dp[1], ISSET(nmp->flags, F_DOTU)) != rx.nstat) {
		DEBUG("convM2D");
		e = EBADRPC;
		goto error;
	}

error:
	free_9p(p);
	*dpp = dp;
	return e;
}
Пример #16
0
static int rootwstat(struct chan *c, uint8_t *m_buf, int m_buf_sz)
{
	struct dirtab *file = &roottab[c->qid.path];
	struct dir *dir;
	int m_sz;

	/* TODO: some security check, Eperm on error */

	/* common trick in wstats.  we want the dir and any strings in the M.  the
	 * strings are smaller than entire M (strings plus other M).  the strings
	 * will be placed right after the dir (dir[1]) */
	dir = kzmalloc(sizeof(struct dir) + m_buf_sz, KMALLOC_WAIT);
	m_sz = convM2D(m_buf, m_buf_sz, &dir[0], (char*)&dir[1]);
	if (!m_sz) {
		kfree(dir);
		error(ENODATA, ERROR_FIXME);
	}
	/* TODO: handle more things than just the mode */
	if (!emptystr(dir->name))
		printk("[%s] attempted rename of %s to %s\n", __FUNCTION__,
		       file->name, dir->name);	/* strncpy for this btw */
	if (dir->mode != ~0UL)
		file->perm = dir->mode | (file->qid.type == QTDIR ? DMDIR : 0);
	kfree(dir);
	return m_sz;
}
Пример #17
0
static long
segmentwstat(Chan *c, uchar *dp, long n)
{
	Globalseg *g;
	Dir *d;

	if(c->qid.type == QTDIR)
		error(Eperm);

	g = getgseg(c);
	if(waserror()){
		putgseg(g);
		nexterror();
	}

	if(strcmp(g->uid, up->user)!=0 && !iseve())
		error(Eperm);
	d = smalloc(sizeof(Dir)+n);
	if(waserror()){
		free(d);
		nexterror();
	}
	n = convM2D(dp, n, &d[0], (char*)&d[1]);
	if(!emptystr(d->uid) && strcmp(d->uid, g->uid) != 0)
		kstrdup(&g->uid, d->uid);
	if(d->mode != ~0UL)
		g->perm = d->mode & 0777;
	poperror();
	free(d);

	poperror();
	putgseg(g);

	return n;
}
Пример #18
0
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
{
	struct dir *dir;
	struct netfile *f;
	int m;

	f = nif->f[NETID(c->qid.path)];
	if (f == 0) {
		set_errno(ENOENT);
		error(Enonexist);
	}

	if (netown(f, current->user, OWRITE) < 0)
		error(Eperm);

	dir = kzmalloc(sizeof(struct dir) + n, 0);
	m = convM2D(db, n, &dir[0], (char *)&dir[1]);
	if (m == 0) {
		kfree(dir);
		error(Eshortstat);
	}
	if (!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if (dir[0].mode != ~0UL)
		f->mode = dir[0].mode;
	kfree(dir);
	return m;
}
Пример #19
0
static void
rread(Fcall* f)
{
	ulong	n, rn, nn, delta;
	Dir	d;
	Fid*	fp;

	if (!isfdir(f, &fp))
		return;
	if (f->count == 0)
		goto done;
	cleannames();
	for (n = nn = 0; n < f->count; n += rn){
		rn = convM2D((uchar*)f->data + n, f->count - n, &d, statbuf);
		if (rn <= BIT16SZ)
			break;
		d.name = importname(d.name);
		//dprint("⇒ %D\n", &d);
		nn += convD2M(&d, (uchar*)dirbuf + nn, sizeof(dirbuf) - nn);
	}
	delta = nn - n;
	setaux(fp, getaux(fp) + delta);
	f->count = nn;
	f->data = dirbuf;
done:
	closefid(fp);
}
Пример #20
0
static int
pipewstat(Chan *c, uchar *dp, int n)
{
	Dir *d;
	Pipe *p;
	int d1;

	if (c->qid.type&QTDIR)
		error(Eperm);
	p = c->aux;
	if(strcmp(up->env->user, p->user) != 0)
		error(Eperm);
	d = smalloc(sizeof(*d)+n);
	if(waserror()){
		free(d);
		nexterror();
	}
	n = convM2D(dp, n, d, (char*)&d[1]);
	if(n == 0)
		error(Eshortstat);
	d1 = NETTYPE(c->qid.path) == Qdata1;
	if(!emptystr(d->name)){
		validwstatname(d->name);
		if(strlen(d->name) >= KNAMELEN)
			error(Efilename);
		if(strcmp(p->pipedir[1+!d1].name, d->name) == 0)
			error(Eexist);
		kstrcpy(p->pipedir[1+d1].name, d->name, KNAMELEN);
	}
	if(d->mode != ~0U)
		p->pipedir[d1 + 1].perm = d->mode & 0777;
	poperror();
	free(d);
	return n;
}
Пример #21
0
static int
pipewstat(Chan* c, uchar* db, int n)
{
	int m;
	Dir *dir;
	Pipe *p;

	p = c->aux;
	if(strcmp(up->user, eve) != 0)
		error(Eperm);
	if(NETTYPE(c->qid.path) == Qdir)
		error(Eisdir);

	dir = smalloc(sizeof(Dir)+n);
	if(waserror()){
		free(dir);
		nexterror();
	}
	m = convM2D(db, n, &dir[0], (char*)&dir[1]);
	if(m == 0)
		error(Eshortstat);
	if(!emptystr(dir[0].uid))
		error("can't change owner");
	if(dir[0].mode != ~0UL)
		p->perm = dir[0].mode;
	poperror();
	free(dir);
	return m;
}
Пример #22
0
static int
cmdwstat(Chan *c, uchar *dp, int n)
{
	Dir *d;
	Conv *cv;

	switch(TYPE(c->qid)){
	default:
		error(Eperm);
	case Qctl:
	case Qdata:
	case Qstderr:
		d = malloc(sizeof(*d)+n);
		if(d == nil)
			error(Enomem);
		if(waserror()){
			free(d);
			nexterror();
		}
		n = convM2D(dp, n, d, (char*)&d[1]);
		if(n == 0)
			error(Eshortstat);
		cv = cmd.conv[CONV(c->qid)];
		if(!iseve() && strcmp(up->env->user, cv->owner) != 0)
			error(Eperm);
		if(!emptystr(d->uid))
			kstrdup(&cv->owner, d->uid);
		if(d->mode != ~0UL)
			cv->perm = d->mode & 0777;
		poperror();
		free(d);
		break;
	}
	return n;
}
Пример #23
0
static vlong
_sysseek(int fd, vlong off, int whence)
{
	Chan *c;
	uchar buf[sizeof(Dir)+100];
	Dir dir;
	int n;

	c = fdtochan(fd, -1, 1, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	if(devtab[c->type]->dc == '|')
		error(Eisstream);

	switch(whence){
	case 0:
		if((c->qid.type & QTDIR) && off != 0)
			error(Eisdir);
		if(off < 0)
			error(Enegoff);
		c->offset = off;
		break;

	case 1:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		lock(&c->ref.lk);	/* lock for read/write update */
		off = off + c->offset;
		if(off < 0)
			error(Enegoff);
		c->offset = off;
		unlock(&c->ref.lk);
		break;

	case 2:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		n = devtab[c->type]->stat(c, buf, sizeof buf);
		if(convM2D(buf, n, &dir, nil) == 0)
			error("internal error: stat error in seek");
		off = dir.length + off;
		if(off < 0)
			error(Enegoff);
		c->offset = off;
		break;

	default:
		error(Ebadarg);
	}
	c->uri = 0;
	c->dri = 0;
	cclose(c);
	poperror();
	return off;
}
Пример #24
0
void
settime(int islocal, int afd, char *rp)
{
	int n, f;
	Dir dir[2];
	char timebuf[64];
	static int timeset;

	if(timeset)
		return;
	print("time...");
	if(islocal){
		/*
		 *  set the time from the real time clock
		 */
		f = open("#r/rtc", ORDWR);
		if(f >= 0){
			if((n = read(f, timebuf, sizeof(timebuf)-1)) > 0){
				timebuf[n] = '\0';
				timeset = 1;
			}
			close(f);
		}else do{
			strcpy(timebuf, "yymmddhhmm[ss]");
			outin("\ndate/time ", timebuf, sizeof(timebuf));
		}while((timeset=lusertime(timebuf)) <= 0);
	}
	if(timeset == 0){
		/*
		 *  set the time from the access time of the root
		 */
		f = open(timeserver, ORDWR);
		if(f < 0)
			return;
		if(mount(f, afd, "/tmp", MREPL, rp) < 0){
			warning("settime mount");
			close(f);
			return;
		}
		close(f);
		if(stat("/tmp", statbuf, sizeof statbuf) < 0)
			fatal("stat");
		convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]);
		sprint(timebuf, "%ld", dir[0].atime);
		unmount(0, "/tmp");
	}

	f = open("#c/time", OWRITE);
	if(write(f, timebuf, strlen(timebuf)) < 0)
		warning("can't set #c/time");
	close(f);
	print("\n");
}
Пример #25
0
static int64_t
sseek(int fd, int64_t offset, int whence)
{
	Proc *up = externup();
	Chan *c;
	uint8_t buf[sizeof(Dir)+100];
	Dir dir;
	int n;

	c = fdtochan(fd, -1, 1, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	if(c->dev->dc == '|')
		error(Eisstream);

	switch(whence){
	case 0:
		if((c->qid.type & QTDIR) && offset != 0LL)
			error(Eisdir);
		c->offset = offset;
		break;

	case 1:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		lock(&c->r.l);	/* lock for read/write update */
		offset += c->offset;
		c->offset = offset;
		unlock(&c->r.l);
		break;

	case 2:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		n = c->dev->stat(c, buf, sizeof buf);
		if(convM2D(buf, n, &dir, nil) == 0)
			error("internal error: stat error in seek");
		offset += dir.length;
		c->offset = offset;
		break;

	default:
		error(Ebadarg);
	}
	c->uri = 0;
	c->dri = 0;
	cclose(c);
	poperror();

	return offset;
}
Пример #26
0
static int
dirpackage(uint8_t *buf, int ts, Dir **d, uint32_t *nd, int dotu)
{
	char *s;
	int ss, i, n, nn;
	uint m;
	
	*d = nil;
	*nd = 0;
	if(ts <= 0) 
		return 0;

	/*
	 * first find number of all stats, check they look like stats, & size all associated strings
	 */
	ss = 0;
	n = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(statcheck(&buf[i], m, dotu) < 0)
			break;
		ss += m;
		n++;
	}

	if(i != ts) {
		DEBUG("statcheck");
		return EBADRPC;
	}
	
	*d = malloc_9p(n * sizeof(Dir) + ss);
	if (*d == NULL)
		return ENOMEM;
	/*
	 * then convert all buffers
	 */
	s = (char*)*d + n * sizeof(Dir);
	nn = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(nn >= n || convM2D(&buf[i], m, *d + nn, s, dotu) != m){
			free_9p(*d);
			*d = nil;
			DEBUG("convM2D");
			return EBADRPC;
		}
		nn++;
		s += m;
	}
	*nd = nn;
	return 0;
}
Пример #27
0
static void
rstat(Fcall* f)
{
	Dir	d;

	cleannames();
	convM2D(f->stat, f->nstat, &d, statbuf);
	d.name = importname(d.name);
	f->nstat = convD2M(&d, (uchar*)dirbuf, sizeof(dirbuf));
	f->stat = (uchar*)dirbuf;
	if (statcheck(f->stat, f->nstat) < 0)
		dprint("stat fails\n");
}
Пример #28
0
static void
twstat(Fcall* f)
{
	Dir	d;

	cleannames();
	if (convM2D(f->stat, f->nstat, &d, statbuf) <= BIT16SZ)
		return;
	d.name = exportname(d.name);
	f->nstat = convD2M(&d, (uchar*)dirbuf, sizeof(dirbuf));
	f->stat = (uchar*)dirbuf;
	if (statcheck(f->stat, f->nstat) < 0)
		dprint("stat fails\n");
}
Пример #29
0
static
long
dirpackage(uchar *buf, long ts, Dir **d)
{
	char *s;
	long ss, i, n, nn, m;

	*d = nil;
	if(ts <= 0)
		return 0;

	/*
	 * first find number of all stats, check they look like stats, & size all associated strings
	 */
	ss = 0;
	n = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16(&buf[i]);
		if(statcheck(&buf[i], m) < 0)
			break;
		ss += m;
		n++;
	}

	if(i != ts)
		return -1;

	*d = malloc(n * sizeof(Dir) + ss);
	if(*d == nil)
		return -1;

	/*
	 * then convert all buffers
	 */
	s = (char*)*d + n * sizeof(Dir);
	nn = 0;
	for(i = 0; i < ts; i += m){
		m = BIT16SZ + GBIT16((uchar*)&buf[i]);
		if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
			free(*d);
			*d = nil;
			return -1;
		}
		nn++;
		s += m;
	}

	return nn;
}
Пример #30
0
int
eiawstat(Chan *c, uchar *dp, int n)
{
	Dir d;
	int i;

	if(strcmp(up->env->user, eve) != 0)
		error(Eperm);
	if(c->qid.type & QTDIR)
		error(Eperm);

	n = convM2D(dp, n, &d, nil);
	i = Nqid*NETID(c->qid.path)+NETTYPE(c->qid.path)-Ndataqid;
	eiadir[i+1].perm = d.mode&0666;
	return n;
}