[gaim-migrate @ 15272]
Replace GaimBlistNodeAction with the more generic GaimMenuAction, this is in
preparation for letting the chat room user list have extensible menus like the
blist entries do. (I know it's not exactly the prettiest, and the callback
isn't exactly type-safe, when we eventually gobjectify everything we can get
some safety back by using (GObject, gpointer) but that's for later.)
I'm planning to look into merging GaimPluginActions into GaimMenuActions as
well.
committer: Tailor Script <tailor@pidgin.im>
line source
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 /*
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * gaim - Jabber Protocol Plugin
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 *
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 *
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * This program is free software; you can redistribute it and/or modify
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * it under the terms of the GNU General Public License as published by
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * the Free Software Foundation; either version 2 of the License, or
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * (at your option) any later version.
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 *
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * This program is distributed in the hope that it will be useful,
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * GNU General Public License for more details.
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 *
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * You should have received a copy of the GNU General Public License
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * along with this program; if not, write to the Free Software
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 *
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 */
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "internal.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "debug.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "prefs.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "util.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "buddy.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "disco.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "iq.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "oob.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "roster.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "si.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #ifdef _WIN32
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #include "utsname.h"
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 #endif
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq = g_new0(JabberIq, 1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->type = type;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->node = xmlnode_new("iq");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 switch(iq->type) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 case JABBER_IQ_SET:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "type", "set");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 break;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 case JABBER_IQ_GET:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "type", "get");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 break;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 case JABBER_IQ_ERROR:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "type", "error");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 break;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 case JABBER_IQ_RESULT:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "type", "result");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 break;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 case JABBER_IQ_NONE:
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 /* this shouldn't ever happen */
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 break;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->js = js;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type == JABBER_IQ_GET || type == JABBER_IQ_SET) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->id = jabber_get_next_id(js);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "id", iq->id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *jabber_iq_new_query(JabberStream *js, JabberIqType type,
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *xmlns)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq = jabber_iq_new(js, type);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode *query;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 query = xmlnode_new_child(iq->node, "query");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(query, "xmlns", xmlns);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 typedef struct _JabberCallbackData {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIqCallback *callback;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 gpointer data;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } JabberCallbackData;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 void
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_set_callback(JabberIq *iq, JabberIqCallback *callback, gpointer data)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->callback = callback;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->callback_data = data;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 void jabber_iq_set_id(JabberIq *iq, const char *id)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(iq->id)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(iq->id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(id) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "id", id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->id = g_strdup(id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_remove_attrib(iq->node, "id");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->id = NULL;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 void jabber_iq_send(JabberIq *iq)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberCallbackData *jcd;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_return_if_fail(iq != NULL);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_send(iq->js, iq->node);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(iq->id && iq->callback) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jcd = g_new0(JabberCallbackData, 1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jcd->callback = iq->callback;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jcd->data = iq->callback_data;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_hash_table_insert(iq->js->iq_callbacks, g_strdup(iq->id), jcd);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_free(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 void jabber_iq_free(JabberIq *iq)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_return_if_fail(iq != NULL);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(iq->id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_free(iq->node);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 static void jabber_iq_last_parse(JabberStream *js, xmlnode *packet)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *type;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *from;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *id;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode *query;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 char *idle_time;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 type = xmlnode_get_attrib(packet, "type");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 from = xmlnode_get_attrib(packet, "from");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 id = xmlnode_get_attrib(packet, "id");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && !strcmp(type, "get")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:last");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_set_id(iq, id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "to", from);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 query = xmlnode_get_child(iq->node, "query");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 idle_time = g_strdup_printf("%ld", js->idle ? time(NULL) - js->idle : 0);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(query, "seconds", idle_time);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(idle_time);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_send(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 static void jabber_iq_time_parse(JabberStream *js, xmlnode *packet)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *type, *from, *id;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 char buf[1024];
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode *query;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 time_t now_t;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 struct tm *now;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 time(&now_t);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 now = localtime(&now_t);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 type = xmlnode_get_attrib(packet, "type");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 from = xmlnode_get_attrib(packet, "from");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 id = xmlnode_get_attrib(packet, "id");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && !strcmp(type, "get")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 char *utf8;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_set_id(iq, id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "to", from);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 query = xmlnode_get_child(iq->node, "query");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 strftime(buf, sizeof(buf), "%Y%m%dT%T", now);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "utc"), buf, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 strftime(buf, sizeof(buf), "%Z", now);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if((utf8 = gaim_utf8_try_convert(buf))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "tz"), utf8, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(utf8);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 strftime(buf, sizeof(buf), "%d %b %Y %T", now);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if((utf8 = gaim_utf8_try_convert(buf))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "display"), utf8, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(utf8);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_send(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 static void jabber_iq_version_parse(JabberStream *js, xmlnode *packet)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *type, *from, *id;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode *query;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 char *os = NULL;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 type = xmlnode_get_attrib(packet, "type");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && !strcmp(type, "get")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(!gaim_prefs_get_bool("/plugins/prpl/jabber/hide_os")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 struct utsname osinfo;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 uname(&osinfo);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 osinfo.machine);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 from = xmlnode_get_attrib(packet, "from");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 id = xmlnode_get_attrib(packet, "id");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "to", from);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_set_id(iq, id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 query = xmlnode_get_child(iq->node, "query");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "name"), PACKAGE, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(os) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_free(os);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_send(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 void jabber_iq_parse(JabberStream *js, xmlnode *packet)
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberCallbackData *jcd;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode *query, *error, *x;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *xmlns;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 const char *type, *id, *from;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 query = xmlnode_get_child(packet, "query");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 type = xmlnode_get_attrib(packet, "type");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 from = xmlnode_get_attrib(packet, "from");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 id = xmlnode_get_attrib(packet, "id");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 /* First, lets see if a special callback got registered */
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && (!strcmp(type, "result") || !strcmp(type, "error"))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(id && *id && (jcd = g_hash_table_lookup(js->iq_callbacks, id))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jcd->callback(js, packet, jcd->data);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 g_hash_table_remove(js->iq_callbacks, id);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 /* Apparently not, so lets see if we have a pre-defined handler */
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && query && (xmlns = xmlnode_get_attrib(query, "xmlns"))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(!strcmp(type, "set")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(!strcmp(xmlns, "jabber:iq:roster")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_roster_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "jabber:iq:oob")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_oob_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "http://jabber.org/protocol/bytestreams")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_bytestreams_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(type, "get")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(!strcmp(xmlns, "jabber:iq:last")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_last_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "jabber:iq:time")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_time_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "jabber:iq:version")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_version_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_disco_info_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#items")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_disco_items_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(type, "result")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(!strcmp(xmlns, "jabber:iq:roster")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_roster_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "jabber:iq:register")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_register_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else if(!strcmp(xmlns, "http://jabber.org/protocol/disco#info")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_disco_info_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 } else {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(xmlnode_get_child_with_namespace(packet, "si", "http://jabber.org/protocol/si")) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_si_parse(js, packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 return;
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 /* If we get here, send the default error reply mandated by XMPP-CORE */
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 if(type && (!strcmp(type, "set") || !strcmp(type, "get"))) {
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_ERROR);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_free(iq->node);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 iq->node = xmlnode_copy(packet);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "to", from);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_remove_attrib(iq->node, "from");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(iq->node, "type", "error");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 error = xmlnode_new_child(iq->node, "error");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(error, "type", "cancel");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(error, "code", "501");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 x = xmlnode_new_child(error, "feature-not-implemented");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 xmlnode_set_attrib(x, "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 jabber_iq_send(iq);
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申 }
+ 鐃緒申��申鐃初姐�渇����鐃醇�鐃緒申��申鐃緒申