<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/stassats/jacc.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/stassats/jacc.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
/*
 * Copy me if you can.
 * by 20h
 */

#include &lt;u.h&gt;
#include &lt;libc.h&gt;
#include &lt;auth.h&gt;
#include &lt;mp.h&gt;
#include &lt;libsec.h&gt;
#include "xmlpull.h"
#include "jacc.h"
#include "dat.h"
#include "roster.h"
#include "recv.h"

#define NAME "jacc - Jabber Client for Plan9"
#define VERSION "3rd ed"
#define OS "Plan 9 4th ed"

extern int doignore;

int
xmljacc(int sock)
{
	return fprint(sock, "&lt;?xml version=\"1.0\"?&gt;\n");
}

int
loginjacc(int sock, char *serv)
{
	return fprint(sock, "&lt;stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\""
						" xmlns=\"jabber:client\" to=\"%s\"&gt;\n", serv);
}

int
userjacc(int sock, char *user, char *pass, char *res)
{
	return fprint(sock, "&lt;iq type=\"set\" id=\"auth_1\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:auth\"&gt;\n"
						"&lt;username&gt;%s&lt;/username&gt;\n"
						"&lt;password&gt;%s&lt;/password&gt;\n"
						"&lt;resource&gt;%s&lt;/resource&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", user, pass, res);
}

int
versionjacc(int sock, char *from, char *to, char *id)
{
	return fprint(sock, "&lt;iq from=\"%s\" type=\"result\" id=\"%s\" to=\"%s\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:version\"&gt;\n"
						"&lt;name&gt;" NAME "&lt;/name&gt;\n"
						"&lt;version&gt;" VERSION "&lt;/version&gt;\n"
						"&lt;os&gt;" OS "&lt;/os&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", from, (id == nil) ? "" : id, to);
}

int
featuresjacc(int sock, char *from, char *to, char *id)
{
	return fprint(sock, "&lt;iq from=\"%s\" type=\"result\" to=\"%s\" id=\"%s\"&gt;\n"
						"&lt;query xmlns=\"http://jabber.org/protocol/disco#info\"&gt;\n"
						"&lt;identity category=\"client\" type=\"pc\"/&gt;\n"
						"&lt;feature var=\"jabber:iq:time\"/&gt;\n"
						"&lt;feature var=\"jabber:iq:version\"/&gt;\n"
						"&lt;feature var=\"http://jabber.org/protocol/muc\"/&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", from, to, (id == nil) ? "" : id);
}

int
timejacc(int sock, char *from, char *to, char *id)
{
	Tm *lo, *gm;

	lo = localtime(time(0));
	gm = gmtime(time(0));
	
	return fprint(sock, "&lt;iq from=\"%s\" type=\"result\" to=\"%s\" id=\"%s\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:time\"&gt;\n"
						"&lt;utc&gt;%.4d%.2d%.2dT%.2d:%.2d:%.2d&lt;/utc&gt;\n"
						"&lt;display&gt;%s %s %.2d %.2d:%.2d:%.2d %.4d&lt;/display&gt;\n"
						"&lt;tz&gt;%s&lt;/tz&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", from, to, (id == nil) ? "" : id, gm-&gt;year + 1900, 
						gm-&gt;mon + 1, gm-&gt;mday, gm-&gt;hour, gm-&gt;min, 
						gm-&gt;sec, getday(lo-&gt;wday), getmonth(lo-&gt;mon), 
						lo-&gt;mday, lo-&gt;hour, lo-&gt;min, lo-&gt;sec, 
						lo-&gt;year + 1900, lo-&gt;zone);
}

int
lastjacc(int sock, char *from, char *to, char *id, int d)
{
	return fprint(sock, "&lt;iq from=\"%s\" type=\"result\" to=\"%s\" id=\"%s\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:last\" seconds=\"%d\"/&gt;\n"
						"&lt;/iq&gt;\n", from, to, (id == nil) ? "" : id, d);
}

int
registerjacc(int sock, char *serv, char *user, char *pass)
{
	return fprint(sock, "&lt;iq type=\"set\" id=\"req\" to=\"%s\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:register\"&gt;\n"
						"&lt;username&gt;%s&lt;/username&gt;\n"
						"&lt;password&gt;%s&lt;/password&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", serv, user, pass);
}

int
vcardgetjacc(int sock, char *from, char *type)
{
	return fprint(sock, "&lt;iq %s=\"%s\" type=\"get\" id=\"v1\"&gt;\n"
						"&lt;vCard xmlns=\"vcard-temp\"/&gt;\n"
						"&lt;/iq&gt;\n", type, from);
}

int
vcardsetjacc(int sock, char *from, int fd)
{
	fprint(sock, "&lt;iq from=\"%s\" type=\"set\" id=\"v2\"&gt;\n"
				 "&lt;vCard xmlns=\"vcard-temp\"&gt;\n", from);
	readwrite(sock, fd);

	return fprint(sock, "&lt;/vCard&gt;\n"
						"&lt;/iq&gt;\n");
}

int
presencejacc(int sock, char *stat, char *show, char *from, char *to)
{
	return fprint(sock, "&lt;presence%s%s%s%s%s%s&gt;\n"
						"&lt;show&gt;%s&lt;/show&gt;\n"
						"&lt;status&gt;%s&lt;/status&gt;\n"
						"&lt;priority&gt;9&lt;/priority&gt;\n"
						"&lt;/presence&gt;\n", (from != nil) ? " from=\"" : "",
										 (from != nil) ? from : "",
										 (from != nil) ? "\"" : "",
										 (to != nil) ? " to=\"" : "",
										 (to != nil) ? to : "",
										 (to != nil) ? "\"" : "", 
										 (show != nil) ? show : "",
										 (stat != nil) ? stat : "");
}

int
presencetypejacc(int sock, char *from, char *to, char *type)
{
	return fprint(sock, "&lt;presence type=\"%s\" from=\"%s\" to=\"%s\"/&gt;\n",
						type, from, to);
}

int
rosterjacc(int sock)
{
	return fprint(sock, "&lt;iq type=\"get\" id=\"auth_2\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:roster\"/&gt;\n"
						"&lt;/iq&gt;\n");
}

int
messagejacc(int sock, char *from, char *to, char *msg, char *type)
{
	return fprint(sock, "&lt;message from=\"%s\" to=\"%s\" type=\"%s\"&gt;\n"
						"&lt;body&gt;%s&lt;/body&gt;\n"
						"&lt;/message&gt;\n", from, to, type, msg);
}

int
addbuddyjacc(int sock, char *jid, char *na, char *group)
{
	if(na == nil){
		na = jid;
		jid = strchr(na, '@');
	
		if(jid == nil)
			return -1;
		*jid++ = '\0';
	
		return fprint(sock, "&lt;iq type=\"set\"&gt;\n"
		 			 "&lt;query xmlns=\"jabber:iq:roster\"&gt;\n"
					 "&lt;item jid=\"%s@%s\" name=\"%s\"/&gt;\n"
					 "%s%s%s"
					 "&lt;/query&gt;\n"
					 "&lt;/iq&gt;\n", na, jid, na,
						(group != nil) ? "&lt;group&gt;" : "",
						(group != nil) ? group : "",
						(group != nil) ? "&lt;/group&gt;\n" : "");
	}
		
	return fprint(sock, "&lt;iq type=\"set\"&gt;\n"
		 		 "&lt;query xmlns=\"jabber:iq:roster\"&gt;\n"
				 "&lt;item jid=\"%s\" name=\"%s\"/&gt;\n"
				 "%s%s%s"
				 "&lt;/query&gt;\n"
				 "&lt;/iq&gt;\n", jid, na,
						(group != nil) ? "&lt;group&gt;" : "",
						(group != nil) ? group : "",
						(group != nil) ? "&lt;/group&gt;\n" : "");
}

int
delbuddyjacc(int sock, char *jid)
{
	return fprint(sock, "&lt;iq type=\"set\"&gt;\n"
						"&lt;query xmlns=\"jabber:iq:roster\"&gt;\n"
						"&lt;item jid=\"%s\" subscription=\"remove\"/&gt;\n"
						"&lt;/query&gt;\n"
						"&lt;/iq&gt;\n", jid);
}

int
xmlnsjacc(int sock, char *who, char *t, char *id)
{
	return fprint(sock, "&lt;iq type=\"get\" to=\"%s\" id=\"%s\"&gt;\n"
						"&lt;query xmlns=\"%s\"/&gt;\n"
						"&lt;/iq&gt;\n", who, id, t);
}

void
printrostern(rostern *r, char *w)
{
	char *tmstmp;

	tmstmp = mktmstmp('(', ')');
	while(r != nil){
		if(w != nil){
			if(r-&gt;status != nil)
				if(!strcmp(r-&gt;status, w))
					goto got_one;
			if(r-&gt;name != nil)
				if(!strcmp(r-&gt;name, w))
					goto got_one;
			if(r-&gt;jid != nil)
				if(!strcmp(r-&gt;jid, w))
					goto got_one;
			if(r-&gt;show != nil)
				if(!strcmp(r-&gt;show, w))
					goto got_one;
			if(r-&gt;group != nil)
				if(!strcmp(r-&gt;group, w))
					goto got_one;
		} else {
got_one:
			print("%s%s/%s on %s -&gt; %s/%s\n", tmstmp, r-&gt;name, r-&gt;jid, r-&gt;group, r-&gt;show, r-&gt;status);	
		}

		r = r-&gt;n;
	}

	return;
}

void
usage(void)
{
	print("usage: [-dgit] [-r res] [-s tosrv] [net!]server[!port]\n");
	exits(0);
}

void admin (int sock, char *id, char *room, char *item)
{
	fprint(sock, "&lt;iq id=\"%s\" to=\"%s\" type=\"set\"&gt;&lt;query xmlns=\"http://jabber.org/protocol/muc#admin\"&gt;&lt;item %s /&gt;&lt;/query&gt;&lt;/iq&gt;",  id, room, item);
}



int
main(int argc, char *argv[])
{
	char *server, *user, *lbl, *b, *tmstmp, *buf, *toserver, *role, *tmp;
	int sock, ts, reg, debug, tls;
	UserPasswd *i;
	TLSconn conn;
	jabberc *me;

	tls = 0;
	b = nil;
	reg = 0;
	debug = 0;
	toserver = nil;

	ARGBEGIN {
	case 't':
		tls = 1;
		break;
	case 'r':
		b = EARGF(usage());
		break;
	case 'g':
		reg = 1;
		break;
	case 'd':
		debug = 1;
		break;
	case 'i':
		doignore = 1;
		break;
	case 's':
		toserver = EARGF(usage());
		break;
	default:
		usage();
	} ARGEND;

	if(argc &lt; 1)
		usage();
	server = strdup(argv[0]);

	lbl = getwindowlbl();
	user = reallocj(nil, strlen(server) + 9, 2);
	snprint(user, strlen(server) + 8, "jacc - %s", server);
	setwindowlbl(user);
	free(user);

	i = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=jabber", server);
	if(i == nil)
		sysfatal("auth_getuserpasswd: %r");

	sock = dial(netmkaddr(server, "tcp", tls ? "5223" : "5222"), 0, 0, 0);
	if(sock &lt; 0)
		sysfatal("dial: %r");

	if(tls){
		ts = tlsClient(sock, &amp;conn);
		if(ts &lt; 0)
			sysfatal("tlsClient: %r");
		sock = ts;

		if(conn.cert != nil)
			free(conn.cert);
	}

	buf = strchr(server, '!');
	if(buf != nil) {
		*buf++ = '\0';
		user = strchr(buf, '!');
		if(user != nil)
			*user = '\0';
		user = strdup(buf);
		free(server);
		server = user;
	}

	if(toserver == nil)
		toserver = server;

	me = mkjabberc();
	me-&gt;show = strdup("Online");
	me-&gt;stat = strdup("Online");
	me-&gt;name = strdup(i-&gt;user);
	me-&gt;serv = strdup(toserver);

	if(b != nil)
		me-&gt;reso = strdup(b);
	else
		me-&gt;reso = strdup("Plan9");
	me-&gt;jid = printjid(me-&gt;name, me-&gt;serv, me-&gt;reso);
	me-&gt;debug = debug;
	me-&gt;reg = reg;
	me-&gt;last = time(0);

	free(server);

	ts = getpid();

#ifdef PLAN9PORT
	switch(fork()) {
#endif
#ifndef PLAN9PORT
	switch(rfork(RFPROC|RFFDG|RFMEM)) {
#endif
	case -1:
		sysfatal("fork: %r");
	case 0:
		if(recvjacc(sock, me, i-&gt;passwd) &lt; 0)
			perror("recvjacc");

		if(lbl != nil){
			setwindowlbl(lbl);
			lbl = nil;
			free(lbl);
		}
		killproc(ts);
		exits(0);
	default:
		user = reallocj(nil, 1025, 2);
		buf = nil;
		while(sock &gt; 0 &amp;&amp; user != nil){
			ts = -1;
			memset(user, 0, 1025);

			while(read(0, &amp;user[++ts], 1) &amp;&amp; ts &lt; 1024 &amp;&amp; sock &gt; 0)
				if(user[ts] == '\n')
					break;
			user[ts] = '\0';
			me-&gt;last = time(0);

			tmstmp = mktmstmp('(', ')');
			if(user[0] != '/'){
				if(buf != nil){
					b = filterhin(user, 0);
					messagejacc(sock, me-&gt;jid, buf, b, "chat");
					print("%s\n", tmstmp);
					free(b);
				}
				free(tmstmp);
				continue;
			}
			if (user[1] == 'x'){
				b = getarg(user, 1, 0);
				if(b != nil){
					if (strcmp(b, "join") == 0){
						free(b);

						server = getarg(user, 2, 0);
                 
						if(server != nil){
							b = getarg(user, 3, 0);                         
							if(b == nil)
								b = strdup(me-&gt;name);

							fprint(sock, "&lt;presence to=\"%s/%s\"/&gt;",  server, b);
							free (server);
							free(b);
						}
					} 
					else
					if (strcmp(b, "leave") == 0){
						free(b);				
						server = getarg(user, 2, 0); 
						if(server != nil) {
							fprint(sock,
								"&lt;presence to='%s' type='unavailable'/&gt;",  server);
							free (server);
						}
											
					}
					else
					if (strcmp(b, "say") == 0){
						free(b);
						server = getarg(user, 2, 0);                    
						if(server != nil){                               
							b = getarg(user, 3, 2);                         
							if(b != nil){
								messagejacc(sock,
									 	me-&gt;jid, server, b, "groupchat");
								free(b);		
							}
							free(server);
						}
					}
					else
					if (strcmp(b, "priv") == 0){
						free(b);
						server = getarg(user, 2, 0);                    
						if(server != nil){
							role = getarg(user, 3, 0);
							if(role != nil){
								b = getarg(user, 4, 2);
								if(b != nil){
									tmp = server;
									server = smprint("%s/%s", server, role);
									free(tmp);

									messagejacc(sock,
									 		me-&gt;jid, server, b, "chat");
									free(b);		
								}
								free(role);
							}
							free(server);
						}
					}
					else
					if (strcmp(b, "role") == 0){
						free(b);
						server = getarg(user, 2, 0);                
						if(server != nil){    
                           				role = getarg(user, 3, 0);
							if(role != nil){
								b = getarg(user, 4, 2);
								if(b != nil){
									tmp = b;								
									b = smprint("nick='%s' role='%s'", b, role);
									free(tmp);

									admin(sock, role, server, b);
									free(b);					
								}
								free(role);
							}                    
							free(server);
						}
					}
					else
					if (strcmp(b, "affil") == 0){
						free(b);
						server = getarg(user, 2, 0);                    
						if(server != nil){
							role = getarg(user, 3, 0);
							if(role != nil){
								b = getarg(user, 4, 2);                         
								if(b != nil){
									tmp = b;
									b = smprint("jid='%s' affiliation='%s'", b, role);
									free(tmp);

									admin(sock, role, server, b);
									free(b);					
								}
								free(role);
							}                    
							free(server);
						}
					}
					else
						free(b);
				}
			}
			else
			switch(user[1]){
			case 'h':
			case 'H':
				print("%sHelp for jacc:\n", tmstmp);
				print("%s  /a [+|-|*]jid - authenticate jid\n", tmstmp);
				print("%s  /b - turn debugging on or off\n", tmstmp);
				print("%s  /c file - set vcard on server\n", tmstmp);
				print("%s  /d jid [feat] - do a discovery request\n", tmstmp);
				print("%s  /e jid - get time from jid\n", tmstmp);
				print("%s  /g jid - get agents information from jid\n", tmstmp);
				print("%s  /h - print out this help\n", tmstmp);
				print("%s  /i jid - get version of jid\n", tmstmp);
				print("%s  /l [status|jid|user] - list the roster\n", tmstmp);
				print("%s  /m jid - send a message to jid\n", tmstmp);
				print("%s  /p [show] [status] - set status and show\n", tmstmp);
				print("%s  /q - quit jacc\n", tmstmp);
				print("%s  /s [jid] - set active jid\n", tmstmp);
				print("%s  /t jid - get idle time of jid\n",tmstmp);
				print("%s  /u [+|-]jid [alias] - manage roster\n", tmstmp);
				print("%s  /v [jid] - get vcard from jid\n", tmstmp);

				print("%s  /x command - operate with groupchat\n", tmstmp);
				print("%s    commands:\n", tmstmp);
				print("%s  groupchat - leave groupchat\n", tmstmp);
				print("%s  join groupchat [nick] - join to the groupchat\n", tmstmp);
//				print("%s  names groupchat - occupants' list\n", tmstmp);
				print("%s  say groupchat - send a message to groupchat\n", tmstmp);
				print("%s  priv groupchat nick - send a private message to occupant\n", tmstmp);
				print("%s  leave groupchat - leave groupchat\n", tmstmp);
				print("%s  affil groupchat affilation jid - set affilation\n", tmstmp);
				print("%s  role groupchat role nick - set role\n", tmstmp);
				break;

			case 'q':
			case 'Q':
				fprint(sock, "&lt;presence from=\"%s\" type=\"unavailable\"/&gt;",
								me-&gt;jid);
				fprint(sock, "&lt;/stream:stream&gt;");
				free(user);
				user = nil;
				break;
			case 's':
			case 'S':
				server = getarg(user, 1, 0);
				if(server == nil){
					print("%s%s\n", tmstmp, (buf != nil) ? buf : "&lt;nil&gt;");
					break;
				}

				buf = setchan(buf, namerostern(me-&gt;rost, nil, server));
				free(server);
					break;
			case 'l':
			case 'L':
				server = getarg(user, 1, 0);

				printrostern(me-&gt;rost, server);

				if(server != nil)
					free(server);
				break;
			case 'm':
			case 'M':
				server = getarg(user, 1, 0);
				if(server != nil){

					b = getarg(user, 2, 2);
					if(b != nil){
						messagejacc(sock, me-&gt;jid, namerostern(me-&gt;rost, nil, server), b, "normal");
						free(b);
					}

					free(server);
				}
				break;
			case 'p':
			case 'P':
				server = getarg(user, 1, 0);
				if(server == nil){
					print("%s%s\n", tmstmp, me-&gt;stat);
					break;
				}

				b = getarg(user, 2, 2);
				if(b != nil){
					presencejacc(sock, b, server, nil, nil);
					free(me-&gt;stat);
					me-&gt;stat = strdup(b);
				} else
					presencejacc(sock, nil, server, nil, nil);
				free(me-&gt;show);
				me-&gt;show = strdup(server);
				statusrostern(me-&gt;rost, me-&gt;jid, me-&gt;jid, server, b);
				free(server);
				break;
			case 'c':
			case 'C':
				server = getarg(user, 1, 0);
				if(server != nil){
					ts = open(server, OREAD);
					if(ts &gt;= 0){
						vcardsetjacc(sock, me-&gt;jid, ts);
						close(ts);
					}
					free(server);
				}
				break;
			case 'v':
			case 'V':
				server = getarg(user, 1, 0);
				if(server == nil){
					vcardgetjacc(sock, me-&gt;jid, "from");
					break;
				}

				vcardgetjacc(sock, namerostern(me-&gt;rost, nil, server), "to");
				print("Vcard of: %s\n", namerostern(me-&gt;rost, nil, server));
				free(server);
				break;
			case 'u':
			case 'U':
				server = getarg(user, 1, 0);
				if(server != nil){
					if(server[0] == '-')
						delbuddyjacc(sock, namerostern(me-&gt;rost, server + 1, server + 1));
					else {
						b = getarg(user, 2, 0);
						if(server[0] == '+')
							addbuddyjacc(sock, server + 1, b, nil);
						else
							addbuddyjacc(sock, server, b, nil);
					}
					free(server);
				}
				break;
			case 'a':
			case 'A':
				server = getarg(user, 1, 0);
				if(server != nil){
					switch(server[0]){
					case '+':
						presencetypejacc(sock, me-&gt;jid, namerostern(me-&gt;rost, nil, server + 1), "subscribed");
						break;
					case '-':
						presencetypejacc(sock, me-&gt;jid, namerostern(me-&gt;rost, nil, server + 1), "unsubscribe");
						break;
					case '*':
						presencetypejacc(sock, me-&gt;jid, namerostern(me-&gt;rost, nil, server + 1), "subscribe");
						break;
					default:
						presencetypejacc(sock, me-&gt;jid, namerostern(me-&gt;rost, nil, server), "subscribed");
						break;
					}
					free(server);
				}
				break;
			case 'd':
			case 'D':
				server = getarg(user, 1, 0);
				if(server != nil){
					b = getarg(user, 2, 2);
					if(b == nil)
						b = strdup("info");

					free(tmstmp);
					tmstmp = reallocj(nil, 35 + strlen(b), 2);
					sprint(tmstmp, "http://jabber.org/protocol/disco#%s", b);

					xmlnsjacc(sock, server, tmstmp, "disco0");
					free(b);
					free(server);
				}
				break;
			case 'b':
			case 'B':
				if(me-&gt;debug == 0)
					me-&gt;debug = 1;
				else
					me-&gt;debug = 0;
				print("%sDebug: %c\n", tmstmp, me-&gt;debug);
				break;
			case 't':
			case 'T':
				server = getarg(user, 1, 0);
				if(server != nil){
					xmlnsjacc(sock, namerostern(me-&gt;rost, nil, server), "jabber:iq:last", "last0");
					free(server);
				}
				break;
			case 'i':
			case 'I':
				server = getarg(user, 1, 0);
				if(server != nil){
					xmlnsjacc(sock, namerostern(me-&gt;rost, nil, server), "jabber:iq:version", "version0");
					free(server);
				}
				break;
			case 'e':
			case 'E':
				server = getarg(user, 1, 0);
				if(server != nil){
					xmlnsjacc(sock, namerostern(me-&gt;rost, nil, server), "jabber:iq:time", "time0");
					free(server);
				}
				break;
			case 'g':
			case 'G':
				server = getarg(user, 1, 0);
				if(server != nil){
					xmlnsjacc(sock, namerostern(me-&gt;rost, nil, server), "jabber:iq:agents", "agents0");
					free(server);
				}
				break;

			default:
				break;
			}
			free(tmstmp);
		}

		wait();
		if(lbl != nil){
			setwindowlbl(lbl);
			lbl = nil;
			free(lbl);
		}
		break;
	}

	freejabberc(me);
	exits(0);
	return 0;
}
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>