#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "dat.h"
#include "fns.h"
typedef struct Aux Aux;
struct Aux {
int doff;
};
typedef struct Fs Fs;
struct Fs {
long inittime;
};
enum {
Qroot = 0,
Qdir,
Qctl,
Qlog,
Qstats,
Qstatus,
Qtlslog,
Nq,
};
static Fs theFs;
static int
fillstat(ulong qid, Dir *d)
{
memset(d, 0, sizeof(Dir));
d->uid = "8021x";
d->gid = "8021x";
d->muid = "";
d->qid = (Qid){qid, 0, 0};
d->atime = time(0);
d->mtime = theFs.inittime;
switch(qid){
case Qroot:
d->name = "/";
d->qid.type = QTDIR;
d->mode = DMDIR|0555;
// d->mtime = ciainfo.inittime;
break;
case Qdir:
d->name = "8021x";
d->qid.type = QTDIR;
d->mode = DMDIR|0555;
break;
case Qctl:
d->name = "ctl";
d->mode = 0666;
break;
case Qlog:
d->name = "log";
d->mode = 0444;
break;
case Qstats:
d->name = "stats";
d->mode = 0444;
break;
case Qstatus:
d->name = "status";
d->mode = 0444;
d->mtime = getPAEChangetime();
break;
case Qtlslog:
d->name = "tlslog";
d->mode = 0444;
break;
default:
return 0;
}
return 1;
}
static void
fsattach(Req *r)
{
r->fid->qid = (Qid){Qroot, 0, QTDIR};
r->ofcall.qid = r->fid->qid;
r->fid->aux = emalloc9p(sizeof(Aux));
respond(r, nil);
}
static char*
fsclone(Fid *old, Fid *new)
{
Aux *na;
na = emalloc9p(sizeof(Aux));
*na = *((Aux*)old->aux);
new->aux = na;
return nil;
}
static char*
fswalk1(Fid *fid, char *name, Qid *qid)
{
switch((ulong)fid->qid.path) {
case Qroot:
if(strcmp(name, "..") == 0) {
*qid = (Qid){Qroot, 0, QTDIR};
return nil;
}
if(strcmp(name, "8021x") == 0) {
*qid = (Qid){Qdir, 0, QTDIR};
return nil;
}
case Qdir:
if(strcmp(name, "..") == 0) {
*qid = (Qid){Qroot, 0, QTDIR};
return nil;
}
if(strcmp(name, "ctl") == 0) {
*qid = (Qid){Qctl, 0, 0};
return nil;
}
if (strcmp(name, "log")== 0) {
*qid = (Qid){Qlog, 0, 0};
return nil;
}
if (strcmp(name, "stats") == 0) {
*qid = (Qid){Qstats, 0, 0};
return nil;
}
if (strcmp(name, "status") == 0) {
*qid = (Qid){Qstatus, 0, 0};
return nil;
}
if (strcmp(name, "tlslog")== 0) {
*qid = (Qid){Qtlslog, 0, 0};
return nil;
}
return "no such file or directory";
default:
return "walk in non-directory";
}
}
static void
readctl(Req *r)
{
char s[1024];
sprint(s, "802.1x ctl bla\n");
readstr(r, s);
}
static void
fsread(Req *r)
{
int j, n;
Fid *fid;
vlong offset;
uchar *p, *ep;
void *buf;
long count;
Dir d;
Aux *a;
char sbuf[1024];
fid = r->fid;
offset = r->ifcall.offset;
buf = r->ofcall.data;
count = r->ifcall.count;
switch((ulong)fid->qid.path) {
case Qroot:
p = buf;
ep = p+count;
if(offset == 0) {
if(fillstat(Qdir, &d) && (n = convD2M(&d, p, ep-p)) > BIT16SZ)
p += n;
r->ofcall.count = p-(uchar*)buf;
}
respond(r, nil);
return;
case Qdir:
p = buf;
ep = p+count;
a = fid->aux;
if(offset == 0)
a->doff = 2; /* skip root and Qdir */
for(j=a->doff; j<Nq; j++) {
if(fillstat(j, &d)) {
if((n = convD2M(&d, p, ep-p)) <= BIT16SZ)
break;
p += n;
}
}
a->doff = j;
r->ofcall.count = p-(uchar*)buf;
respond(r, nil);
return;
case Qlog:
case Qstats:
case Qtlslog:
r->ofcall.count = 0;
respond(r, nil);
return;
case Qstatus:
getPAEStatus(sbuf, sizeof(sbuf));
readstr(r, sbuf);
respond(r, nil);
return;
case Qctl:
readctl(r);
respond(r, nil);
return;
}
}
static char*
writectl(void *v, long count)
{
return nil;
}
static void
fswrite(Req *r)
{
Fid *fid;
fid = r->fid;
r->ofcall.count = r->ifcall.count;
if(fid->qid.path == Qctl) {
respond(r, writectl(r->ifcall.data, r->ifcall.count));
return;
}
respond(r, "permission denied");
return;
}
static void
fsstat(Req *r)
{
fillstat((ulong)r->fid->qid.path, &r->d);
r->d.name = estrdup9p(r->d.name);
r->d.uid = estrdup9p(r->d.uid);
r->d.gid = estrdup9p(r->d.gid);
r->d.muid = estrdup9p(r->d.muid);
respond(r, nil);
}
static void
fsopen(Req *r)
{
int omode;
Fid *fid;
fid = r->fid;
omode = r->ifcall.mode;
r->ofcall.qid = (Qid){fid->qid.path, 0, fid->qid.vers};
switch((ulong)fid->qid.path){
case Qroot:
case Qdir:
case Qlog:
case Qstats:
case Qstatus:
case Qtlslog:
if(omode == OREAD)
respond(r, nil);
else
respond(r, "permission denied");
return;
case Qctl:
if(omode&~(OTRUNC|OREAD|OWRITE|ORDWR))
respond(r, "permission denied");
else
respond(r, nil);
return;
default:
respond(r, "no such file or directory");
}
}
static void
fsdestroyfid(Fid *fid)
{
if(fid->aux) {
free(fid->aux);
fid->aux = 0;
}
}
Srv fs = {
.attach= fsattach,
.clone= fsclone,
.walk1= fswalk1,
.open= fsopen,
.read= fsread,
.write= fswrite,
.stat= fsstat,
.destroyfid= fsdestroyfid,
};
void
initFs(void)
{
theFs.inittime = time(0);
}
|