Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/xmpp_iqrequest.c @ 1668:41c26b7d2890
Install mcabber headers
* Change mcabber headers naming scheme
* Move 'src/' -> 'mcabber/'
* Add missing include <mcabber/config.h>'s
* Create and install clean config.h version in 'include/'
* Move "dirty" config.h version to 'mcabber/'
* Add $(top_srcdir) to compiler include path
* Update modules HOWTO
author | Myhailo Danylenko <isbear@ukrpost.net> |
---|---|
date | Mon, 18 Jan 2010 15:36:19 +0200 |
parents | mcabber/src/xmpp_iqrequest.c@351427ef0b4b |
children | b09f82f61745 |
comparison
equal
deleted
inserted
replaced
1667:8af0e0ad20ad | 1668:41c26b7d2890 |
---|---|
1 /* | |
2 * xmpp_iqrequest.c -- Jabber IQ request handling | |
3 * | |
4 * Copyright (C) 2008-2009 Frank Zschockelt <mcabber@freakysoft.de> | |
5 * Copyright (C) 2005-2009 Mikael Berthe <mikael@lilotux.net> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or (at | |
10 * your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
20 * USA | |
21 */ | |
22 | |
23 #include <string.h> | |
24 #include <stdlib.h> | |
25 | |
26 #include "xmpp_helper.h" | |
27 #include "xmpp_iq.h" | |
28 #include "screen.h" | |
29 #include "utils.h" | |
30 #include "settings.h" | |
31 #include "hooks.h" | |
32 #include "hbuf.h" | |
33 | |
34 extern LmMessageNode *bookmarks; | |
35 extern LmMessageNode *rosternotes; | |
36 | |
37 static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c, | |
38 LmMessage *m, gpointer user_data); | |
39 static LmHandlerResult cb_version(LmMessageHandler *h, LmConnection *c, | |
40 LmMessage *m, gpointer user_data); | |
41 static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c, | |
42 LmMessage *m, gpointer user_data); | |
43 static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c, | |
44 LmMessage *m, gpointer user_data); | |
45 static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c, | |
46 LmMessage *m, gpointer user_data); | |
47 | |
48 static struct IqRequestHandlers | |
49 { | |
50 const gchar *xmlns; | |
51 const gchar *querytag; | |
52 LmHandleMessageFunction handler; | |
53 } iq_request_handlers[] = { | |
54 {NS_ROSTER, "query", &cb_roster}, | |
55 {NS_VERSION,"query", &cb_version}, | |
56 {NS_TIME, "query", &cb_time}, | |
57 {NS_LAST, "query", &cb_last}, | |
58 {NS_VCARD, "vCard", &cb_vcard}, | |
59 {NULL, NULL, NULL} | |
60 }; | |
61 | |
62 // Enum for vCard attributes | |
63 enum vcard_attr { | |
64 vcard_home = 1<<0, | |
65 vcard_work = 1<<1, | |
66 vcard_postal = 1<<2, | |
67 vcard_voice = 1<<3, | |
68 vcard_fax = 1<<4, | |
69 vcard_cell = 1<<5, | |
70 vcard_inet = 1<<6, | |
71 vcard_pref = 1<<7, | |
72 }; | |
73 | |
74 // xmlns has to be a namespace from iq_request_handlers[].xmlns | |
75 void xmpp_iq_request(const char *fulljid, const char *xmlns) | |
76 { | |
77 LmMessage *iq; | |
78 LmMessageNode *query; | |
79 LmMessageHandler *handler; | |
80 int i; | |
81 | |
82 iq = lm_message_new_with_sub_type(fulljid, LM_MESSAGE_TYPE_IQ, | |
83 LM_MESSAGE_SUB_TYPE_GET); | |
84 for (i = 0; strcmp(iq_request_handlers[i].xmlns, xmlns) != 0 ; ++i) | |
85 ; | |
86 query = lm_message_node_add_child(iq->node, | |
87 iq_request_handlers[i].querytag, | |
88 NULL); | |
89 lm_message_node_set_attribute(query, "xmlns", xmlns); | |
90 handler = lm_message_handler_new(iq_request_handlers[i].handler, | |
91 NULL, FALSE); | |
92 lm_connection_send_with_reply(lconnection, iq, handler, NULL); | |
93 lm_message_handler_unref(handler); | |
94 lm_message_unref(iq); | |
95 } | |
96 | |
97 // This callback is reached when mcabber receives the first roster update | |
98 // after the connection. | |
99 static LmHandlerResult cb_roster(LmMessageHandler *h, LmConnection *c, | |
100 LmMessage *m, gpointer user_data) | |
101 { | |
102 LmMessageNode *x; | |
103 const char *ns; | |
104 | |
105 // Only execute the hook if the roster has been successfully retrieved | |
106 if (lm_message_get_sub_type(m) != LM_MESSAGE_SUB_TYPE_RESULT) | |
107 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
108 | |
109 x = lm_message_node_find_child(m->node, "query"); | |
110 if (!x) | |
111 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
112 | |
113 ns = lm_message_node_get_attribute(x, "xmlns"); | |
114 if (ns && !strcmp(ns, NS_ROSTER)) | |
115 handle_iq_roster(NULL, c, m, user_data); | |
116 | |
117 // Post-login stuff | |
118 hook_execute_internal("hook-post-connect"); | |
119 | |
120 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
121 } | |
122 | |
123 static LmHandlerResult cb_version(LmMessageHandler *h, LmConnection *c, | |
124 LmMessage *m, gpointer user_data) | |
125 { | |
126 LmMessageNode *ansqry; | |
127 const char *p, *bjid; | |
128 char *tmp; | |
129 char *buf; | |
130 | |
131 ansqry = lm_message_node_get_child(m->node, "query"); | |
132 if (!ansqry) { | |
133 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result!"); | |
134 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
135 } | |
136 | |
137 // Display IQ result sender... | |
138 p = lm_message_get_from(m); | |
139 if (!p) { | |
140 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:version result (no sender name)."); | |
141 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
142 } | |
143 bjid = p; | |
144 | |
145 buf = g_strdup_printf("Received IQ:version result from <%s>", bjid); | |
146 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); | |
147 | |
148 // bjid should now really be the "bare JID", let's strip the resource | |
149 tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); | |
150 if (tmp) *tmp = '\0'; | |
151 | |
152 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); | |
153 g_free(buf); | |
154 | |
155 // Get result data... | |
156 p = lm_message_node_get_child_value(ansqry, "name"); | |
157 if (p) { | |
158 buf = g_strdup_printf("Name: %s", p); | |
159 scr_WriteIncomingMessage(bjid, buf, | |
160 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
161 g_free(buf); | |
162 } | |
163 p = lm_message_node_get_child_value(ansqry, "version"); | |
164 if (p) { | |
165 buf = g_strdup_printf("Version: %s", p); | |
166 scr_WriteIncomingMessage(bjid, buf, | |
167 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
168 g_free(buf); | |
169 } | |
170 p = lm_message_node_get_child_value(ansqry, "os"); | |
171 if (p) { | |
172 buf = g_strdup_printf("OS: %s", p); | |
173 scr_WriteIncomingMessage(bjid, buf, | |
174 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
175 g_free(buf); | |
176 } | |
177 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
178 } | |
179 | |
180 static LmHandlerResult cb_time(LmMessageHandler *h, LmConnection *c, | |
181 LmMessage *m, gpointer user_data) | |
182 { | |
183 LmMessageNode *ansqry; | |
184 const char *p, *bjid; | |
185 char *tmp; | |
186 char *buf; | |
187 | |
188 ansqry = lm_message_node_get_child(m->node, "query"); | |
189 if (!ansqry) { | |
190 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result!"); | |
191 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
192 } | |
193 // Display IQ result sender... | |
194 p = lm_message_get_from(m); | |
195 if (!p) { | |
196 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:time result (no sender name)."); | |
197 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
198 } | |
199 bjid = p; | |
200 | |
201 buf = g_strdup_printf("Received IQ:time result from <%s>", bjid); | |
202 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); | |
203 | |
204 // bjid should now really be the "bare JID", let's strip the resource | |
205 tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); | |
206 if (tmp) *tmp = '\0'; | |
207 | |
208 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); | |
209 g_free(buf); | |
210 | |
211 // Get result data... | |
212 p = lm_message_node_get_child_value(ansqry, "utc"); | |
213 if (p) { | |
214 buf = g_strdup_printf("UTC: %s", p); | |
215 scr_WriteIncomingMessage(bjid, buf, | |
216 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
217 g_free(buf); | |
218 } | |
219 p = lm_message_node_get_child_value(ansqry, "tz"); | |
220 if (p) { | |
221 buf = g_strdup_printf("TZ: %s", p); | |
222 scr_WriteIncomingMessage(bjid, buf, | |
223 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
224 g_free(buf); | |
225 } | |
226 p = lm_message_node_get_child_value(ansqry, "display"); | |
227 if (p) { | |
228 buf = g_strdup_printf("Time: %s", p); | |
229 scr_WriteIncomingMessage(bjid, buf, | |
230 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
231 g_free(buf); | |
232 } | |
233 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
234 } | |
235 | |
236 static LmHandlerResult cb_last(LmMessageHandler *h, LmConnection *c, | |
237 LmMessage *m, gpointer user_data) | |
238 { | |
239 LmMessageNode *ansqry; | |
240 const char *p, *bjid; | |
241 char *buf, *tmp; | |
242 | |
243 ansqry = lm_message_node_get_child(m->node, "query"); | |
244 if (!ansqry) { | |
245 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result!"); | |
246 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
247 } | |
248 // Display IQ result sender... | |
249 p = lm_message_get_from(m); | |
250 if (!p) { | |
251 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:last result (no sender name)."); | |
252 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
253 } | |
254 bjid = p; | |
255 | |
256 buf = g_strdup_printf("Received IQ:last result from <%s>", bjid); | |
257 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); | |
258 | |
259 // bjid should now really be the "bare JID", let's strip the resource | |
260 tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); | |
261 if (tmp) *tmp = '\0'; | |
262 | |
263 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); | |
264 g_free(buf); | |
265 | |
266 // Get result data... | |
267 p = lm_message_node_get_attribute(ansqry, "seconds"); | |
268 if (p) { | |
269 long int s; | |
270 GString *sbuf; | |
271 sbuf = g_string_new("Idle time: "); | |
272 s = atol(p); | |
273 // Days | |
274 if (s > 86400L) { | |
275 g_string_append_printf(sbuf, "%ldd ", s/86400L); | |
276 s %= 86400L; | |
277 } | |
278 // hh:mm:ss | |
279 g_string_append_printf(sbuf, "%02ld:", s/3600L); | |
280 s %= 3600L; | |
281 g_string_append_printf(sbuf, "%02ld:%02ld", s/60L, s%60L); | |
282 scr_WriteIncomingMessage(bjid, sbuf->str, | |
283 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
284 g_string_free(sbuf, TRUE); | |
285 } else { | |
286 scr_WriteIncomingMessage(bjid, "No idle time reported.", | |
287 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
288 } | |
289 p = lm_message_node_get_value(ansqry); | |
290 if (p) { | |
291 buf = g_strdup_printf("Status message: %s", p); | |
292 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); | |
293 g_free(buf); | |
294 } | |
295 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
296 } | |
297 | |
298 static void display_vcard_item(const char *bjid, const char *label, | |
299 enum vcard_attr vcard_attrib, const char *text) | |
300 { | |
301 char *buf; | |
302 | |
303 if (!text || !bjid || !label) | |
304 return; | |
305 | |
306 buf = g_strdup_printf("%s: %s%s%s%s%s%s%s%s%s%s", label, | |
307 (vcard_attrib & vcard_home ? "[home]" : ""), | |
308 (vcard_attrib & vcard_work ? "[work]" : ""), | |
309 (vcard_attrib & vcard_postal ? "[postal]" : ""), | |
310 (vcard_attrib & vcard_voice ? "[voice]" : ""), | |
311 (vcard_attrib & vcard_fax ? "[fax]" : ""), | |
312 (vcard_attrib & vcard_cell ? "[cell]" : ""), | |
313 (vcard_attrib & vcard_inet ? "[inet]" : ""), | |
314 (vcard_attrib & vcard_pref ? "[pref]" : ""), | |
315 (vcard_attrib ? " " : ""), | |
316 text); | |
317 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0); | |
318 g_free(buf); | |
319 } | |
320 | |
321 static void handle_vcard_node(const char *barejid, LmMessageNode *vcardnode) | |
322 { | |
323 LmMessageNode *x; | |
324 const char *p; | |
325 | |
326 for (x = vcardnode->children ; x; x = x->next) { | |
327 const char *data; | |
328 enum vcard_attr vcard_attrib = 0; | |
329 | |
330 p = x->name; | |
331 data = lm_message_node_get_value(x); | |
332 if (!p || !data) | |
333 continue; | |
334 | |
335 if (!strcmp(p, "FN")) | |
336 display_vcard_item(barejid, "Name", vcard_attrib, data); | |
337 else if (!strcmp(p, "NICKNAME")) | |
338 display_vcard_item(barejid, "Nickname", vcard_attrib, data); | |
339 else if (!strcmp(p, "URL")) | |
340 display_vcard_item(barejid, "URL", vcard_attrib, data); | |
341 else if (!strcmp(p, "BDAY")) | |
342 display_vcard_item(barejid, "Birthday", vcard_attrib, data); | |
343 else if (!strcmp(p, "TZ")) | |
344 display_vcard_item(barejid, "Timezone", vcard_attrib, data); | |
345 else if (!strcmp(p, "TITLE")) | |
346 display_vcard_item(barejid, "Title", vcard_attrib, data); | |
347 else if (!strcmp(p, "ROLE")) | |
348 display_vcard_item(barejid, "Role", vcard_attrib, data); | |
349 else if (!strcmp(p, "DESC")) | |
350 display_vcard_item(barejid, "Comment", vcard_attrib, data); | |
351 else if (!strcmp(p, "N")) { | |
352 data = lm_message_node_get_child_value(x, "FAMILY"); | |
353 display_vcard_item(barejid, "Family Name", vcard_attrib, data); | |
354 data = lm_message_node_get_child_value(x, "GIVEN"); | |
355 display_vcard_item(barejid, "Given Name", vcard_attrib, data); | |
356 data = lm_message_node_get_child_value(x, "MIDDLE"); | |
357 display_vcard_item(barejid, "Middle Name", vcard_attrib, data); | |
358 } else if (!strcmp(p, "ORG")) { | |
359 data = lm_message_node_get_child_value(x, "ORGNAME"); | |
360 display_vcard_item(barejid, "Organisation name", vcard_attrib, data); | |
361 data = lm_message_node_get_child_value(x, "ORGUNIT"); | |
362 display_vcard_item(barejid, "Organisation unit", vcard_attrib, data); | |
363 } else { | |
364 // The HOME, WORK and PREF attributes are common to the remaining fields | |
365 // (ADR, TEL & EMAIL) | |
366 if (lm_message_node_get_child(x, "HOME")) | |
367 vcard_attrib |= vcard_home; | |
368 if (lm_message_node_get_child(x, "WORK")) | |
369 vcard_attrib |= vcard_work; | |
370 if (lm_message_node_get_child(x, "PREF")) | |
371 vcard_attrib |= vcard_pref; | |
372 if (!strcmp(p, "ADR")) { // Address | |
373 if (lm_message_node_get_child(x, "POSTAL")) | |
374 vcard_attrib |= vcard_postal; | |
375 data = lm_message_node_get_child_value(x, "EXTADD"); | |
376 display_vcard_item(barejid, "Addr (ext)", vcard_attrib, data); | |
377 data = lm_message_node_get_child_value(x, "STREET"); | |
378 display_vcard_item(barejid, "Street", vcard_attrib, data); | |
379 data = lm_message_node_get_child_value(x, "LOCALITY"); | |
380 display_vcard_item(barejid, "Locality", vcard_attrib, data); | |
381 data = lm_message_node_get_child_value(x, "REGION"); | |
382 display_vcard_item(barejid, "Region", vcard_attrib, data); | |
383 data = lm_message_node_get_child_value(x, "PCODE"); | |
384 display_vcard_item(barejid, "Postal code", vcard_attrib, data); | |
385 data = lm_message_node_get_child_value(x, "CTRY"); | |
386 display_vcard_item(barejid, "Country", vcard_attrib, data); | |
387 } else if (!strcmp(p, "TEL")) { // Telephone | |
388 data = lm_message_node_get_child_value(x, "NUMBER"); | |
389 if (data) { | |
390 if (lm_message_node_get_child(x, "VOICE")) | |
391 vcard_attrib |= vcard_voice; | |
392 if (lm_message_node_get_child(x, "FAX")) | |
393 vcard_attrib |= vcard_fax; | |
394 if (lm_message_node_get_child(x, "CELL")) | |
395 vcard_attrib |= vcard_cell; | |
396 display_vcard_item(barejid, "Phone", vcard_attrib, data); | |
397 } | |
398 } else if (!strcmp(p, "EMAIL")) { // Email | |
399 if (lm_message_node_get_child(x, "INTERNET")) | |
400 vcard_attrib |= vcard_inet; | |
401 data = lm_message_node_get_child_value(x, "USERID"); | |
402 display_vcard_item(barejid, "Email", vcard_attrib, data); | |
403 } | |
404 } | |
405 } | |
406 } | |
407 | |
408 static LmHandlerResult cb_vcard(LmMessageHandler *h, LmConnection *c, | |
409 LmMessage *m, gpointer user_data) | |
410 { | |
411 LmMessageNode *ansqry; | |
412 const char *p, *bjid; | |
413 char *buf, *tmp; | |
414 | |
415 // Display IQ result sender... | |
416 p = lm_message_get_from(m); | |
417 if (!p) { | |
418 scr_LogPrint(LPRINT_LOGNORM, "Invalid IQ:vCard result (no sender name)."); | |
419 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; | |
420 } | |
421 bjid = p; | |
422 | |
423 buf = g_strdup_printf("Received IQ:vCard result from <%s>", bjid); | |
424 scr_LogPrint(LPRINT_LOGNORM, "%s", buf); | |
425 | |
426 // Get the vCard node | |
427 ansqry = lm_message_node_get_child(m->node, "vCard"); | |
428 if (!ansqry) { | |
429 scr_LogPrint(LPRINT_LOGNORM, "Empty IQ:vCard result!"); | |
430 g_free(buf); | |
431 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
432 } | |
433 | |
434 // bjid should really be the "bare JID", let's strip the resource | |
435 tmp = strchr(bjid, JID_RESOURCE_SEPARATOR); | |
436 if (tmp) *tmp = '\0'; | |
437 | |
438 scr_WriteIncomingMessage(bjid, buf, 0, HBB_PREFIX_INFO, 0); | |
439 g_free(buf); | |
440 | |
441 // Get result data... | |
442 handle_vcard_node(bjid, ansqry); | |
443 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
444 } | |
445 | |
446 static void storage_bookmarks_parse_conference(LmMessageNode *node) | |
447 { | |
448 const char *fjid, *name, *autojoin; | |
449 const char *pstatus, *awhois; | |
450 char *bjid; | |
451 GSList *room_elt; | |
452 | |
453 fjid = lm_message_node_get_attribute(node, "jid"); | |
454 if (!fjid) | |
455 return; | |
456 name = lm_message_node_get_attribute(node, "name"); | |
457 autojoin = lm_message_node_get_attribute(node, "autojoin"); | |
458 awhois = lm_message_node_get_attribute(node, "autowhois"); | |
459 pstatus = lm_message_node_get_child_value(node, "print_status"); | |
460 | |
461 bjid = jidtodisp(fjid); // Bare jid | |
462 | |
463 // Make sure this is a room (it can be a conversion user->room) | |
464 room_elt = roster_find(bjid, jidsearch, 0); | |
465 if (!room_elt) { | |
466 room_elt = roster_add_user(bjid, name, NULL, ROSTER_TYPE_ROOM, | |
467 sub_none, -1); | |
468 } else { | |
469 buddy_settype(room_elt->data, ROSTER_TYPE_ROOM); | |
470 /* | |
471 // If the name is available, should we use it? | |
472 // I don't think so, it would be confusing because this item is already | |
473 // in the roster. | |
474 if (name) | |
475 buddy_setname(room_elt->data, name); | |
476 */ | |
477 } | |
478 | |
479 // Set the print_status and auto_whois values | |
480 if (pstatus) { | |
481 enum room_printstatus i; | |
482 for (i = status_none; i <= status_all; i++) | |
483 if (!strcasecmp(pstatus, strprintstatus[i])) | |
484 break; | |
485 if (i <= status_all) | |
486 buddy_setprintstatus(room_elt->data, i); | |
487 } | |
488 if (awhois) { | |
489 enum room_autowhois i = autowhois_default; | |
490 if (!strcmp(awhois, "1")) | |
491 i = autowhois_on; | |
492 else if (!strcmp(awhois, "0")) | |
493 i = autowhois_off; | |
494 if (i != autowhois_default) | |
495 buddy_setautowhois(room_elt->data, i); | |
496 } | |
497 | |
498 // Is autojoin set? | |
499 // If it is, we'll look up for more information (nick? password?) and | |
500 // try to join the room. | |
501 if (autojoin && !strcmp(autojoin, "1")) { | |
502 const char *nick, *passwd; | |
503 char *tmpnick = NULL; | |
504 nick = lm_message_node_get_child_value(node, "nick"); | |
505 passwd = lm_message_node_get_child_value(node, "password"); | |
506 if (!nick || !*nick) | |
507 nick = tmpnick = default_muc_nickname(NULL); | |
508 // Let's join now | |
509 scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid); | |
510 xmpp_room_join(bjid, nick, passwd); | |
511 g_free(tmpnick); | |
512 } | |
513 g_free(bjid); | |
514 } | |
515 | |
516 static LmHandlerResult cb_storage_bookmarks(LmMessageHandler *h, | |
517 LmConnection *c, | |
518 LmMessage *m, gpointer user_data) | |
519 { | |
520 LmMessageNode *x, *ansqry; | |
521 char *p; | |
522 | |
523 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { | |
524 // No server support, or no bookmarks? | |
525 p = m->node->children->name; | |
526 if (p && !strcmp(p, "item-not-found")) { | |
527 // item-no-found means the server has Private Storage, but it's | |
528 // currently empty. | |
529 if (bookmarks) | |
530 lm_message_node_unref(bookmarks); | |
531 bookmarks = lm_message_node_new("storage", "storage:bookmarks"); | |
532 // We return 0 so that the IQ error message be | |
533 // not displayed, as it isn't a real error. | |
534 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
535 } | |
536 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Unhandled error | |
537 } | |
538 | |
539 ansqry = lm_message_node_get_child(m->node, "query"); | |
540 ansqry = lm_message_node_get_child(ansqry, "storage"); | |
541 if (!ansqry) { | |
542 scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! (storage:bookmarks)"); | |
543 return 0; | |
544 } | |
545 | |
546 // Walk through the storage tags | |
547 for (x = ansqry->children ; x; x = x->next) { | |
548 // If the current node is a conference item, parse it and update the roster | |
549 if (x->name && !strcmp(x->name, "conference")) | |
550 storage_bookmarks_parse_conference(x); | |
551 } | |
552 // "Copy" the bookmarks node | |
553 if (bookmarks) | |
554 lm_message_node_unref(bookmarks); | |
555 lm_message_node_deep_ref(ansqry); | |
556 bookmarks = ansqry; | |
557 return 0; | |
558 } | |
559 | |
560 | |
561 static LmHandlerResult cb_storage_rosternotes(LmMessageHandler *h, | |
562 LmConnection *c, | |
563 LmMessage *m, gpointer user_data) | |
564 { | |
565 LmMessageNode *ansqry; | |
566 | |
567 if (lm_message_get_sub_type(m) == LM_MESSAGE_SUB_TYPE_ERROR) { | |
568 const char *p; | |
569 // No server support, or no roster notes? | |
570 p = m->node->children->name; | |
571 if (p && !strcmp(p, "item-not-found")) { | |
572 // item-no-found means the server has Private Storage, but it's | |
573 // currently empty. | |
574 if (rosternotes) | |
575 lm_message_node_unref(rosternotes); | |
576 rosternotes = lm_message_node_new("storage", "storage:rosternotes"); | |
577 // We return 0 so that the IQ error message be | |
578 // not displayed, as it isn't a real error. | |
579 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
580 } | |
581 return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; // Unhandled error | |
582 } | |
583 | |
584 ansqry = lm_message_node_get_child(m->node, "query"); | |
585 ansqry = lm_message_node_get_child(ansqry, "storage"); | |
586 if (!ansqry) { | |
587 scr_LogPrint(LPRINT_LOG, "Invalid IQ:private result! " | |
588 "(storage:rosternotes)"); | |
589 return LM_HANDLER_RESULT_REMOVE_MESSAGE; | |
590 } | |
591 // Copy the rosternotes node | |
592 if (rosternotes) | |
593 lm_message_node_unref(rosternotes); | |
594 lm_message_node_deep_ref(ansqry); | |
595 rosternotes = ansqry; | |
596 return 0; | |
597 } | |
598 | |
599 | |
600 static struct IqRequestStorageHandlers | |
601 { | |
602 const gchar *storagens; | |
603 LmHandleMessageFunction handler; | |
604 } iq_request_storage_handlers[] = { | |
605 {"storage:rosternotes", &cb_storage_rosternotes}, | |
606 {"storage:bookmarks", &cb_storage_bookmarks}, | |
607 {NULL, NULL} | |
608 }; | |
609 | |
610 void xmpp_request_storage(const gchar *storage) | |
611 { | |
612 LmMessage *iq; | |
613 LmMessageNode *query; | |
614 LmMessageHandler *handler; | |
615 int i; | |
616 | |
617 iq = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_IQ, | |
618 LM_MESSAGE_SUB_TYPE_GET); | |
619 query = lm_message_node_add_child(iq->node, "query", NULL); | |
620 lm_message_node_set_attribute(query, "xmlns", NS_PRIVATE); | |
621 lm_message_node_set_attribute(lm_message_node_add_child | |
622 (query, "storage", NULL), | |
623 "xmlns", storage); | |
624 | |
625 for (i = 0; | |
626 strcmp(iq_request_storage_handlers[i].storagens, storage) != 0; | |
627 ++i) ; | |
628 | |
629 handler = lm_message_handler_new(iq_request_storage_handlers[i].handler, | |
630 NULL, FALSE); | |
631 lm_connection_send_with_reply(lconnection, iq, handler, NULL); | |
632 lm_message_handler_unref(handler); | |
633 lm_message_unref(iq); | |
634 } | |
635 | |
636 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ |