shithub: pain

ref: 4bcb73eb20638b1564d6757405508ea63ccf5f14
dir: /fs.c/

View raw version
#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;
}