shithub: mez

ref: a4d0372d0f1916d1d9df34c4fe4ae7a98c8de020
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"

Image *nicksscreen, *cmdscreen, *nickscols[NCOL], *cols[NCOL], *cmdcols[NCOL];
char *nickswsys = "/mnt/nickswsys", *cmdwsys = "/mnt/cmdwsys";
Screen *_nicksscreen, *_cmdscreen;

enum {
	MOUSE,
	KEYBD,
	RESIZE,
	NICKSMOUSE,
	NICKSKEYBD,
	NICKSRESIZE,
	CMDMOUSE,
	CMDKEYBD,
	CMDRESIZE,
	NCHAN,
};

void
usage(void)
{
	fprint(2, "usage: %s [-u user] host netid\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*
erealloc(void *ptr, ulong size)
{
	void *p;

	if((p = realloc(ptr, size)) == nil)
		error("Out of memory there");
	setmalloctag(p, getcallerpc(&ptr));
	return p;
}

void
vwmsg(Net *n, char *fmt, va_list v)
{
	char *e;

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

void
wmsg(Net *n, char *fmt, ...)
{
	va_list v;

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

char*
rmsg(Net *n)
{
	int bytes;

	bytes = read(n->fd, n->in, sizeof(n->in));
	n->in[bytes-2] = '\n';
	n->in[bytes-1] = '\0';
	return n->in;
}

char*
wrmsg(Net *n, char *fmt, ...)
{
	va_list v;

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

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

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

	wmsg(n, "CAP LS 302");
	wmsg(n, "NICK %s", a->user);
	print(wrmsg(n, "USER %s 0 * %s", a->user, a->user));
	print(wrmsg(n, "CAP REQ :sasl"));
	print(wrmsg(n, "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(n, "AUTHENTICATE %s\r\n", b64));

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

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

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

Msg*
parse(char *s)
{
}

void
createwindow(char *wsys, Image **screen, Screen **_screen, Rectangle r)
{
	static char s[512];
	char *wsysv;
	int fd;

	if((wsysv = getenv("wsys")) == nil)
		sysfatal("cannot find $wsys: %r");
	if((fd = open(wsysv, ORDWR)) < 0)
		sysfatal("cannot open $wsys: %r");
	free(wsysv);
	snprint(s, sizeof(s), "new -r %d %d %d %d", r.min.x, r.min.y, r.max.x, r.max.y);
	if(mount(fd, -1, wsys, MREPL, s) < 0)
		sysfatal("cannot create new window: %r");
	close(fd);
	snprint(s, sizeof(s), "%s/label", wsys);
	if((fd = open(s, OWRITE)) < 0)
		sysfatal("cannot open label: %r");
	write(fd, "guitest", sizeof("guitest"));
	close(fd);
	snprint(s, sizeof(s), "%s/winname", wsys);
	if(gengetwindow(display, s, screen, _screen, Refnone) < 0)
		sysfatal("cannot get window: %r");
}

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

	app.user = getenv("user");
	ARGBEGIN{
	default:
		usage();
	case 'u':
		app.user = EARGF(usage());
		break;
	}ARGEND
	if (argc != 2)
		usage();
	app.host = argv[0];
	netid = strtol(argv[1], nil, 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;
	n = connect(&app, netid);
	for(int i = 0; i < 10000; i++){
		print(rmsg(n));
	}
	free(up);
	close(n->fd);
	free(n);
	threadexits(0);
}