Example #1
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;
}
Example #2
0
long
sysstat(uint32 *arg)
{
	char *name;
	Chan *c;
	uint l;
	uchar *p;

	l = arg[2];
	p = uvalidaddr(arg[1], l, 1);
	name = uvalidaddr(arg[0], 1, 0);
	c = namec(name, Aaccess, 0, 0);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	l = devtab[c->type]->stat(c, p, l);
	name = pathlast(c->path);
	if(name)
		l = dirsetname(name, strlen(name), p, l, arg[2]);

	poperror();
	cclose(c);
	return l;
}
Example #3
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;
}
Example #4
0
void
sysstat(Ar0* ar0, ...)
{
	Proc *up = externup();
	char *aname;
	Chan *c;
	usize n;
	int r;
	uint8_t *p;
	va_list list;
	va_start(list, ar0);

	/*
	 * int stat(char* name, uchar* edir, int nedir);
	 * should really be
	 * usize stat(char* name, uchar* edir, usize nedir);
	 * but returning an unsigned is probably too
	 * radical.
	 */
	aname = va_arg(list, char*);
	aname = validaddr(aname, 1, 0);
	p = va_arg(list, uint8_t*);
	n = va_arg(list, usize);
	va_end(list);

	p = validaddr(p, n, 1);
	c = namec(aname, Aaccess, 0, 0);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	r = c->dev->stat(c, p, n);
	aname = pathlast(c->path);
	if(aname)
		r = dirsetname(aname, strlen(aname), p, r, n);

	poperror();
	cclose(c);

	ar0->i = r;
}
Example #5
0
/*
 * Rewrite the results of a directory read to reflect current
 * name space bindings and mounts.  Specifically, replace
 * directory entries for bind and mount points with the results
 * of statting what is mounted there.  Except leave the old names.
 */
static int32_t
mountfix(Chan *c, uint8_t *op, int32_t n, int32_t maxn)
{
	Proc *up = externup();
	char *name;
	int nbuf;
	Chan *nc;
	Mhead *mh;
	Mount *mount;
	usize dirlen, nname, r, rest;
	int32_t l;
	uint8_t *buf, *e, *p;
	Dir d;

	p = op;
	buf = nil;
	nbuf = 0;
	for(e=&p[n]; p+BIT16SZ<e; p+=dirlen){
		dirlen = dirfixed(p, e, &d);
		if(dirlen == 0)
			break;
		nc = nil;
		mh = nil;
		if(findmount(&nc, &mh, d.type, d.dev, d.qid)){
			/*
			 * If it's a union directory and the original is
			 * in the union, don't rewrite anything.
			 */
			for(mount=mh->mount; mount; mount=mount->next)
				if(eqchanddq(mount->to, d.type, d.dev, d.qid, 1))
					goto Norewrite;

			name = dirname(p, &nname);
			/*
			 * Do the stat but fix the name.  If it fails,
			 * leave old entry.
			 * BUG: If it fails because there isn't room for
			 * the entry, what can we do?  Nothing, really.
			 * Might as well skip it.
			 */
			if(buf == nil){
				buf = smalloc(4096);
				nbuf = 4096;
			}
			if(waserror())
				goto Norewrite;
			l = nc->dev->stat(nc, buf, nbuf);
			r = dirsetname(name, nname, buf, l, nbuf);
			if(r == BIT16SZ)
				error("dirsetname");
			poperror();

			/*
			 * Shift data in buffer to accomodate new entry,
			 * possibly overflowing into rock.
			 */
			rest = e - (p+dirlen);
			if(r > dirlen){
				while(p+r+rest > op+maxn){
					mountrock(c, p, &e);
					if(e == p){
						dirlen = 0;
						goto Norewrite;
					}
					rest = e - (p+dirlen);
				}
			}
			if(r != dirlen){
				memmove(p+r, p+dirlen, rest);
				dirlen = r;
				e = p+dirlen+rest;
			}

			/*
			 * Rewrite directory entry.
			 */
			memmove(p, buf, r);

		    Norewrite:
			cclose(nc);
			putmhead(mh);
		}
	}
	if(buf)
		free(buf);

	if(p != e)
		error("oops in mountfix");

	return e-op;
}
Example #6
0
/*
 * Rewrite the results of a directory read to reflect current 
 * name space bindings and mounts.  Specifically, replace
 * directory entries for bind and mount points with the results
 * of statting what is mounted there.  Except leave the old names.
 */
static long
mountfix(Chan *c, uchar *op, long n, long maxn)
{
	char *name;
	int nbuf, nname;
	Chan *nc;
	Mhead *mh;
	Mount *m;
	uchar *p;
	int dirlen, rest;
	long l;
	uchar *buf, *e;
	Dir d;

	p = op;
	buf = nil;
	nbuf = 0;
	for(e=&p[n]; p+BIT16SZ<e; p+=dirlen){
		dirlen = dirfixed(p, e, &d);
		if(dirlen < 0)
			break;
		nc = nil;
		mh = nil;
		if(findmount(&nc, &mh, d.type, d.dev, d.qid)){
			/*
			 * If it's a union directory and the original is
			 * in the union, don't rewrite anything.
			 */
			for(m=mh->mount; m; m=m->next)
				if(eqchantdqid(m->to, d.type, d.dev, d.qid, 1))
					goto Norewrite;

			name = dirname(p, &nname);
			/*
			 * Do the stat but fix the name.  If it fails, leave old entry.
			 * BUG: If it fails because there isn't room for the entry,
			 * what can we do?  Nothing, really.  Might as well skip it.
			 */
			if(buf == nil){
				buf = smalloc(4096);
				nbuf = 4096;
			}
			if(waserror())
				goto Norewrite;
			l = devtab[nc->type]->stat(nc, buf, nbuf);
			l = dirsetname(name, nname, buf, l, nbuf);
			if(l == BIT16SZ)
				error("dirsetname");
			poperror();

			/*
			 * Shift data in buffer to accomodate new entry,
			 * possibly overflowing into rock.
			 */
			rest = e - (p+dirlen);
			if(l > dirlen){
				while(p+l+rest > op+maxn){
					mountrock(c, p, &e);
					if(e == p){
						dirlen = 0;
						goto Norewrite;
					}
					rest = e - (p+dirlen);
				}
			}
			if(l != dirlen){
				memmove(p+l, p+dirlen, rest);
				dirlen = l;
				e = p+dirlen+rest;
			}

			/*
			 * Rewrite directory entry.
			 */
			memmove(p, buf, l);

		    Norewrite:
			cclose(nc);
			putmhead(mh);
		}
	}
	if(buf)
		free(buf);

	if(p != e)
		error("oops in rockfix");

	return e-op;
}