#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/fcall.h>
#include <9pm/ns.h>
void
validstat(uchar *s, int n)
{
int m;
char buf[64];
if(statcheck(s, n) < 0)
error("bad stat entry");
/* verify that name entry is acceptable */
s += STATFIXLEN - 4*BIT16SZ; /* location of first string */
/*
* s now points at count for first string.
* if it's too long, let the server decide; this is
* only for his protection anyway. otherwise
* we'd have to allocate and waserror.
*/
m = GBIT16(s);
s += BIT16SZ;
if(m+1 > sizeof buf)
return;
memmove(buf, s, m);
buf[m] = '\0';
/* name could be '/' */
if(strcmp(buf, "/") != 0)
validname(buf, 0);
}
/*
* Rewrite channel type and dev for in-flight data to
* reflect local values. These entries are known to be
* the first two in the Dir encoding after the count.
*/
void
mntdirfix(uchar *dirbuf, Mnt *mnt)
{
uint r;
r = mnt->dev->dc;
dirbuf += BIT16SZ; /* skip count */
PBIT16(dirbuf, r);
dirbuf += BIT16SZ;
PBIT32(dirbuf, mnt->devid);
}
static char isfrog[256]={
/*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x2F = '/' */
/*0x30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*0x70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0x7F = rubout */
};
/*
* Check that the name
* a) is in valid memory (no-op here)
* b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
* c) contains no frogs.
* The first byte is known to be addressible by the requester, so the
* routine works for kernel and user memory both.
* The parameter slashok flags whether a slash character is an error
* or a valid character.
*/
void
validname(char *name, int slashok)
{
char *ename;
int c;
Rune r;
ename = memchr(name, 0, (1<<16));
if(ename==nil || ename-name>=(1<<16))
error("name too long");
while(*name){
/* all characters above '~' are ok */
c = *(uchar*)name;
if(c >= Runeself)
name += chartorune(&r, name);
else{
if(isfrog[c])
if(!slashok || c!='/')
error("bad character in file name");
name++;
}
}
}
void
mntdirreadfix(uchar *p, int n, Mnt *mnt)
{
int dirlen;
uchar *e;
for(e = &p[n]; p+BIT16SZ < e; p += dirlen){
dirlen = BIT16SZ+GBIT16(p);
if(p+dirlen > e)
break;
validstat(p, dirlen);
mntdirfix(p, mnt);
}
if(p != e)
error("bad directory entry in directory read");
}
syntax highlighted by Code2HTML, v. 0.9.1