comparison 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
comparison
equal deleted inserted replaced
7013:859cafb6433f 7014:67c4e9d39242
1 /*
2 * gaim - Jabber Protocol Plugin
3 *
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21 #include "internal.h"
22 #include "debug.h"
23 #include "prefs.h"
24
25 #include "iq.h"
26 #include "roster.h"
27
28
29 JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
30 {
31 JabberIq *iq;
32
33 iq = g_new0(JabberIq, 1);
34
35 iq->type = type;
36
37 iq->node = xmlnode_new("iq");
38 switch(iq->type) {
39 case JABBER_IQ_SET:
40 xmlnode_set_attrib(iq->node, "type", "set");
41 break;
42 case JABBER_IQ_GET:
43 xmlnode_set_attrib(iq->node, "type", "get");
44 break;
45 case JABBER_IQ_ERROR:
46 xmlnode_set_attrib(iq->node, "type", "error");
47 break;
48 case JABBER_IQ_RESULT:
49 xmlnode_set_attrib(iq->node, "type", "result");
50 break;
51 case JABBER_IQ_NONE:
52 /* this shouldn't ever happen */
53 break;
54 }
55
56 iq->js = js;
57
58 if(type == JABBER_IQ_GET || type == JABBER_IQ_SET) {
59 iq->id = jabber_get_next_id(js);
60 xmlnode_set_attrib(iq->node, "id", iq->id);
61 }
62
63 return iq;
64 }
65
66 JabberIq *jabber_iq_new_query(JabberStream *js, JabberIqType type,
67 const char *xmlns)
68 {
69 JabberIq *iq = jabber_iq_new(js, type);
70 xmlnode *query;
71
72 query = xmlnode_new_child(iq->node, "query");
73 xmlnode_set_attrib(query, "xmlns", xmlns);
74
75 return iq;
76 }
77
78 void jabber_iq_set_callback(JabberIq *iq, JabberCallback *callback)
79 {
80 iq->callback = callback;
81 }
82
83 void jabber_iq_set_id(JabberIq *iq, const char *id)
84 {
85 if(iq->id)
86 g_free(iq->id);
87
88 if(id) {
89 xmlnode_set_attrib(iq->node, "id", id);
90 iq->id = g_strdup(id);
91 } else {
92 xmlnode_remove_attrib(iq->node, "id");
93 iq->id = NULL;
94 }
95 }
96
97 void jabber_iq_send(JabberIq *iq)
98 {
99 g_return_if_fail(iq != NULL);
100
101 jabber_send(iq->js, iq->node);
102
103 if(iq->id && iq->callback)
104 g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), iq->callback);
105
106 jabber_iq_free(iq);
107 }
108
109 void jabber_iq_free(JabberIq *iq)
110 {
111 g_return_if_fail(iq != NULL);
112
113 g_free(iq->id);
114 xmlnode_free(iq->node);
115 g_free(iq);
116 }
117
118 static void jabber_iq_handle_last(JabberStream *js, xmlnode *packet)
119 {
120 JabberIq *iq;
121 const char *from;
122 const char *id;
123 xmlnode *query;
124 char *idle_time;
125
126 from = xmlnode_get_attrib(packet, "from");
127 id = xmlnode_get_attrib(packet, "id");
128
129 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:last");
130 jabber_iq_set_id(iq, id);
131 xmlnode_set_attrib(iq->node, "to", from);
132
133 query = xmlnode_get_child(iq->node, "query");
134
135 idle_time = g_strdup_printf("%ld", js->idle ? time(NULL) - js->idle : 0);
136 xmlnode_set_attrib(query, "seconds", idle_time);
137 g_free(idle_time);
138 }
139
140 static void jabber_iq_handle_time(JabberStream *js, xmlnode *packet)
141 {
142 const char *from, *id;
143 JabberIq *iq;
144 char buf[1024];
145 xmlnode *query;
146 time_t now_t;
147 struct tm now;
148 time(&now_t);
149 localtime_r(&now_t, &now);
150
151 from = xmlnode_get_attrib(packet, "from");
152 id = xmlnode_get_attrib(packet, "id");
153
154 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time");
155 jabber_iq_set_id(iq, id);
156 xmlnode_set_attrib(iq->node, "to", from);
157
158 query = xmlnode_get_child(iq->node, "query");
159
160 strftime(buf, sizeof(buf), "%Y%m%dT%T", &now);
161 xmlnode_insert_data(xmlnode_new_child(query, "utc"), buf, -1);
162 strftime(buf, sizeof(buf), "%Z", &now);
163 xmlnode_insert_data(xmlnode_new_child(query, "tz"), buf, -1);
164 strftime(buf, sizeof(buf), "%d %b %Y %T", &now);
165 xmlnode_insert_data(xmlnode_new_child(query, "display"), buf, -1);
166
167 jabber_iq_send(iq);
168 }
169
170 static void jabber_iq_handle_version(JabberStream *js, xmlnode *packet)
171 {
172 JabberIq *iq;
173 const char *from, *id;
174 xmlnode *query;
175 char *os = NULL;
176
177 if(!gaim_prefs_get_bool("/plugins/prpl/jabber/hide_os")) {
178 struct utsname osinfo;
179
180 uname(&osinfo);
181 os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
182 osinfo.machine);
183 }
184
185 from = xmlnode_get_attrib(packet, "from");
186 id = xmlnode_get_attrib(packet, "id");
187
188 iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
189 xmlnode_set_attrib(iq->node, "to", from);
190 jabber_iq_set_id(iq, id);
191
192 query = xmlnode_get_child(iq->node, "query");
193
194 xmlnode_insert_data(xmlnode_new_child(query, "name"), PACKAGE, -1);
195 xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1);
196 if(os) {
197 xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1);
198 g_free(os);
199 }
200
201 jabber_iq_send(iq);
202 }
203
204 void jabber_iq_parse(JabberStream *js, xmlnode *packet)
205 {
206 xmlnode *query;
207 const char *xmlns;
208
209 query = xmlnode_get_child(packet, "query");
210
211 if(!query)
212 return;
213
214 xmlns = xmlnode_get_attrib(query, "xmlns");
215
216 if(!xmlns)
217 return;
218
219 if(!strcmp(xmlns, "jabber:iq:roster")) {
220 jabber_roster_parse(js, packet);
221 } else if(!strcmp(xmlns, "jabber:iq:last")) {
222 jabber_iq_handle_last(js, packet);
223 } else if(!strcmp(xmlns, "jabber:iq:time")) {
224 jabber_iq_handle_time(js, packet);
225 } else if(!strcmp(xmlns, "jabber:iq:version")) {
226 jabber_iq_handle_version(js, packet);
227 } else {
228 gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns);
229 }
230 }
231