shithub: pronterfs

ref: c3b784ac16bbf3f62d8d3aec49acebd2f6c77fee
dir: /pronterfs.c/

View raw version
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "machine.h"

void
usage(void)
{
	fprint(2, "usage: %s [ -s srvname ] [ -m mountpoint ] devicefile\n", argv0);
	exits("usage");
}

char *srvname = "pronterfs";
char *mtpt = "/mnt/pronterfs";
char *devicefile;

char* Efilenotfound = "file not found";
char* Ecnf = "command not found";

Channel *chan;

File* Fctl;
File* Fprogram;

Program program;

void
writeprogram(Req* r)
{
	ulong offset;
	
	offset = r->ifcall.offset;
	if (offset + r->ifcall.count > program.size) {
		program.size = offset + r->ifcall.count;
		program.data = realloc(program.data, program.size);
		if (program.data == nil)
			respond(r, "out of memory");
	}
	memmove(program.data + offset, r->ifcall.data, r->ifcall.count);
	r->ofcall.count = r->ifcall.count;
	Fprogram->length = program.size;
	respond(r, nil);
}

void
readprogram(Req* r)
{
	ulong offset;
	ulong count;
	
	offset = r->ifcall.offset;
	if (offset >= program.size) {
		r->ofcall.count = 0;
		respond(r, nil);
		return;
	}
	count = r->ifcall.count;
	if (offset + count > program.size)
		count = program.size - offset;
	r->ofcall.data = program.data + offset;
	r->ofcall.count = count;
	respond(r, nil);
}

void
writectl(Req *r)
{
	char* cmd;
	
	cmd = r->ifcall.data;
	cmd[r->ifcall.count-1] = 0;
	
	if (strcmp(cmd, "start") == 0) {
		startmachine();
		respond(r, nil);
		return;
	}
	if (strcmp(cmd, "stop") == 0) {
		stopmachine();
		respond(r, nil);
		return;
	}
	
	respond(r, Ecnf);
}

void
readctl(Req *r)
{
	respond(r, nil);
}

void
fsread(Req *r)
{
	if (r->fid->file == Fctl) {
		readctl(r);
		return;
	}
	if (r->fid->file == Fprogram) {
		readprogram(r);
		return;
	}
	
	respond(r, Efilenotfound);
}

void
fswrite(Req *r)
{
	if (r->fid->file == Fctl) {
		writectl(r);
		return;
	}
	if (r->fid->file == Fprogram) {
		writeprogram(r);
		return;
	}
	respond(r, Efilenotfound);
}

Srv fs = {
	.read = fsread,
	.write = fswrite,
};

void
initfiles(void)
{
	Fctl = createfile(fs.tree->root, "ctl", "none", 0666, nil);
	Fprogram = createfile(fs.tree->root, "program", "none", 0666, nil);
}

void
threadmain(int argc, char **argv)
{
	ARGBEGIN{
	case 's':
		srvname = EARGF(usage());
		break;
	case 'm':
		mtpt = EARGF(usage());
		break;
	}ARGEND;
	
	if (argc != 1)
		usage();
	
	devicefile = argv[0];
	
	chan = chancreate(sizeof(int), 1);
	if (!initmachine(devicefile, chan))
		sysfatal("initmachine: %r");
	proccreate(machineloop, chan, 8192);

	program.data = malloc(1024);
	program.pc = program.data;
	program.size = 0;
	
	fs.tree = alloctree(nil, nil, DMDIR|0775, nil);
	initfiles();
	
	threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
	exits(nil);
}