Mercurial > pidgin.yaz
diff src/protocols/jabber/iq.c @ 7014:67c4e9d39242
[gaim-migrate @ 7577]
Here it is, the bulk of the new Jabber prpl.
Left to do:
- Implement registration
- Implement password changing
- Keep track of conversation threads (since I apparently have to)
- Fix the bugs that always magically appear in code after I commit
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Mon, 29 Sep 2003 15:23:19 +0000 |
parents | |
children | 06e7697f3fae |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/jabber/iq.c Mon Sep 29 15:23:19 2003 +0000 @@ -0,0 +1,231 @@ +/* + * 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 "iq.h" +#include "roster.h" + + +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; +} + +void jabber_iq_set_callback(JabberIq *iq, JabberCallback *callback) +{ + iq->callback = callback; +} + +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) +{ + g_return_if_fail(iq != NULL); + + jabber_send(iq->js, iq->node); + + if(iq->id && iq->callback) + g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), iq->callback); + + 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_handle_last(JabberStream *js, xmlnode *packet) +{ + JabberIq *iq; + const char *from; + const char *id; + xmlnode *query; + char *idle_time; + + from = xmlnode_get_attrib(packet, "from"); + id = xmlnode_get_attrib(packet, "id"); + + 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); +} + +static void jabber_iq_handle_time(JabberStream *js, xmlnode *packet) +{ + const char *from, *id; + JabberIq *iq; + char buf[1024]; + xmlnode *query; + time_t now_t; + struct tm now; + time(&now_t); + localtime_r(&now_t, &now); + + from = xmlnode_get_attrib(packet, "from"); + id = xmlnode_get_attrib(packet, "id"); + + 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); + xmlnode_insert_data(xmlnode_new_child(query, "tz"), buf, -1); + strftime(buf, sizeof(buf), "%d %b %Y %T", &now); + xmlnode_insert_data(xmlnode_new_child(query, "display"), buf, -1); + + jabber_iq_send(iq); +} + +static void jabber_iq_handle_version(JabberStream *js, xmlnode *packet) +{ + JabberIq *iq; + const char *from, *id; + xmlnode *query; + char *os = NULL; + + 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) +{ + xmlnode *query; + const char *xmlns; + + query = xmlnode_get_child(packet, "query"); + + if(!query) + return; + + xmlns = xmlnode_get_attrib(query, "xmlns"); + + if(!xmlns) + return; + + if(!strcmp(xmlns, "jabber:iq:roster")) { + jabber_roster_parse(js, packet); + } else if(!strcmp(xmlns, "jabber:iq:last")) { + jabber_iq_handle_last(js, packet); + } else if(!strcmp(xmlns, "jabber:iq:time")) { + jabber_iq_handle_time(js, packet); + } else if(!strcmp(xmlns, "jabber:iq:version")) { + jabber_iq_handle_version(js, packet); + } else { + gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns); + } +} +