shithub: ircd

ref: e3bb18d0464ea795f1805186cc68d4e7a9eedbdc
dir: /cmd.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"
#include "cmd.h"
#include "version.h"

static void
cversion(Client *c, Request *r)
{
	if (r->args[0]) {
		fprint(2, "get version of '%s' (not implemented yet!)\n", r->args[0]);
		reply(c, Enosuchserver, r->args[0]);
		return;
	}
	reply(c, Rversion, getversion());
}

static void
cuser(Client *c, Request *r)
{
	User *u;
	if (!r->args[3]) {
		fprint(2, "user without enough args%R\n", *r);
		reply(c, Eneedmoreparams, r->cmd->name);
		return;
	}
	u = finduser(r->args[0]);
	if (u) {
		fprint(2, "user already registered%R\n", *r);
		reply(c, Ealreadyregistered);
		return;
	}
	u = adduser(r->args[0]);
	u->realname = strdup(r->args[3]);
	c->user = u;
	
	if (c->nick)
		reply(c, Rwelcome, welcome, c->nick, u->name, sysnameb);
}

static void
cnick(Client *c, Request *r)
{
	if (!r->args[0]) {
		reply(c, Enonicknamegiven);
		return;
	}
	
	if (findnick(r->args[0])) {
		reply(c, Enicknameinuse, r->args[0]);
		return;
	}
	
	c->nick = strdup(r->args[0]);
	
	if (c->user)
		reply(c, Rwelcome, welcome, c->nick, c->user->name, sysnameb);
}

static void
cwhois(Client *c, Request *r)
{
	// TODO: implement remaining replies: (/lib/rfc/rfc2812:/^3.6.2)
	int start = 0;
	char *server = nil;
	User *u;
	Client *cl;
	
	if (!r->args[0]) {
		reply(c, Enonicknamegiven);
		return;
	}
	if (r->args[1] && strcmp(r->args[1], ",")) {
		server = r->args[0];
		start = 2;
	}
	for (int i = start; i < 15; i += 2) {
		/* args[i] is nick, args[i+1] is ',' */
		if (!r->args[i])
			break;
		if (!server) {
			cl = findnick(r->args[i]);
			if (cl) {
				u = cl->user;
				if (!u)
					goto Next;
				reply(c, Rwhoisuser, cl->nick, u->name, sysnameb, u->realname);
			} else
				reply(c, Enosuchnick, r->args[i]);
		} else {
			// TODO: forward to server: send message to server
		}
Next:
		reply(c, Rendofwhois, r->args[i]);
	}
}

static Command commands[] = {
	{ "whois", cwhois },
	{ "version", cversion },
	{ "user", cuser },
	{ "nick", cnick },
};
int ncommands = sizeof(commands) / sizeof(Command);

Command*
findcommand(char *s)
{
	for (int i = 0; i < ncommands; i++) {
		if (cistrcmp(commands[i].name, s) == 0)
			return &commands[i];
	}
	return nil;
}

Command*
findcommandn(int n)
{
	assert(0);
	return nil;
}

void
execrequest(Client *c, Request r)
{
	if (!(r.cmd && r.cmd->func)) {
		fprint(2, "cannot execute request: no command\n");
		return;
	}
	if (debug)
		fprint(2, "run command '%s'\n", r.cmd->name);
	r.cmd->func(c, &r);
}