jacc

Jabber/XMPP client for Plan 9
git clone git://r-36.net/jacc
Log | Files | Refs | LICENSE

jacs.c (4764B)


      1 /*
      2  * Copy me if you can.
      3  * by 20h
      4  */
      5 
      6 #include <u.h>
      7 #include <libc.h>
      8 #include <auth.h>
      9 #include <mp.h>
     10 #include <libsec.h>
     11 #include "xmlpull.h"
     12 #include "jacs.h"
     13 #include "dat.h"
     14 #include "roster.h"
     15 #include "recv.h"
     16 
     17 #define NAME "jacs - Jabber Service Registry for Plan9"
     18 #define VERSION "2nd ed"
     19 #define OS "Plan9 4th ed"
     20 
     21 int
     22 xmljacc(int sock)
     23 {
     24 	return fprint(sock, "<?xml version=\"1.0\"?>\n");
     25 }
     26 
     27 int
     28 loginjacc(int sock, char *serv)
     29 {
     30 	return fprint(sock, "<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\""
     31 						" xmlns=\"jabber:client\" to=\"%s\">\n", serv);
     32 }
     33 
     34 int
     35 userjacc(int sock, char *user, char *pass, char *res)
     36 {
     37 	return fprint(sock, "<iq type=\"set\" id=\"auth_1\">\n"
     38 						"<query xmlns=\"jabber:iq:auth\">\n"
     39 						"<username>%s</username>\n"
     40 						"<password>%s</password>\n"
     41 						"<resource>%s</resource>\n"
     42 						"</query>\n"
     43 						"</iq>\n", user, pass, res);
     44 }
     45 
     46 int
     47 presencejacc(int sock, char *stat, char *show, char *from, char *to)
     48 {
     49 	return fprint(sock, "<presence%s%s%s%s%s%s>\n"
     50 						"<show>%s</show>\n"
     51 						"<status>%s</status>\n"
     52 						"<priority>1</priority>\n"
     53 						"</presence>\n", (from != nil) ? " from=\"" : "",
     54 										 (from != nil) ? from : "",
     55 										 (from != nil) ? "\"" : "",
     56 										 (to != nil) ? " to=\"" : "",
     57 										 (to != nil) ? to : "",
     58 										 (to != nil) ? "\"" : "", 
     59 										 (show != nil) ? show : "",
     60 										 (stat != nil) ? stat : "");
     61 }
     62 
     63 int
     64 versionjacc(int sock, char *from, char *to, char *id)
     65 {
     66 	return fprint(sock, "<iq from=\"%s\" type=\"result\" id=\"%s\" to=\"%s\">\n"
     67 						"<query xmlns=\"jabber:iq:version\">\n"
     68 						"<name>" NAME "</name>\n"
     69 						"<version>" VERSION "</version>\n"
     70 						"<os>" OS "</os>\n"
     71 						"</query>\n"
     72 						"</iq>\n", from, id, to);
     73 }
     74 
     75 int
     76 featuresjacc(int sock, char *from, char *to, char *id)
     77 {
     78 	return fprint(sock, "<iq from=\"%s\" type=\"result\" to=\"%s\" id=\"%s\">\n"
     79 						"<query xmlns=\"http://jabber.org/protocol/disco#info\">\n"
     80 						"</query>\n"
     81 						"</iq>\n", from, to, id);
     82 }
     83 
     84 int
     85 answersjacc(int sock, char *who, char *t, char *id, ilist *l)
     86 {
     87 	fprint(sock, "<iq type=\"set\" to=\"%s\" id=\"%s\">\n"
     88 				 "<query xmlns=\"%s\">\n", who, id, t);
     89 	for(; l; l = l->n)
     90 		fprint(sock, "<%s>%s</%s>\n", l->name, l->val, l->name);
     91 
     92 	return fprint(sock, "</query>\n"
     93 						"</iq>\n");
     94 }
     95 
     96 int
     97 xmlnsjacc(int sock, char *who, char *t, char *id)
     98 {
     99 	return fprint(sock, "<iq type=\"get\" to=\"%s\" id=\"%s\">\n"
    100 						"<query xmlns=\"%s\"/>\n"
    101 						"</iq>\n", who, id, t);
    102 }
    103 
    104 int
    105 xmlnsnegjacc(int sock, char *who, char *t, char* id)
    106 {
    107 	return fprint(sock, "<iq type=\"set\" to=\"%s\" id=\"%s\">\n"
    108 						"<query xmlns=\"%s\">\n"
    109 						"<remove/>\n"
    110 						"</query>\n"
    111 						"</iq>\n", who, id, t);
    112 }
    113 
    114 void
    115 usage(void)
    116 {
    117 	print("usage: jacs [-dtu] [-e dest] [-s tosrv] [-r res] net!server!port\n");
    118 	exits(0);
    119 }
    120 
    121 int
    122 main(int argc, char *argv[])
    123 {
    124 	char *server, *user, *lbl, *b, *dest, *buf, *toserver;
    125 	int sock, ts, tls, debug, unreg;
    126 	UserPasswd *i;
    127 	TLSconn conn;
    128 	jabberc *me;
    129 
    130 	tls = 0;
    131 	b = nil;
    132 	dest = nil;
    133 	unreg = 0;
    134 	debug = 0;
    135 	toserver = nil;
    136 
    137 	ARGBEGIN {
    138 	case 't':
    139 		tls = 1;
    140 		break;
    141 	case 'r':
    142 		b = EARGF(usage());
    143 		break;
    144 	case 'e':
    145 		dest = EARGF(usage());
    146 		break;
    147 	case 'u':
    148 		unreg = 1;
    149 		break;
    150 	case 'd':
    151 		debug = 1;
    152 		break;
    153 	case 's':
    154 		toserver = EARGF(usage());
    155 		break;
    156 	default:
    157 		usage();
    158 	} ARGEND;
    159 
    160 	if(argc < 1 || dest == nil)
    161 		usage();
    162 	server = strdup(argv[0]);
    163 
    164 	lbl = getwindowlbl();
    165 	user = reallocj(nil, strlen(server) + 9, 2);
    166 	snprint(user, strlen(server) + 8, "jacs - %s", server);
    167 	setwindowlbl(user);
    168 	free(user);
    169 
    170 	i = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=jabber", server);
    171 	if(i == nil)
    172 		sysfatal("auth_getuserpasswd: %r");
    173 
    174 	sock = dial(netmkaddr(server, "tcp", tls ? "5223" : "5222"), 0, 0, 0);
    175 	if(sock < 0)
    176 		sysfatal("dial: &r");
    177 
    178 	if(tls){
    179 		ts = tlsClient(sock, &conn);
    180 		if(ts < 0)
    181 			sysfatal("tlsClient: %r");
    182 		sock = ts;
    183 
    184 		if(conn.cert != nil)
    185 			free(conn.cert);
    186 	}
    187 
    188 	buf = strchr(server, '!');
    189 	if(buf != nil) {
    190 		*buf++ = '\0';
    191 		user = strchr(buf, '!');
    192 		if(user != nil)
    193 			*user = '\0';
    194 		user = strdup(buf);
    195 		free(server);
    196 		server = user;
    197 	}
    198 
    199 	if(toserver == nil)
    200 		toserver = server;
    201 
    202 	me = mkjabberc();
    203 	me->dest = strdup(dest);
    204 	me->show = strdup("Online");
    205 	me->stat = strdup("Online");
    206 	me->name = strdup(i->user);
    207 	me->serv = strdup(toserver);
    208 
    209 	if(b != nil)
    210 		me->reso = strdup(b);
    211 	else
    212 		me->reso = strdup("Plan9-Service");
    213 	me->jid = printjid(me->name, me->serv, me->reso);
    214 	me->debug = debug;
    215 	me->unreg = unreg;
    216 
    217 	free(buf);
    218 
    219 	if(recvjacc(sock, me, i->passwd) < 0)
    220 		perror("recv_jacc");
    221 
    222 	if(lbl != nil){
    223 		setwindowlbl(lbl);
    224 		lbl = nil;
    225 		free(lbl);
    226 	}
    227 
    228 	freejabberc(me);
    229 	exits(0);
    230 	return 0;
    231 }