--- a/mcabber/src/jabglue.c Sun Nov 27 00:17:51 2005 +0100
+++ b/mcabber/src/jabglue.c Sun Nov 27 00:19:07 2005 +0100
@@ -71,30 +71,6 @@
scr_LogPrint(LPRINT_DEBUG, "%03s: %s", ((io == 0) ? "OUT" : "IN"), buf);
}
-/*
-static void jidsplit(const char *jid, char **user, char **host,
- char **res)
-{
- char *tmp, *ptr;
- tmp = strdup(jid);
-
- if ((ptr = strchr(tmp, '/')) != NULL) {
- *res = strdup(ptr+1);
- *ptr = 0;
- } else
- *res = NULL;
-
- if ((ptr = strchr(tmp, '@')) != NULL) {
- *host = strdup(ptr+1);
- *ptr = 0;
- } else
- *host = NULL;
-
- *user = strdup(tmp);
- free(tmp);
-}
-*/
-
// jidtodisp(jid)
// Strips the resource part from the jid
// The caller should g_free the result after use.
@@ -305,22 +281,22 @@
switch(st) {
case away:
xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "away",
- (unsigned) -1);
+ (unsigned) -1);
break;
case dontdisturb:
xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "dnd",
- (unsigned) -1);
+ (unsigned) -1);
break;
case freeforchat:
xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "chat",
- (unsigned) -1);
+ (unsigned) -1);
break;
case notavail:
xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "xa",
- (unsigned) -1);
+ (unsigned) -1);
break;
case invisible:
@@ -908,21 +884,465 @@
previous_state = state;
}
+static void handle_packet_iq(jconn conn, char *type, char *from,
+ xmlnode xmldata)
+{
+ char *p;
+ xmlnode x, y;
+ char *ns = NULL;
+ char *id=NULL;
+
+ if (!type)
+ return;
+
+ if (!strcmp(type, "result")) {
+
+ if ((p = xmlnode_get_attrib(xmldata, "id")) != NULL) {
+ int iid = atoi(p);
+
+ scr_LogPrint(LPRINT_DEBUG, "iid = %d", iid);
+ if (iid == s_id) {
+ if (!regmode) {
+ if (jstate == STATE_GETAUTH) {
+ if ((x = xmlnode_get_tag(xmldata, "query")) != NULL)
+ if (!xmlnode_get_tag(x, "digest")) {
+ jc->sid = 0;
+ }
+
+ s_id = atoi(jab_auth(jc));
+ jstate = STATE_SENDAUTH;
+ } else {
+ gotloggedin();
+ jstate = STATE_LOGGED;
+ }
+ } else {
+ regdone = TRUE;
+ }
+ return;
+ }
+
+ if (!strcmp(p, "VCARDreq")) {
+ x = xmlnode_get_firstchild(xmldata);
+ if (!x) x = xmldata;
+
+ //jhook.gotvcard(ic, x); TODO
+ scr_LogPrint(LPRINT_LOGNORM, "Got VCARD");
+ return;
+ } else if (!strcmp(p, "versionreq")) {
+ // jhook.gotversion(ic, xmldata); TODO
+ scr_LogPrint(LPRINT_LOGNORM, "Got version");
+ return;
+ }
+ }
+
+ if ((x = xmlnode_get_tag(xmldata, "query")) != NULL) {
+ p = xmlnode_get_attrib(x, "xmlns"); if (p) ns = p;
+
+ if (!strcmp(ns, NS_ROSTER)) {
+ gotroster(x);
+ } else if (!strcmp(ns, NS_AGENTS)) {
+ for (y = xmlnode_get_tag(x, "agent"); y; y = xmlnode_get_nextsibling(y)) {
+ const char *alias = xmlnode_get_attrib(y, "jid");
+
+ if (alias) {
+ const char *name = xmlnode_get_tag_data(y, "name");
+ const char *desc = xmlnode_get_tag_data(y, "description");
+ // TODO
+ // const char *service = xmlnode_get_tag_data(y, "service");
+ enum agtype atype = unknown;
+
+ if (xmlnode_get_tag(y, TMSG_GROUPCHAT)) atype = groupchat;
+ else if (xmlnode_get_tag(y, "transport")) atype = transport;
+ else if (xmlnode_get_tag(y, "search")) atype = search;
+
+ if (atype == transport) {
+ char *cleanjid = jidtodisp(alias);
+ roster_add_user(cleanjid, NULL, JABBER_AGENT_GROUP,
+ ROSTER_TYPE_AGENT);
+ g_free(cleanjid);
+ }
+ if (alias && name && desc) {
+ scr_LogPrint(LPRINT_LOGNORM,
+ "Agent: %s / %s / %s / type=%d",
+ alias, name, desc, atype);
+
+ if (atype == search) {
+ x = jutil_iqnew (JPACKET__GET, NS_SEARCH);
+ xmlnode_put_attrib(x, "to", alias);
+ xmlnode_put_attrib(x, "id", "Agent info");
+ jab_send(conn, x);
+ xmlnode_free(x);
+ }
+
+ if (xmlnode_get_tag(y, "register")) {
+ x = jutil_iqnew (JPACKET__GET, NS_REGISTER);
+ xmlnode_put_attrib(x, "to", alias);
+ xmlnode_put_attrib(x, "id", "Agent info");
+ jab_send(conn, x);
+ xmlnode_free(x);
+ }
+ }
+ }
+ }
+
+ /*
+ if (find(jhook.agents.begin(), jhook.agents.end(), DEFAULT_CONFSERV) == jhook.agents.end())
+ jhook.agents.insert(jhook.agents.begin(), agent(DEFAULT_CONFSERV, DEFAULT_CONFSERV,
+ _("Default Jabber conference server"), agent::atGroupchat));
+
+ */
+ } else if (!strcmp(ns, NS_SEARCH) || !strcmp(ns, NS_REGISTER)) {
+ p = xmlnode_get_attrib(xmldata, "id"); id = p ? p : (char*)"";
+
+ if (!strcmp(id, "Agent info")) {
+ // jhook.gotagentinfo(xmldata); TODO
+ scr_LogPrint(LPRINT_LOGNORM, "Got agent info");
+ } else if (!strcmp(id, "Lookup")) {
+ // jhook.gotsearchresults(xmldata); TODO
+ scr_LogPrint(LPRINT_LOGNORM, "Got search results");
+ } else if (!strcmp(id, "Register")) {
+ if (!from)
+ return;
+ x = jutil_iqnew(JPACKET__GET, NS_REGISTER);
+ xmlnode_put_attrib(x, "to", from);
+ xmlnode_put_attrib(x, "id", "Agent info");
+ jab_send(conn, x);
+ xmlnode_free(x);
+ }
+
+ }
+ }
+ } else if (!strcmp(type, "get")) {
+ p = xmlnode_get_attrib(xmldata, "id");
+ if (p) {
+ xmlnode z;
+
+ id = p;
+ x = xmlnode_new_tag("iq");
+ xmlnode_put_attrib(x, "type", "result");
+ xmlnode_put_attrib(x, "to", from);
+ xmlnode_put_attrib(x, "id", id);
+ xmlnode_put_attrib(x, "type", TMSG_ERROR);
+ y = xmlnode_insert_tag(x, TMSG_ERROR);
+ xmlnode_put_attrib(y, "code", "503");
+ xmlnode_put_attrib(y, "type", "cancel");
+ z = xmlnode_insert_tag(y, "feature-not-implemented");
+ xmlnode_put_attrib(z, "xmlns",
+ "urn:ietf:params:xml:ns:xmpp-stanzas");
+ jab_send(conn, x);
+ xmlnode_free(x);
+ }
+ } else if (!strcmp(type, "set")) {
+ /* FIXME: send error */
+ } else if (!strcmp(type, TMSG_ERROR)) {
+ if ((x = xmlnode_get_tag(xmldata, TMSG_ERROR)) != NULL)
+ display_server_error(x);
+ }
+}
+
+static void handle_packet_presence(jconn conn, char *type, char *from,
+ xmlnode xmldata)
+{
+ char *p, *r, *s;
+ const char *m;
+ xmlnode x, y;
+ const char *rname;
+ enum imstatus ust;
+ char bpprio;
+
+ r = jidtodisp(from);
+ if (type && !strcmp(type, TMSG_ERROR)) {
+ scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r);
+ if ((x = xmlnode_get_tag(xmldata, TMSG_ERROR)) != NULL)
+ display_server_error(x);
+ g_free(r);
+ return;
+ }
+
+ p = xmlnode_get_tag_data(xmldata, "priority");
+ if (p && *p) bpprio = (gchar)atoi(p);
+ else bpprio = 0;
+
+ ust = available;
+ p = xmlnode_get_tag_data(xmldata, "show");
+ if (p) {
+ if (!strcmp(p, "away")) ust = away;
+ else if (!strcmp(p, "dnd")) ust = dontdisturb;
+ else if (!strcmp(p, "xa")) ust = notavail;
+ else if (!strcmp(p, "chat")) ust = freeforchat;
+ }
+
+ if (type && !strcmp(type, "unavailable"))
+ ust = offline;
+
+ s = NULL;
+ p = xmlnode_get_tag_data(xmldata, "status");
+ if (p) {
+ s = from_utf8(p);
+ if (!s)
+ scr_LogPrint(LPRINT_LOG,
+ "Decoding of status message of <%s> has failed: %s",
+ from, p);
+ }
+
+ // Call hk_statuschange() if status has changed or if the
+ // status message is different
+ rname = strchr(from, '/');
+ if (rname) rname++;
+
+ // Check for MUC presence packet
+ // There can be multiple <x> tags!!
+ x = xmlnode_get_firstchild(xmldata);
+ for ( ; x; x = xmlnode_get_nextsibling(x)) {
+ if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
+ if ((p = xmlnode_get_attrib(x, "xmlns")) &&
+ !strcasecmp(p, "http://jabber.org/protocol/muc#user"))
+ break;
+ }
+ if (x) { // This is a MUC presence message
+ enum imrole mbrole = role_none;
+ const char *mbrjid = NULL;
+ const char *mbnewnick = NULL;
+ GSList *room_elt;
+ int log_muc_conf = settings_opt_get_int("log_muc_conf");
+
+ // Add room if it doesn't already exist
+ room_elt = roster_find(r, jidsearch, 0);
+ if (!room_elt)
+ room_elt = roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM);
+ else // Make sure this is a room (it can be a conversion user->room)
+ buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
+
+ // Get room member's information
+ y = xmlnode_get_tag(x, "item");
+ if (y) {
+ p = xmlnode_get_attrib(y, "role");
+ if (p) {
+ if (!strcmp(p, "moderator")) mbrole = role_moderator;
+ else if (!strcmp(p, "participant")) mbrole = role_participant;
+ else if (!strcmp(p, "visitor")) mbrole = role_visitor;
+ else if (!strcmp(p, "none")) mbrole = role_none;
+ else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
+ from, p);
+ }
+ p = xmlnode_get_attrib(y, "jid");
+ if (p) mbrjid = p;
+ p = xmlnode_get_attrib(y, "nick");
+ if (p) mbnewnick = p;
+ }
+
+ // Check for nickname change
+ y = xmlnode_get_tag(x, "status");
+ if (y && mbnewnick) {
+ p = xmlnode_get_attrib(y, "code");
+ if (p && !strcmp(p, "303")) {
+ gchar *mbuf;
+ gchar *newname_noutf8 = from_utf8(mbnewnick);
+ if (!newname_noutf8)
+ scr_LogPrint(LPRINT_LOG,
+ "Decoding of new nickname has failed: %s",
+ mbnewnick);
+ mbuf = g_strdup_printf("%s is now known as %s", rname,
+ (newname_noutf8 ? newname_noutf8 : "(?)"));
+ scr_WriteIncomingMessage(r, mbuf, 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
+ if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
+ g_free(mbuf);
+ if (newname_noutf8) {
+ buddy_resource_setname(room_elt->data, rname, newname_noutf8);
+ m = buddy_getnickname(room_elt->data);
+ if (m && !strcmp(rname, m))
+ buddy_setnickname(room_elt->data, newname_noutf8);
+ g_free(newname_noutf8);
+ }
+ }
+ }
+
+ // Check for departure/arrival
+ if (!mbnewnick && mbrole == role_none) {
+ gchar *mbuf;
+
+ // If this is a leave, check if it is ourself
+ m = buddy_getnickname(room_elt->data);
+ if (m && !strcmp(rname, m)) {
+ // _We_ have left! (kicked, banned, etc.)
+ buddy_setnickname(room_elt->data, NULL);
+ buddy_del_all_resources(room_elt->data);
+ scr_LogPrint(LPRINT_LOGNORM, "You have left %s", r);
+ scr_WriteIncomingMessage(r, "You have left", 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
+ update_roster = TRUE;
+
+ goto out_packet_presence;
+ }
+
+ if (s) mbuf = g_strdup_printf("%s has left: %s", rname, s);
+ else mbuf = g_strdup_printf("%s has left", rname);
+ scr_WriteIncomingMessage(r, mbuf, 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
+ if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
+ g_free(mbuf);
+ } else if (buddy_getstatus(room_elt->data, rname) == offline &&
+ ust != offline) {
+ gchar *mbuf;
+ if (buddy_getnickname(room_elt->data) == NULL) {
+ buddy_setnickname(room_elt->data, rname);
+ mbuf = g_strdup_printf("You have joined as \"%s\"", rname);
+ } else {
+ mbuf = g_strdup_printf("%s has joined", rname);
+ }
+ scr_WriteIncomingMessage(r, mbuf, 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
+ if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
+ g_free(mbuf);
+ }
+
+ // Update room member status
+ if (rname)
+ roster_setstatus(r, rname, bpprio, ust, s, mbrole, mbrjid);
+ else
+ scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
+
+ buddylist_build();
+ scr_DrawRoster();
+
+ goto out_packet_presence;
+ }
+
+ // Not a MUC message, so this is a regular buddy...
+ m = roster_getstatusmsg(r, rname);
+ if ((ust != roster_getstatus(r, rname)) ||
+ (!s && m && m[0]) || (s && (!m || strcmp(s, m))))
+ hk_statuschange(r, rname, bpprio, 0, ust, s);
+
+out_packet_presence:
+ g_free(r);
+ if (s) g_free(s);
+}
+
+static void handle_packet_message(jconn conn, char *type, char *from,
+ xmlnode xmldata)
+{
+ char *p, *r, *s;
+ xmlnode x;
+ char *body=NULL;
+ char *enc = NULL;
+ char *tmp = NULL;
+ time_t timestamp = 0;
+
+ body = xmlnode_get_tag_data(xmldata, "body");
+
+ p = xmlnode_get_tag_data(xmldata, "subject");
+ if (p != NULL) {
+ if (type && !strcmp(type, TMSG_GROUPCHAT)) { // Room topic
+ gchar *mbuf;
+ gchar *subj_noutf8 = from_utf8(p);
+ if (!subj_noutf8)
+ scr_LogPrint(LPRINT_LOG,
+ "Decoding of room topic has failed: %s", p);
+ // Get the room (s) and the nickname (r)
+ s = g_strdup(from);
+ r = strchr(s, '/');
+ if (r) *r++ = 0;
+ else r = s;
+ // Display inside the room window
+ mbuf = g_strdup_printf("%s has set the topic to: %s", r,
+ (subj_noutf8 ? subj_noutf8 : "(?)"));
+ scr_WriteIncomingMessage(s, mbuf, 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
+ if (settings_opt_get_int("log_muc_conf"))
+ hlog_write_message(s, 0, FALSE, mbuf);
+ if (subj_noutf8) g_free(subj_noutf8);
+ g_free(s);
+ g_free(mbuf);
+ } else { // Chat message
+ tmp = g_new(char, (body ? strlen(body) : 0) + strlen(p) + 4);
+ *tmp = '[';
+ strcpy(tmp+1, p);
+ strcat(tmp, "]\n");
+ if (body) strcat(tmp, body);
+ body = tmp;
+ }
+ }
+
+ /* there can be multiple <x> tags. we're looking for one with
+ xmlns = jabber:x:encrypted */
+
+ x = xmlnode_get_firstchild(xmldata);
+ for ( ; x; x = xmlnode_get_nextsibling(x)) {
+ if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
+ if ((p = xmlnode_get_attrib(x, "xmlns")) &&
+ !strcasecmp(p, "jabber:x:encrypted"))
+ if ((p = xmlnode_get_data(x)) != NULL) {
+ enc = p;
+ break;
+ }
+ }
+
+ // Timestamp?
+ if ((x = xmlnode_get_tag(xmldata, "x")) != NULL) {
+ if ((p = xmlnode_get_attrib(x, "stamp")) != NULL)
+ timestamp = from_iso8601(p, 1);
+ }
+
+ if (type && !strcmp(type, TMSG_ERROR)) {
+ if ((x = xmlnode_get_tag(xmldata, TMSG_ERROR)) != NULL)
+ display_server_error(x);
+ }
+ if (from && body)
+ gotmessage(type, from, body, enc, timestamp);
+ if (tmp)
+ g_free(tmp);
+}
+
+static void handle_packet_s10n(jconn conn, char *type, char *from,
+ xmlnode xmldata)
+{
+ xmlnode x;
+
+ scr_LogPrint(LPRINT_LOGNORM, "Received (un)subscription packet "
+ "(type=%s)", ((type) ? type : ""));
+
+ if (!strcmp(type, "subscribe")) {
+ char *r;
+ int isagent;
+ r = jidtodisp(from);
+ isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0;
+ g_free(r);
+ //scr_LogPrint(LPRINT_LOGNORM, "isagent=%d", isagent); // XXX DBG
+ if (!isagent) {
+ scr_LogPrint(LPRINT_LOGNORM, "<%s> wants to subscribe "
+ "to your network presence updates", from);
+ // FIXME we accept everybody...
+ x = jutil_presnew(JPACKET__SUBSCRIBED, from, 0);
+ jab_send(jc, x);
+ xmlnode_free(x);
+ } else {
+ x = jutil_presnew(JPACKET__SUBSCRIBED, from, 0);
+ jab_send(jc, x);
+ xmlnode_free(x);
+ }
+ } else if (!strcmp(type, "unsubscribe")) {
+ x = jutil_presnew(JPACKET__UNSUBSCRIBED, from, 0);
+ jab_send(jc, x);
+ xmlnode_free(x);
+ scr_LogPrint(LPRINT_LOGNORM, "<%s> has unsubscribed to "
+ "your presence updates", from);
+ }
+}
+
static void packethandler(jconn conn, jpacket packet)
{
char *p, *r, *s;
- const char *m, *rname;
- xmlnode x, y;
- char *from=NULL, *type=NULL, *body=NULL, *enc=NULL;
- char *ns=NULL;
- char *id=NULL;
- enum imstatus ust;
- char bpprio;
+ const char *m;
+ char *from=NULL, *type=NULL;
jb_reset_keepalive(); // reset keepalive timeout
jpacket_reset(packet);
- p = xmlnode_get_attrib(packet->x, "type"); if (p) type = p;
+ p = xmlnode_get_attrib(packet->x, "type");
+ if (p) type = p;
+
p = xmlnode_get_attrib(packet->x, "from");
if (p) { // Convert from UTF8
// We need to be careful because from_utf8() can fail on some chars
@@ -953,426 +1373,25 @@
switch (packet->type) {
case JPACKET_MESSAGE:
- {
- char *tmp = NULL;
- time_t timestamp = 0;
-
- body = xmlnode_get_tag_data(packet->x, "body");
-
- p = xmlnode_get_tag_data(packet->x, "subject");
- if (p != NULL) {
- if (type && !strcmp(type, TMSG_GROUPCHAT)) { // Room topic
- gchar *mbuf;
- gchar *subj_noutf8 = from_utf8(p);
- if (!subj_noutf8)
- scr_LogPrint(LPRINT_LOG,
- "Decoding of room topic has failed: %s", p);
- // Get the room (s) and the nickname (r)
- s = g_strdup(from);
- r = strchr(s, '/');
- if (r) *r++ = 0;
- else r = s;
- // Display inside the room window
- mbuf = g_strdup_printf("%s has set the topic to: %s", r,
- (subj_noutf8 ? subj_noutf8 : "(?)"));
- scr_WriteIncomingMessage(s, mbuf, 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
- if (settings_opt_get_int("log_muc_conf"))
- hlog_write_message(s, 0, FALSE, mbuf);
- if (subj_noutf8) g_free(subj_noutf8);
- g_free(s);
- g_free(mbuf);
- } else { // Chat message
- tmp = g_new(char, (body ? strlen(body) : 0) + strlen(p) + 4);
- *tmp = '[';
- strcpy(tmp+1, p);
- strcat(tmp, "]\n");
- if (body) strcat(tmp, body);
- body = tmp;
- }
- }
-
- /* there can be multiple <x> tags. we're looking for one with
- xmlns = jabber:x:encrypted */
-
- x = xmlnode_get_firstchild(packet->x);
- for ( ; x; x = xmlnode_get_nextsibling(x)) {
- if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
- if ((p = xmlnode_get_attrib(x, "xmlns")) &&
- !strcasecmp(p, "jabber:x:encrypted"))
- if ((p = xmlnode_get_data(x)) != NULL) {
- enc = p;
- break;
- }
- }
-
- // Timestamp?
- if ((x = xmlnode_get_tag(packet->x, "x")) != NULL) {
- if ((p = xmlnode_get_attrib(x, "stamp")) != NULL)
- timestamp = from_iso8601(p, 1);
- }
-
- if (type && !strcmp(type, TMSG_ERROR)) {
- if ((x = xmlnode_get_tag(packet->x, TMSG_ERROR)) != NULL)
- display_server_error(x);
- }
- if (from && body)
- gotmessage(type, from, body, enc, timestamp);
- if (tmp)
- g_free(tmp);
- }
+ handle_packet_message(conn, type, from, packet->x);
break;
case JPACKET_IQ:
- if (!strcmp(type, "result")) {
-
- if ((p = xmlnode_get_attrib(packet->x, "id")) != NULL) {
- int iid = atoi(p);
-
- scr_LogPrint(LPRINT_DEBUG, "iid = %d", iid);
- if (iid == s_id) {
- if (!regmode) {
- if (jstate == STATE_GETAUTH) {
- if ((x = xmlnode_get_tag(packet->x, "query")) != NULL)
- if (!xmlnode_get_tag(x, "digest")) {
- jc->sid = 0;
- }
-
- s_id = atoi(jab_auth(jc));
- jstate = STATE_SENDAUTH;
- } else {
- gotloggedin();
- jstate = STATE_LOGGED;
- }
- } else {
- regdone = TRUE;
- }
- return;
- }
-
- if (!strcmp(p, "VCARDreq")) {
- x = xmlnode_get_firstchild(packet->x);
- if (!x) x = packet->x;
-
- //jhook.gotvcard(ic, x); TODO
- scr_LogPrint(LPRINT_LOGNORM, "Got VCARD");
- return;
- } else if (!strcmp(p, "versionreq")) {
- // jhook.gotversion(ic, packet->x); TODO
- scr_LogPrint(LPRINT_LOGNORM, "Got version");
- return;
- }
- }
-
- if ((x = xmlnode_get_tag(packet->x, "query")) != NULL) {
- p = xmlnode_get_attrib(x, "xmlns"); if (p) ns = p;
-
- if (!strcmp(ns, NS_ROSTER)) {
- gotroster(x);
- } else if (!strcmp(ns, NS_AGENTS)) {
- for (y = xmlnode_get_tag(x, "agent"); y; y = xmlnode_get_nextsibling(y)) {
- const char *alias = xmlnode_get_attrib(y, "jid");
-
- if (alias) {
- const char *name = xmlnode_get_tag_data(y, "name");
- const char *desc = xmlnode_get_tag_data(y, "description");
- // TODO
- // const char *service = xmlnode_get_tag_data(y, "service");
- enum agtype atype = unknown;
-
- if (xmlnode_get_tag(y, TMSG_GROUPCHAT)) atype = groupchat;
- else if (xmlnode_get_tag(y, "transport")) atype = transport;
- else if (xmlnode_get_tag(y, "search")) atype = search;
-
- if (atype == transport) {
- char *cleanjid = jidtodisp(alias);
- roster_add_user(cleanjid, NULL, JABBER_AGENT_GROUP,
- ROSTER_TYPE_AGENT);
- g_free(cleanjid);
- }
- if (alias && name && desc) {
- scr_LogPrint(LPRINT_LOGNORM,
- "Agent: %s / %s / %s / type=%d",
- alias, name, desc, atype);
-
- if (atype == search) {
- x = jutil_iqnew (JPACKET__GET, NS_SEARCH);
- xmlnode_put_attrib(x, "to", alias);
- xmlnode_put_attrib(x, "id", "Agent info");
- jab_send(conn, x);
- xmlnode_free(x);
- }
-
- if (xmlnode_get_tag(y, "register")) {
- x = jutil_iqnew (JPACKET__GET, NS_REGISTER);
- xmlnode_put_attrib(x, "to", alias);
- xmlnode_put_attrib(x, "id", "Agent info");
- jab_send(conn, x);
- xmlnode_free(x);
- }
- }
- }
- }
-
- /*
- if (find(jhook.agents.begin(), jhook.agents.end(), DEFAULT_CONFSERV) == jhook.agents.end())
- jhook.agents.insert(jhook.agents.begin(), agent(DEFAULT_CONFSERV, DEFAULT_CONFSERV,
- _("Default Jabber conference server"), agent::atGroupchat));
-
- */
- } else if (!strcmp(ns, NS_SEARCH) || !strcmp(ns, NS_REGISTER)) {
- p = xmlnode_get_attrib(packet->x, "id"); id = p ? p : (char*)"";
-
- if (!strcmp(id, "Agent info")) {
- // jhook.gotagentinfo(packet->x); TODO
- scr_LogPrint(LPRINT_LOGNORM, "Got agent info");
- } else if (!strcmp(id, "Lookup")) {
- // jhook.gotsearchresults(packet->x); TODO
- scr_LogPrint(LPRINT_LOGNORM, "Got search results");
- } else if (!strcmp(id, "Register")) {
- x = jutil_iqnew(JPACKET__GET, NS_REGISTER);
- xmlnode_put_attrib(x, "to", from);
- xmlnode_put_attrib(x, "id", "Agent info");
- jab_send(conn, x);
- xmlnode_free(x);
- }
-
- }
- }
- } else if (!strcmp(type, "get")) {
- p = xmlnode_get_attrib(packet->x, "id");
- if (p) {
- xmlnode z;
-
- id = p;
- x = xmlnode_new_tag("iq");
- xmlnode_put_attrib(x, "type", "result");
- xmlnode_put_attrib(x, "to", from);
- xmlnode_put_attrib(x, "id", id);
- xmlnode_put_attrib(x, "type", TMSG_ERROR);
- y = xmlnode_insert_tag(x, TMSG_ERROR);
- xmlnode_put_attrib(y, "code", "503");
- xmlnode_put_attrib(y, "type", "cancel");
- z = xmlnode_insert_tag(y, "feature-not-implemented");
- xmlnode_put_attrib(z, "xmlns",
- "urn:ietf:params:xml:ns:xmpp-stanzas");
- jab_send(conn, x);
- xmlnode_free(x);
- }
- } else if (!strcmp(type, "set")) {
- /* FIXME: send error */
- } else if (!strcmp(type, TMSG_ERROR)) {
- if ((x = xmlnode_get_tag(packet->x, TMSG_ERROR)) != NULL)
- display_server_error(x);
- }
+ handle_packet_iq(conn, type, from, packet->x);
break;
case JPACKET_PRESENCE:
- r = jidtodisp(from);
- if (type && !strcmp(type, TMSG_ERROR)) {
- scr_LogPrint(LPRINT_LOGNORM, "Error presence packet from <%s>", r);
- if ((x = xmlnode_get_tag(packet->x, TMSG_ERROR)) != NULL)
- display_server_error(x);
- g_free(r);
- break;
- }
-
- p = xmlnode_get_tag_data(packet->x, "priority");
- if (p && *p) bpprio = (gchar)atoi(p);
- else bpprio = 0;
-
- ust = available;
- p = xmlnode_get_tag_data(packet->x, "show");
- if (p) {
- if (!strcmp(p, "away")) ust = away;
- else if (!strcmp(p, "dnd")) ust = dontdisturb;
- else if (!strcmp(p, "xa")) ust = notavail;
- else if (!strcmp(p, "chat")) ust = freeforchat;
- }
-
- if (type && !strcmp(type, "unavailable"))
- ust = offline;
-
- s = NULL;
- p = xmlnode_get_tag_data(packet->x, "status");
- if (p) {
- s = from_utf8(p);
- if (!s)
- scr_LogPrint(LPRINT_LOG,
- "Decoding of status message of <%s> has failed: %s",
- from, p);
- }
-
- // Call hk_statuschange() if status has changed or if the
- // status message is different
- rname = strchr(from, '/');
- if (rname) rname++;
-
- // Check for MUC presence packet
- // There can be multiple <x> tags!!
- x = xmlnode_get_firstchild(packet->x);
- for ( ; x; x = xmlnode_get_nextsibling(x)) {
- if ((p = xmlnode_get_name(x)) && !strcmp(p, "x"))
- if ((p = xmlnode_get_attrib(x, "xmlns")) &&
- !strcasecmp(p, "http://jabber.org/protocol/muc#user"))
- break;
- }
- if (x) { // This is a MUC presence message
- enum imrole mbrole = role_none;
- const char *mbrjid = NULL;
- const char *mbnewnick = NULL;
- GSList *room_elt;
- int log_muc_conf = settings_opt_get_int("log_muc_conf");
-
- // Add room if it doesn't already exist
- room_elt = roster_find(r, jidsearch, 0);
- if (!room_elt)
- room_elt = roster_add_user(r, NULL, NULL, ROSTER_TYPE_ROOM);
- else // Make sure this is a room (it can be a conversion user->room)
- buddy_settype(room_elt->data, ROSTER_TYPE_ROOM);
-
- // Get room member's information
- y = xmlnode_get_tag(x, "item");
- if (y) {
- p = xmlnode_get_attrib(y, "role");
- if (p) {
- if (!strcmp(p, "moderator")) mbrole = role_moderator;
- else if (!strcmp(p, "participant")) mbrole = role_participant;
- else if (!strcmp(p, "visitor")) mbrole = role_visitor;
- else if (!strcmp(p, "none")) mbrole = role_none;
- else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
- from, p);
- }
- p = xmlnode_get_attrib(y, "jid");
- if (p) mbrjid = p;
- p = xmlnode_get_attrib(y, "nick");
- if (p) mbnewnick = p;
- }
-
- // Check for nickname change
- y = xmlnode_get_tag(x, "status");
- if (y && mbnewnick) {
- p = xmlnode_get_attrib(y, "code");
- if (p && !strcmp(p, "303")) {
- gchar *mbuf;
- gchar *newname_noutf8 = from_utf8(mbnewnick);
- if (!newname_noutf8)
- scr_LogPrint(LPRINT_LOG,
- "Decoding of new nickname has failed: %s",
- mbnewnick);
- mbuf = g_strdup_printf("%s is now known as %s", rname,
- (newname_noutf8 ? newname_noutf8 : "(?)"));
- scr_WriteIncomingMessage(r, mbuf, 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
- if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
- g_free(mbuf);
- if (newname_noutf8) {
- buddy_resource_setname(room_elt->data, rname, newname_noutf8);
- m = buddy_getnickname(room_elt->data);
- if (m && !strcmp(rname, m))
- buddy_setnickname(room_elt->data, newname_noutf8);
- g_free(newname_noutf8);
- }
- }
- }
-
- // Check for departure/arrival
- if (!mbnewnick && mbrole == role_none) {
- gchar *mbuf;
-
- // If this is a leave, check if it is ourself
- m = buddy_getnickname(room_elt->data);
- if (m && !strcmp(rname, m)) {
- // _We_ have left! (kicked, banned, etc.)
- buddy_setnickname(room_elt->data, NULL);
- buddy_del_all_resources(room_elt->data);
- scr_LogPrint(LPRINT_LOGNORM, "You have left %s", r);
- scr_WriteIncomingMessage(r, "You have left", 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
- g_free(r);
- if (s) g_free(s);
- update_roster = TRUE;
- break;
- }
-
- if (s) mbuf = g_strdup_printf("%s has left: %s", rname, s);
- else mbuf = g_strdup_printf("%s has left", rname);
- scr_WriteIncomingMessage(r, mbuf, 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
- if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
- g_free(mbuf);
- } else if (buddy_getstatus(room_elt->data, rname) == offline &&
- ust != offline) {
- gchar *mbuf;
- if (buddy_getnickname(room_elt->data) == NULL) {
- buddy_setnickname(room_elt->data, rname);
- mbuf = g_strdup_printf("You have joined as \"%s\"", rname);
- } else {
- mbuf = g_strdup_printf("%s has joined", rname);
- }
- scr_WriteIncomingMessage(r, mbuf, 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG);
- if (log_muc_conf) hlog_write_message(r, 0, FALSE, mbuf);
- g_free(mbuf);
- }
-
- // Update room member status
- if (rname)
- roster_setstatus(r, rname, bpprio, ust, s, mbrole, mbrjid);
- else
- scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
-
- g_free(r);
- if (s) g_free(s);
-
- buddylist_build();
- scr_DrawRoster();
- break;
- }
-
- // Not a MUC message, so this is a regular buddy...
- m = roster_getstatusmsg(r, rname);
- if ((ust != roster_getstatus(r, rname)) ||
- (!s && m && m[0]) || (s && (!m || strcmp(s, m))))
- hk_statuschange(r, rname, bpprio, 0, ust, s);
- g_free(r);
- if (s) g_free(s);
+ handle_packet_presence(conn, type, from, packet->x);
break;
case JPACKET_S10N:
- scr_LogPrint(LPRINT_LOGNORM, "Received (un)subscription packet "
- "(type=%s)", ((type) ? type : ""));
-
- if (!strcmp(type, "subscribe")) {
- int isagent;
- r = jidtodisp(from);
- isagent = (roster_gettype(r) & ROSTER_TYPE_AGENT) != 0;
- g_free(r);
- //scr_LogPrint(LPRINT_LOGNORM, "isagent=%d", isagent); // XXX DBG
- if (!isagent) {
- scr_LogPrint(LPRINT_LOGNORM, "<%s> wants to subscribe "
- "to your network presence updates", from);
- // FIXME we accept everybody...
- x = jutil_presnew(JPACKET__SUBSCRIBED, from, 0);
- jab_send(jc, x);
- xmlnode_free(x);
- } else {
- x = jutil_presnew(JPACKET__SUBSCRIBED, from, 0);
- jab_send(jc, x);
- xmlnode_free(x);
- }
- } else if (!strcmp(type, "unsubscribe")) {
- x = jutil_presnew(JPACKET__UNSUBSCRIBED, from, 0);
- jab_send(jc, x);
- xmlnode_free(x);
- scr_LogPrint(LPRINT_LOGNORM, "<%s> has unsubscribed to "
- "your presence updates", from);
- }
+ handle_packet_s10n(conn, type, from, packet->x);
break;
default:
- break;
+ scr_LogPrint(LPRINT_LOG, "Unhandled packet type (%d)", packet->type);
}
- g_free(from);
+ if (from)
+ g_free(from);
}