ref: 4bcb73eb20638b1564d6757405508ea63ccf5f14
dir: /fs.c/
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include <draw.h>
#include <mouse.h>
#include "dat.h"
#include "fns.h"
#define WALK1NAMEQID(q_, n_) \
if (strcmp(n_, name) == 0) { \
*qid = (Qid){q_, 0, QTDIR}; \
return nil; \
}
int fillstat(ulong qid, Dir *d);
static void fsopen(Req * req);
static void fsread(Req * req);
static void fswrite(Req * req);
static void fswstat(Req * req);
static void fscreate(Req * req);
static void fsattach(Req * req);
static void fsdestroyfid(Fid * req);
static void fswalk1(Fid *fid, char *name, Qid *qid);
static void fsstart(Srv * srv);
static void fsdetroyfile(File * f);
static char mntpath[128] = {0};
static void fssrvforker(void (*fn)(void*), void *arg, int flags);
static Srv fs = {
.open = fsopen,
.read = fsread,
.write = fswrite,
.wstat = fswstat,
.walk1 = fswalk1,
.create = fscreate,
.destroyfid = fsdestroyfid,
.attach = fsattach,
.start = fsstart,
.forker = fssrvforker,
};
enum {
Qdir,
Qctl,
Qcanvas,
Qerrors,
Qevent,
Qcursor,
Qwindow,
Qlog,
Qlabel,
Qbrush,
};
int
fillstat(ulong qid, Dir *d)
{
static char buf[32];
nulldir(d);
d->type = L'M';
d->dev = 1;
d->length = 0;
d->uid = d->gid = buf;
d->muid = "";
d->qid = (Qid){qid, drive->nchange, 0};
d->atime = time(0);
d->mtime = drive->changetime;
switch(qid){
case Qdir:
d->name = "/";
d->qid.type = QTDIR;
d->mode = DMDIR|0777;
break;
case Qctl:
d->name = "ctl";
d->mode = 0666;
break;
case Qwa:
if(drive->writeok == No ||
drive->mmctype != Mmcnone &&
drive->mmctype != Mmccd)
return 0;
d->name = "wa";
d->qid.type = QTDIR;
d->mode = DMDIR|0777;
break;
case Qwd:
if(drive->writeok == No)
return 0;
d->name = "wd";
d->qid.type = QTDIR;
d->mode = DMDIR|0777;
break;
default:
if(qid-Qtrack >= drive->ntrack)
return 0;
t = &drive->track[qid-Qtrack];
if(strcmp(t->name, "") == 0)
return 0;
d->name = t->name;
d->mode = t->mode;
d->length = t->size;
break;
}
return 1;
}
static void
fsopen(Req * req) {
respond(req, nil);
}
static void
fsread(Req * req) {
respond(req,nil);
}
static void
fswrite(Req * req) {
respond(req,nil);
}
static void
fswstat(Req * req) {
respond(req,nil);
}
static void
fscreate(Req * req) {
respond(req,nil);
}
static void
fswalk1(Fid *fid, char *name, Qid *qid) {
switch(fid->qid.path) {
case Qdir:
if (strcmp("..", name) == 0) {
*qid = (Qid){Qdir, 0, QTDIR};
return nil;
}
if (strcmp("ctl", name) == 0) {
*qid = (Qid){Qdir, 0, QTDIR};
return nil;
}
if (strcmp("canvas", name) == 0) {
*qid = (Qid){Qcanvas, 0, QTDIR};
return nil;
}
if (strcmp("errors", name) == 0) {
*qid = (Qid){Qerrors, 0, QTDIR};
return nil;
}
if (strcmp("event", name) == 0) {
*qid = (Qid){Qevent, 0, QTDIR};
return nil;
}
if (strcmp("cursor", name) == 0) {
*qid = (Qid){Qcursor, 0, QTDIR};
return nil;
}
if (strcmp("window", name) == 0) {
*qid = (Qid){Qwindow, 0, QTDIR};
return nil;
}
if (strcmp("log", name) == 0) {
*qid = (Qid){Qlog, 0, QTDIR};
return nil;
}
if (strcmp("brush", name) == 0) {
*qid = (Qid){Qbrush, 0, QTDIR};
return nil;
}
return "file not found";
default:
return "walk in non-directory";
}
}
static void
fsdestroyfid(Fid * req) {
USED(req);
}
static void
fsattach(Req * req) {
char *spec;
spec = r->ifcall.aname;
if(spec && spec[0]){
respond(r, "invalid attach specifier");
return;
}
r->ofcall.qid = (Qid){Qdir, 0, QTDIR};
r->fid->qid = r->ofcall.qid;
respond(r, nil);
}
static void
fsstart(Srv * srv) {
USED(srv);
}
static void
fsdestroyfile(File * f) {
USED(f);
}
void
fsclose(void)
{
Waitmsg * m;
while ((m = wait()) != nil)
free(m);
}
static void
fssrvforker(void (*fn)(void*), void *arg, int flags)
{
srvforker(fn, arg, RFPROC|RFNAMEG|RFNOTEG|RFMEM|flags);
}
int
fsinit(char * srvname)
{
if (fs.tree == nil) {
return -1;
}
snprint(mntpath, sizeof(mntpath), "/mnt/%s", srvname);
postmountsrv(&fs, srvname, mntpath, MCREATE|MREPL);
return 1;
}