shithub: mez

ref: a959605dff6d7ffffbca9441db4e57b98b261b71
dir: /mez.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <auth.h>
#include <mp.h>
#include <libsec.h>
#include <draw.h>
#include <mouse.h>
#include <frame.h>
#include "mez.h"

void
usage(void)
{
	fprint(2, "usage: %s [-u user] host\n", argv0);
	threadexits("usage");
}

void
error(char *s)
{
	fprint(2, "%s: error: %s: %r\n", argv0, s);
	threadexits(s);
}

void*
emallocz(ulong sz, int clr)
{
	void *p;

	if((p = mallocz(sz, clr)) == nil)
		error("Out of memory");
	setmalloctag(p, getcallerpc(&sz));
	return p;
}

void
vwmsg(int fd, char *fmt, va_list v)
{
	static char buf[8192];
	char *e;

	e = vseprint(buf, buf+sizeof(buf), fmt, v);
	va_end(v);
	*e++ = '\r';
	*e++ = '\n';
	write(fd, buf, e-buf);
}

void
wmsg(int fd, char *fmt, ...)
{
	va_list v;

	va_start(v, fmt);
	vwmsg(fd, fmt, v);
}

char*
rmsg(int fd)
{
	int bytes;
	static char buf[8192];

	bytes = read(fd, buf, sizeof(buf));
	buf[bytes] = '\0';
	return buf;
}

char*
wrmsg(int fd, char *fmt, ...)
{
	va_list v;

	va_start(v, fmt);
	vwmsg(fd, fmt, v);
	return rmsg(fd);
}

int
connect(App *a, int netid)
{
	int fd, bytes;
	char b64[512];
	uchar buf[512];
	TLSconn *conn;

	fd = dial(netmkaddr(a->host, "tcp", "6697"), nil, nil, nil);
	if(fd == -1)
		error("Could not connect");
	conn = emallocz(sizeof(*conn), 1);
	fd = tlsClient(fd, conn);
	free(conn);
	if(fd == -1)
		error("Could not negotiate tls connection");

	wmsg(fd, "CAP LS 302");
	wmsg(fd, "NICK %s", a->user);
	print(wrmsg(fd, "USER %s 0 * %s", a->user, a->user));

	print(wrmsg(fd, "CAP REQ :sasl"));

	print(wrmsg(fd, "AUTHENTICATE PLAIN\r\n"));

	bytes = snprint((char*)buf, sizeof(buf), "%c%s%c%s", '\0', a->user, '\0', a->passwd);
	enc64(b64, sizeof(b64), buf, bytes);
	print(wrmsg(fd, "AUTHENTICATE %s\r\n", b64));

	if(netid < 0){
		wmsg(fd, "CAP END");
		wmsg(fd, "BOUNCER LISTNETWORKS");
		return fd;
	}
	wmsg(fd, "BOUNCER BIND %d", netid);
	wmsg(fd, "CAP END");
	return fd;
}

void
readnetproc(void *a)
{
	Net *net;
	char *in;

	net = a;
	for(;;){
		in = rmsg(net->fd);
		if(strcmp(in, "PING") == 0){
			wmsg(net->fd, "PONG%s", in+4);
			continue;
		}
	}
}

void
threadmain(int argc, char **argv)
{
	App app;
	UserPasswd *up;
	int fd;

	app.user = getenv("user");
	ARGBEGIN{
	default:
		usage();
	case 'u':
		app.user = EARGF(usage());
		break;
	}ARGEND
	if (argc != 1)
		usage();
	app.host = argv[0];
	up = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=irc user=%s", app.host, app.user);
	if(up == nil)
		error("could not get a password");
	app.passwd = up->passwd;
	fd = connect(&app, 3);
	for(int i = 0; i < 10000; i++){
		print(rmsg(fd));
	}
	free(up);
	close(fd);
	threadexits(0);
}