ref: fbdac038aad6c5873e6ce3323a92591a14575583
dir: /fshandler.inc/
#line 0 "fshandler.inc"
static void
fsread(Req *r)
{
respond(r, nil);
}
static void
fswrite(Req *r)
{
respond(r, nil);
}
static void
fsstat(Req *r)
{
int q;
Filedata *fd;
void (*func)(Req *r);
q = breakqid(r->fid->qid.path);
fprint(2, "stat: q: %d\n", q);
fd = &filedata[q];
r->d = fd->dir;
qidtype = q;
r->d.qid.path = makeqid(getqidhash(r->fid));
r->d.qid.vers = 0;
r->d.qid.type = fd->dir.mode&DMDIR ? QTDIR : QTFILE;
r->d.name = estrdup9p(fd->dir.name);
r->d.uid = estrdup9p("none");
r->d.gid = estrdup9p("none");
r->d.gid = estrdup9p("none");
if (fd->stat) {
func = fd->stat;
func(r);
/* if function exists, it should respond */
return;
}
respond(r, nil);
return;
}
static int
childrencontains(int *fh, int search)
{
int *i;
for (i = fh; *i; i++) {
if (*i == search)
return 1;
}
return 0;
}
static int
findparent(int qid)
{
for (int i = Qroot; i < Qmax; i++) {
if (childrencontains(filehierarchy[i], qid))
return i;
}
return Qroot;
}
/* 0 is root/not found, n is qid */
static int
findchild(int qid, char *name)
{
Filedata *fd;
char *s;
int n;
fprint(2, "find child %s of %d\n", name, qid);
assert(qid >= Qroot && qid < Qmax);
if (!filehierarchy[qid]) {
return qid;
}
for (int *i = filehierarchy[qid]; *i; i++) {
fd = &filedata[*i];
s = fd->dir.name;
n = strlen(s);
if (s[0] == '{' && s[n-1] == '}')
return *i;
if (strcmp(s, name) == 0)
return *i;
}
return Qroot;
}
static char*
fswalk(Fid *fid, char *name, Qid *qid)
{
int qt, i;
uvlong id;
Filedata *fd;
char buf[32];
char *s;
if (strcmp(name, ".") == 0) {
fid->qid = *qid;
return nil;
}
qt = breakqid(fid->qid.path);
id = getqidid(fid->qid.path);
if (strcmp(name, "..") == 0) {
qt = findparent(qt);
fd = &filedata[qt];
qidtype = qt;
qid->path = makeqid(getqidhash(fid));
qid->vers = 0;
qid->type = fd->dir.mode&DMDIR ? QTDIR : QTFILE;
fid->qid = *qid;
fprint(2, "walk: QID: %d %d\n", qt, qid->type);
return nil;
}
i = findchild(qt, name);
switch (i) {
case 0:
/* invalid file */
return "file not found";
default:
/* found child */
break;
}
fd = &filedata[i];
if (fd->dir.name[0] == '{') {
strcpy(buf, fd->dir.name+1);
s = strchr(buf, '}');
*s = 0;
setvar(fid->aux, buf, name);
}
qidtype = i;
qid->path = makeqid(getqidhash(fid));
qid->vers = 0;
qid->type = fd->dir.mode&DMDIR ? QTDIR : QTFILE;
fid->qid = *qid;
fprint(2, "found child: %d of %d\n", qidtype, qt);
return nil;
}
static char*
fsclone(Fid *ofid, Fid *nfid)
{
FileAux *src, *dst;
if (!ofid->aux)
return nil;
src = ofid->aux;
nfid->aux = dst = mallocz(sizeof(FileAux), 1);
clonevars(src, dst);
return nil;
}
static void
fsattach(Req *r)
{
Qid q;
qidtype = Qroot;
q.path = makeqid(0);
q.vers = 0;
q.type = QTDIR;
r->ofcall.qid = r->fid->qid = q;
respond(r, nil);
}