shithub: ircd

ref: eaf9a2c0694335ea7d5139f83b3824f6127fb310
dir: /ircd.c/

View raw version
#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include <String.h>
#include "dat.h"
#include "fns.h"
#include "version.h"

void
usage(void)
{
	fprint(2, "usage: %s\n", argv0);
	threadexitsall("usage");
}

enum {
	Firc,
};

char *sysnameb = "nil";
static char *versionstring = nil;
int debug = 0;

char*
getversion()
{
	if (versionstring)
		return versionstring;
	
	versionstring = smprint("%s.%d %s :%s", Vversion, debug, Vname, Vcomment);
	return versionstring;
}

char *welcome = "one does not simply connect to mordor";
char *mtpt = "/mnt/ircd";
char *srvname = "ircd";
Reqqueue *reqqueue = nil;

Client*
getclient(Req *r)
{
	Client *c;
	c = findclient(r->fid->fid);
	if (c)
		return c;
	c = addclient(r->fid->fid);
	return c;
}

static void
readproc(Req *r)
{
	char *repl;
	Client *c;
	
	threadsetname("readproc");
	
	c = findclient(r->fid->fid);
	
	if (!c) {
		respond(r, "client not connected!");
		return;
	}
	
	while (1) {
		qlock(&c->replies);
		repl = getreplies(c);
		if (repl) {
			r->ifcall.offset = 0;
			readstr(r, repl);
			flushreplies(c);
			qunlock(&c->replies);
			respond(r, nil);
			return;
		}
		qunlock(&c->replies);
	}
}

static void
fsread(Req *r)
{
	if (r->fid->file->aux != Firc) {
		respond(r, "file not found");
		return;
	}
	getclient(r);
	reqqueuepush(reqqueue, r, readproc);
}

static void
fswrite(Req *r)
{
	char line[512];
	char *c;
	Request parsed;
	Client *cl;
	
	if (r->fid->file->aux != Firc) {
		respond(r, "file not found");
		return;
	}
	
	cl = getclient(r);
	if (!cl) {
		respond(r, "client not found!");
		return;
	}
	if (r->ifcall.count > 512) {
		respond(r, "too many bytes");
		return;
	}
	memcpy(line, r->ifcall.data, r->ifcall.count);
	r->ofcall.count = r->ifcall.count;
	line[r->ifcall.count-1] = 0; /* last char is either \n or \r */
	
	c = strchr(line, '
');
	if (c) *c = 0;
	else {
		c = strchr(line, '\n');
		if (c) *c = 0;
	}
	
	parsed = parseline(line);
	if (debug > 1)
		fprint(2, "request:%R", parsed);
	execrequest(cl, parsed);
	
	respond(r, nil);
}

static void
fsflush(Req *r)
{
	reqqueueflush(reqqueue, r->oldreq);
	respond(r, nil);
}

static void
fsdestroyfid(Fid *fid)
{
	Client *c;
	if (!fid || !fid->file)
		return;
	if (fid->file->aux != Firc)
		return;
	
	c = findclient(fid->fid);
	if (!c)
		return;
	if (c->user)
		deluser(c->user);
	delclient(c);
}

Srv fs = {
	.read = fsread,
	.write = fswrite,
	.flush = fsflush,
	.destroyfid = fsdestroyfid,
};

void
populatetree(File *root)
{
	File *f;
	
	if ((f = createfile(root, "irc", nil, 0666, Firc)) != nil) {
		f->length = 0;
	}
}

void
threadmain(int argc, char **argv)
{
	ARGBEGIN{
	case 'h':
		usage();
		break;
	case 'v':
		fprint(2, "version: %s\n", getversion());
		threadexitsall(nil);
	case 's':
		srvname = EARGF(usage());
		break;
	case 'm':
		mtpt = EARGF(usage());
		break;
	case 'd':
		debug++;
		break;
	case 'D':
		chatty9p++;
		break;
	}ARGEND;
	
	fmtinstall('R', Rfmt);
	
	sysnameb = sysname();
	reqqueue = reqqueuecreate();
	
	fs.tree = alloctree(nil, nil, DMDIR|0777, nil);
	populatetree(fs.tree->root);
	threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
	//exits(nil);
}