Plan 9 from Bell Labs’s /usr/web/sources/contrib/axel/8021x/v200/fs.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
};

enum {
	Qroot = 0,
	Qdir,
	Qctl,
	Qlog,
	Qstats,
	Qstatus,
	Qtlslog,
	Nq,
};

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);

	switch(qid){
	case Qroot:
		d->name = "/";
		d->qid.type = QTDIR;
		d->mode = DMDIR|0777;
//		d->mtime = ciainfo.inittime;
		break;

	case Qdir:
		d->name = "8021x";
		d->qid.type = QTDIR;
		d->mode = DMDIR|0777;
		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 = ciainfo.stattime;
		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,
};


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.