Mercurial > pidgin.yaz
annotate src/protocols/jabber/jabber.c @ 8273:f24172f53650
[gaim-migrate @ 8997]
This is Scott Lamb's eventloop abstraction patch. If it breaks things,
Scott Lamb will be glad to take the punishment. If it doesn't, it should
make integration into other event loops easier. Well, no, not easier,
harder actually, but it'll be done more appropriately and less hackily..
er, hacky. Is hackily a word?
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Tue, 17 Feb 2004 02:17:48 +0000 |
parents | 22b3974dc1af |
children | dd6fe7d965aa |
rev | line source |
---|---|
2086 | 1 /* |
7014 | 2 * gaim - Jabber Protocol Plugin |
2086 | 3 * |
7014 | 4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> |
2086 | 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. | |
7014 | 10 * |
2086 | 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 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
21 #include "internal.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
22 |
7014 | 23 #include "account.h" |
24 #include "accountopt.h" | |
25 #include "debug.h" | |
26 #include "message.h" | |
27 #include "multi.h" | |
7072 | 28 #include "notify.h" |
7014 | 29 #include "prpl.h" |
7072 | 30 #include "request.h" |
7014 | 31 #include "server.h" |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
32 #include "util.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
33 |
7014 | 34 #include "auth.h" |
35 #include "buddy.h" | |
36 #include "chat.h" | |
37 #include "iq.h" | |
38 #include "jutil.h" | |
39 #include "message.h" | |
40 #include "parser.h" | |
41 #include "presence.h" | |
42 #include "jabber.h" | |
43 #include "roster.h" | |
7923 | 44 #include "xdata.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
45 |
7014 | 46 #define JABBER_CONNECT_STEPS (js->gsc ? 8 : 5) |
2086 | 47 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
48 static GaimPlugin *my_protocol = NULL; |
4249 | 49 |
7014 | 50 static void jabber_stream_init(JabberStream *js) |
51 { | |
52 char *open_stream; | |
3340 | 53 |
7014 | 54 open_stream = g_strdup_printf("<stream:stream to='%s' " |
55 "xmlns='jabber:client' " | |
7395 | 56 "xmlns:stream='http://etherx.jabber.org/streams' " |
57 "version='1.0'>", | |
7291 | 58 js->user->domain); |
3311 | 59 |
7642 | 60 jabber_send_raw(js, open_stream, -1); |
2086 | 61 |
7014 | 62 g_free(open_stream); |
2086 | 63 } |
64 | |
7395 | 65 static void |
66 jabber_session_initialized_cb(JabberStream *js, xmlnode *packet, gpointer data) | |
3311 | 67 { |
7014 | 68 const char *type = xmlnode_get_attrib(packet, "type"); |
69 if(type && !strcmp(type, "result")) { | |
70 jabber_stream_set_state(js, JABBER_STREAM_CONNECTED); | |
71 } else { | |
72 gaim_connection_error(js->gc, _("Error initializing session")); | |
3311 | 73 } |
74 } | |
75 | |
7014 | 76 static void jabber_session_init(JabberStream *js) |
3311 | 77 { |
7014 | 78 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); |
79 xmlnode *session; | |
3311 | 80 |
7395 | 81 jabber_iq_set_callback(iq, jabber_session_initialized_cb, NULL); |
3311 | 82 |
7014 | 83 session = xmlnode_new_child(iq->node, "session"); |
84 xmlnode_set_attrib(session, "xmlns", "urn:ietf:params:xml:ns:xmpp-session"); | |
3311 | 85 |
7014 | 86 jabber_iq_send(iq); |
3311 | 87 } |
88 | |
7395 | 89 static void jabber_bind_result_cb(JabberStream *js, xmlnode *packet, |
90 gpointer data) | |
91 { | |
7923 | 92 /* XXX: check for errors, re-set our own js->user JID */ |
7395 | 93 |
94 jabber_session_init(js); | |
95 } | |
96 | |
97 static void jabber_stream_features_parse(JabberStream *js, xmlnode *packet) | |
98 { | |
99 if(xmlnode_get_child(packet, "mechanisms")) { | |
100 jabber_auth_start(js, packet); | |
101 } else if(xmlnode_get_child(packet, "bind")) { | |
102 xmlnode *bind, *resource; | |
103 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); | |
104 bind = xmlnode_new_child(iq->node, "bind"); | |
105 xmlnode_set_attrib(bind, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind"); | |
106 resource = xmlnode_new_child(bind, "resource"); | |
107 xmlnode_insert_data(resource, js->user->resource, -1); | |
108 | |
109 jabber_iq_set_callback(iq, jabber_bind_result_cb, NULL); | |
110 | |
111 jabber_iq_send(iq); | |
112 } | |
113 } | |
114 | |
7014 | 115 static void jabber_stream_handle_error(JabberStream *js, xmlnode *packet) |
3311 | 116 { |
7014 | 117 xmlnode *textnode; |
118 char *error_text = NULL; | |
119 const char *text; | |
120 char *buf; | |
3311 | 121 |
7014 | 122 if(xmlnode_get_child(packet, "bad-format")) { |
123 text = _("Bad Format"); | |
124 } else if(xmlnode_get_child(packet, "bad-namespace-prefix")) { | |
125 text = _("Bad Namespace Prefix"); | |
126 } else if(xmlnode_get_child(packet, "conflict")) { | |
127 js->gc->wants_to_die = TRUE; | |
128 text = _("Resource Conflict"); | |
129 } else if(xmlnode_get_child(packet, "connection-timeout")) { | |
130 text = _("Connection Timeout"); | |
131 } else if(xmlnode_get_child(packet, "host-gone")) { | |
132 text = _("Host Gone"); | |
133 } else if(xmlnode_get_child(packet, "host-unknown")) { | |
134 text = _("Host Unknown"); | |
135 } else if(xmlnode_get_child(packet, "improper-addressing")) { | |
136 text = _("Improper Addressing"); | |
137 } else if(xmlnode_get_child(packet, "internal-server-error")) { | |
138 text = _("Internal Server Error"); | |
139 } else if(xmlnode_get_child(packet, "invalid-id")) { | |
140 text = _("Invalid ID"); | |
141 } else if(xmlnode_get_child(packet, "invalid-namespace")) { | |
142 text = _("Invalid Namespace"); | |
143 } else if(xmlnode_get_child(packet, "invalid-xml")) { | |
144 text = _("Invalid XML"); | |
145 } else if(xmlnode_get_child(packet, "nonmatching-hosts")) { | |
146 text = _("Non-matching Hosts"); | |
147 } else if(xmlnode_get_child(packet, "not-authorized")) { | |
148 text = _("Not Authorized"); | |
149 } else if(xmlnode_get_child(packet, "policy-violation")) { | |
150 text = _("Policy Violation"); | |
151 } else if(xmlnode_get_child(packet, "remote-connection-failed")) { | |
152 text = _("Remote Connection Failed"); | |
153 } else if(xmlnode_get_child(packet, "resource-constraint")) { | |
154 text = _("Resource Constraint"); | |
155 } else if(xmlnode_get_child(packet, "restricted-xml")) { | |
156 text = _("Restricted XML"); | |
157 } else if(xmlnode_get_child(packet, "see-other-host")) { | |
158 text = _("See Other Host"); | |
159 } else if(xmlnode_get_child(packet, "system-shutdown")) { | |
160 text = _("System Shutdown"); | |
161 } else if(xmlnode_get_child(packet, "undefined-condition")) { | |
162 text = _("Undefined Condition"); | |
163 } else if(xmlnode_get_child(packet, "unsupported-encoding")) { | |
7417 | 164 text = _("Unsupported Encoding"); |
7014 | 165 } else if(xmlnode_get_child(packet, "unsupported-stanza-type")) { |
166 text = _("Unsupported Stanza Type"); | |
167 } else if(xmlnode_get_child(packet, "unsupported-version")) { | |
168 text = _("Unsupported Version"); | |
169 } else if(xmlnode_get_child(packet, "xml-not-well-formed")) { | |
170 text = _("XML Not Well Formed"); | |
3311 | 171 } else { |
7014 | 172 text = _("Stream Error"); |
3311 | 173 } |
174 | |
7014 | 175 if((textnode = xmlnode_get_child(packet, "text"))) |
176 error_text = xmlnode_get_data(textnode); | |
2086 | 177 |
7014 | 178 buf = g_strdup_printf("%s%s%s", text, |
179 error_text ? ": " : "", | |
180 error_text ? error_text : ""); | |
181 gaim_connection_error(js->gc, buf); | |
182 g_free(buf); | |
183 if(error_text) | |
184 g_free(error_text); | |
2086 | 185 } |
186 | |
7014 | 187 static void tls_init(JabberStream *js); |
2086 | 188 |
7014 | 189 void jabber_process_packet(JabberStream *js, xmlnode *packet) |
2086 | 190 { |
7014 | 191 if(!strcmp(packet->name, "iq")) { |
7395 | 192 jabber_iq_parse(js, packet); |
7014 | 193 } else if(!strcmp(packet->name, "presence")) { |
194 jabber_presence_parse(js, packet); | |
195 } else if(!strcmp(packet->name, "message")) { | |
196 jabber_message_parse(js, packet); | |
197 } else if(!strcmp(packet->name, "stream:features")) { | |
7395 | 198 jabber_stream_features_parse(js, packet); |
7014 | 199 } else if(!strcmp(packet->name, "stream:error")) { |
200 jabber_stream_handle_error(js, packet); | |
201 } else if(!strcmp(packet->name, "challenge")) { | |
202 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
203 jabber_auth_handle_challenge(js, packet); | |
204 } else if(!strcmp(packet->name, "success")) { | |
205 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
206 jabber_auth_handle_success(js, packet); | |
207 } else if(!strcmp(packet->name, "failure")) { | |
208 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
209 jabber_auth_handle_failure(js, packet); | |
210 } else if(!strcmp(packet->name, "proceed")) { | |
211 if(js->state == JABBER_STREAM_AUTHENTICATING && !js->gsc) | |
212 tls_init(js); | |
213 } else { | |
214 gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown packet: %s\n", | |
215 packet->name); | |
2086 | 216 } |
217 } | |
218 | |
7642 | 219 void jabber_send_raw(JabberStream *js, const char *data, int len) |
2086 | 220 { |
7014 | 221 int ret; |
2086 | 222 |
7014 | 223 /* because printing a tab to debug every minute gets old */ |
224 if(strcmp(data, "\t")) | |
225 gaim_debug(GAIM_DEBUG_MISC, "jabber", "Sending%s: %s\n", | |
226 js->gsc ? " (ssl)" : "", data); | |
2086 | 227 |
7014 | 228 if(js->gsc) { |
7642 | 229 ret = gaim_ssl_write(js->gsc, data, len == -1 ? strlen(data) : len); |
7014 | 230 } else { |
8013 | 231 if(js->fd < 0) |
232 return; | |
7642 | 233 ret = write(js->fd, data, len == -1 ? strlen(data) : len); |
2814
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
234 } |
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
235 |
7014 | 236 if(ret < 0) |
237 gaim_connection_error(js->gc, _("Write error")); | |
238 | |
2814
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
239 } |
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
240 |
7014 | 241 void jabber_send(JabberStream *js, xmlnode *packet) |
2086 | 242 { |
7014 | 243 char *txt; |
7642 | 244 int len; |
2086 | 245 |
7642 | 246 txt = xmlnode_to_str(packet, &len); |
247 jabber_send_raw(js, txt, len); | |
7014 | 248 g_free(txt); |
2086 | 249 } |
250 | |
7014 | 251 static void jabber_keepalive(GaimConnection *gc) |
2086 | 252 { |
7642 | 253 jabber_send_raw(gc->proto_data, "\t", -1); |
2086 | 254 } |
255 | |
7014 | 256 static void |
257 jabber_recv_cb_ssl(gpointer data, GaimSslConnection *gsc, | |
6764 | 258 GaimInputCondition cond) |
259 { | |
7014 | 260 GaimConnection *gc = data; |
261 JabberStream *js = gc->proto_data; | |
6764 | 262 int len; |
7014 | 263 static char buf[4096]; |
6768 | 264 |
7014 | 265 if(!g_list_find(gaim_connections_get_all(), gc)) { |
6768 | 266 gaim_ssl_close(gsc); |
267 return; | |
268 } | |
269 | |
7014 | 270 if((len = gaim_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) { |
6764 | 271 buf[len] = '\0'; |
7014 | 272 gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (ssl)(%d): %s\n", len, buf); |
273 jabber_parser_process(js, buf, len); | |
7177 | 274 } else { |
275 gaim_connection_error(gc, _("Read Error")); | |
2086 | 276 } |
277 } | |
278 | |
7014 | 279 static void |
280 jabber_recv_cb(gpointer data, gint source, GaimInputCondition condition) | |
2086 | 281 { |
5572 | 282 GaimConnection *gc = data; |
7014 | 283 JabberStream *js = gc->proto_data; |
284 int len; | |
285 static char buf[4096]; | |
2086 | 286 |
7014 | 287 if(!g_list_find(gaim_connections_get_all(), gc)) |
288 return; | |
2956 | 289 |
7014 | 290 if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) { |
291 buf[len] = '\0'; | |
292 gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (%d): %s\n", len, buf); | |
293 jabber_parser_process(js, buf, len); | |
7177 | 294 } else { |
295 gaim_connection_error(gc, _("Read Error")); | |
7014 | 296 } |
2086 | 297 } |
298 | |
7014 | 299 static void |
300 jabber_login_callback_ssl(gpointer data, GaimSslConnection *gsc, | |
6764 | 301 GaimInputCondition cond) |
302 { | |
303 GaimConnection *gc = data; | |
7014 | 304 JabberStream *js = gc->proto_data; |
6764 | 305 |
7014 | 306 if(!g_list_find(gaim_connections_get_all(), gc)) { |
6764 | 307 gaim_ssl_close(gsc); |
308 return; | |
309 } | |
310 | |
7014 | 311 js->gsc = gsc; |
6764 | 312 |
7014 | 313 if(js->state == JABBER_STREAM_CONNECTING) |
7642 | 314 jabber_send_raw(js, "<?xml version='1.0' ?>", -1); |
6764 | 315 |
7014 | 316 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
317 gaim_ssl_input_add(gsc, jabber_recv_cb_ssl, gc); | |
6764 | 318 } |
319 | |
7014 | 320 |
321 static void | |
322 jabber_login_callback(gpointer data, gint source, GaimInputCondition cond) | |
6764 | 323 { |
5572 | 324 GaimConnection *gc = data; |
7014 | 325 JabberStream *js = gc->proto_data; |
2086 | 326 |
7014 | 327 if(!g_list_find(gaim_connections_get_all(), gc)) { |
2086 | 328 close(source); |
329 return; | |
330 } | |
331 | |
7014 | 332 js->fd = source; |
2956 | 333 |
7014 | 334 if(js->state == JABBER_STREAM_CONNECTING) |
7642 | 335 jabber_send_raw(js, "<?xml version='1.0' ?>", -1); |
2300
d2686f757d6e
[gaim-migrate @ 2310]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2289
diff
changeset
|
336 |
7014 | 337 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
338 gc->inpa = gaim_input_add(js->fd, GAIM_INPUT_READ, jabber_recv_cb, gc); | |
339 } | |
2086 | 340 |
7014 | 341 static void |
7426 | 342 jabber_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, |
343 gpointer data) | |
344 { | |
345 GaimConnection *gc = data; | |
346 | |
347 switch(error) { | |
348 case GAIM_SSL_HANDSHAKE_FAILED: | |
349 gaim_connection_error(gc, _("SSL Handshake Failed")); | |
350 break; | |
351 } | |
352 } | |
353 | |
7427 | 354 static void tls_init(JabberStream *js) |
355 { | |
356 gaim_input_remove(js->gc->inpa); | |
357 js->gc->inpa = 0; | |
358 js->gsc = gaim_ssl_connect_fd(js->gc->account, js->fd, | |
359 jabber_login_callback_ssl, jabber_ssl_connect_failure, js->gc); | |
360 } | |
361 | |
362 | |
7426 | 363 static void |
7014 | 364 jabber_login(GaimAccount *account) |
2086 | 365 { |
7014 | 366 int rc; |
367 GaimConnection *gc = gaim_account_get_connection(account); | |
368 const char *connect_server = gaim_account_get_string(account, | |
369 "connect_server", ""); | |
5572 | 370 const char *server; |
7014 | 371 JabberStream *js; |
2086 | 372 |
7014 | 373 gc->flags |= GAIM_CONNECTION_HTML; |
374 js = gc->proto_data = g_new0(JabberStream, 1); | |
375 js->gc = gc; | |
8013 | 376 js->fd = -1; |
7014 | 377 js->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, |
7395 | 378 g_free, g_free); |
7014 | 379 js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal, |
7116 | 380 g_free, (GDestroyNotify)jabber_buddy_free); |
7014 | 381 js->chats = g_hash_table_new_full(g_str_hash, g_str_equal, |
382 g_free, NULL); | |
8043 | 383 js->chat_servers = g_list_append(NULL, g_strdup("conference.jabber.org")); |
7014 | 384 js->user = jabber_id_new(gaim_account_get_username(account)); |
7322 | 385 js->next_id = g_random_int(); |
5613 | 386 |
7310 | 387 if(!js->user) { |
388 gaim_connection_error(gc, _("Invalid Jabber ID")); | |
389 return; | |
390 } | |
391 | |
7147 | 392 if(!js->user->resource) { |
393 char *me; | |
394 js->user->resource = g_strdup("Gaim"); | |
395 if(!js->user->node) { | |
396 js->user->node = js->user->domain; | |
397 js->user->domain = g_strdup("jabber.org"); | |
398 } | |
399 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, | |
400 js->user->resource); | |
401 gaim_account_set_username(account, me); | |
402 g_free(me); | |
7145 | 403 } |
404 | |
7014 | 405 server = connect_server[0] ? connect_server : js->user->domain; |
2086 | 406 |
7014 | 407 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); |
2956 | 408 |
7630 | 409 |
410 if(gaim_account_get_bool(account, "old_ssl", FALSE)) { | |
411 if(gaim_ssl_is_supported()) { | |
412 js->gsc = gaim_ssl_connect(account, server, | |
413 gaim_account_get_int(account, "port", 5222), | |
414 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); | |
415 } else { | |
416 gaim_connection_error(gc, _("SSL support unavailable")); | |
417 } | |
3311 | 418 } |
3770 | 419 |
7014 | 420 if(!js->gsc) { |
421 rc = gaim_proxy_connect(account, server, | |
422 gaim_account_get_int(account, "port", 5222), | |
423 jabber_login_callback, gc); | |
2086 | 424 |
7014 | 425 if (rc != 0) |
426 gaim_connection_error(gc, _("Unable to create socket")); | |
2956 | 427 } |
2086 | 428 } |
429 | |
7072 | 430 static gboolean |
431 conn_close_cb(gpointer data) | |
432 { | |
433 JabberStream *js = data; | |
434 gaim_connection_destroy(js->gc); | |
435 return FALSE; | |
436 } | |
437 | |
438 static void | |
439 jabber_connection_schedule_close(JabberStream *js) | |
440 { | |
8273
f24172f53650
[gaim-migrate @ 8997]
Christian Hammond <chipx86@chipx86.com>
parents:
8194
diff
changeset
|
441 gaim_timeout_add(0, conn_close_cb, js); |
7072 | 442 } |
443 | |
444 static void | |
7395 | 445 jabber_registration_result_cb(JabberStream *js, xmlnode *packet, gpointer data) |
7072 | 446 { |
447 const char *type = xmlnode_get_attrib(packet, "type"); | |
448 char *buf; | |
449 | |
450 if(!strcmp(type, "result")) { | |
451 buf = g_strdup_printf(_("Registration of %s@%s successful"), | |
452 js->user->node, js->user->domain); | |
453 gaim_notify_info(NULL, _("Registration Successful"), | |
454 _("Registration Successful"), buf); | |
455 g_free(buf); | |
456 } else { | |
457 char *error; | |
458 xmlnode *y; | |
459 | |
460 if((y = xmlnode_get_child(packet, "error"))) { | |
461 error = xmlnode_get_data(y); | |
462 } else { | |
463 error = g_strdup(_("Unknown Error")); | |
464 } | |
465 | |
466 buf = g_strdup_printf(_("Registration of %s@%s failed: %s"), | |
467 js->user->node, js->user->domain, error); | |
468 gaim_notify_error(NULL, _("Registration Failed"), | |
469 _("Registration Failed"), buf); | |
470 g_free(buf); | |
471 g_free(error); | |
472 } | |
473 jabber_connection_schedule_close(js); | |
474 } | |
475 | |
476 static void | |
477 jabber_register_cb(JabberStream *js, GaimRequestFields *fields) | |
478 { | |
479 GList *groups, *flds; | |
480 xmlnode *query, *y; | |
481 JabberIq *iq; | |
7264 | 482 char *username; |
7072 | 483 |
484 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
485 query = xmlnode_get_child(iq->node, "query"); | |
486 | |
487 for(groups = gaim_request_fields_get_groups(fields); groups; | |
488 groups = groups->next) { | |
489 for(flds = gaim_request_field_group_get_fields(groups->data); | |
490 flds; flds = flds->next) { | |
491 GaimRequestField *field = flds->data; | |
492 const char *id = gaim_request_field_get_id(field); | |
493 const char *value = gaim_request_field_string_get_value(field); | |
494 | |
495 if(!strcmp(id, "username")) { | |
496 y = xmlnode_new_child(query, "username"); | |
497 } else if(!strcmp(id, "password")) { | |
498 y = xmlnode_new_child(query, "password"); | |
499 } else if(!strcmp(id, "name")) { | |
500 y = xmlnode_new_child(query, "name"); | |
501 } else if(!strcmp(id, "email")) { | |
502 y = xmlnode_new_child(query, "email"); | |
503 } else if(!strcmp(id, "nick")) { | |
504 y = xmlnode_new_child(query, "nick"); | |
505 } else if(!strcmp(id, "first")) { | |
506 y = xmlnode_new_child(query, "first"); | |
507 } else if(!strcmp(id, "last")) { | |
508 y = xmlnode_new_child(query, "last"); | |
509 } else if(!strcmp(id, "address")) { | |
510 y = xmlnode_new_child(query, "address"); | |
511 } else if(!strcmp(id, "city")) { | |
512 y = xmlnode_new_child(query, "city"); | |
513 } else if(!strcmp(id, "state")) { | |
514 y = xmlnode_new_child(query, "state"); | |
515 } else if(!strcmp(id, "zip")) { | |
516 y = xmlnode_new_child(query, "zip"); | |
517 } else if(!strcmp(id, "phone")) { | |
518 y = xmlnode_new_child(query, "phone"); | |
519 } else if(!strcmp(id, "url")) { | |
520 y = xmlnode_new_child(query, "url"); | |
521 } else if(!strcmp(id, "date")) { | |
522 y = xmlnode_new_child(query, "date"); | |
523 } else { | |
524 continue; | |
525 } | |
526 xmlnode_insert_data(y, value, -1); | |
7264 | 527 if(!strcmp(id, "username")) { |
528 if(js->user->node) | |
529 g_free(js->user->node); | |
530 js->user->node = g_strdup(value); | |
531 } | |
7072 | 532 } |
533 } | |
534 | |
7264 | 535 username = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, |
536 js->user->resource); | |
537 gaim_account_set_username(js->gc->account, username); | |
538 g_free(username); | |
539 | |
7395 | 540 jabber_iq_set_callback(iq, jabber_registration_result_cb, NULL); |
7072 | 541 |
542 jabber_iq_send(iq); | |
543 | |
544 } | |
545 | |
546 static void | |
547 jabber_register_cancel_cb(JabberStream *js, GaimRequestFields *fields) | |
548 { | |
549 jabber_connection_schedule_close(js); | |
550 } | |
551 | |
7923 | 552 static void jabber_register_x_data_cb(JabberStream *js, xmlnode *result, gpointer data) |
553 { | |
554 xmlnode *query; | |
555 JabberIq *iq; | |
556 | |
557 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
558 query = xmlnode_get_child(iq->node, "query"); | |
559 | |
560 xmlnode_insert_child(query, result); | |
561 | |
562 jabber_iq_set_callback(iq, jabber_registration_result_cb, NULL); | |
563 jabber_iq_send(iq); | |
564 } | |
565 | |
7072 | 566 void jabber_register_parse(JabberStream *js, xmlnode *packet) |
567 { | |
568 if(js->registration) { | |
569 GaimRequestFields *fields; | |
570 GaimRequestFieldGroup *group; | |
571 GaimRequestField *field; | |
7923 | 572 xmlnode *query, *x, *y; |
7072 | 573 char *instructions; |
574 | |
575 /* get rid of the login thingy */ | |
576 gaim_connection_set_state(js->gc, GAIM_CONNECTED); | |
577 | |
578 query = xmlnode_get_child(packet, "query"); | |
579 | |
580 if(xmlnode_get_child(query, "registered")) { | |
581 gaim_notify_error(NULL, _("Already Registered"), | |
582 _("Already Registered"), NULL); | |
583 jabber_connection_schedule_close(js); | |
584 return; | |
585 } | |
586 | |
8135 | 587 for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) { |
7923 | 588 const char *xmlns; |
589 if(!(xmlns = xmlnode_get_attrib(x, "xmlns"))) | |
590 continue; | |
591 | |
592 if(!strcmp(xmlns, "jabber:x:data")) { | |
593 jabber_x_data_request(js, x, jabber_register_x_data_cb, NULL); | |
594 return; | |
595 } | |
596 } | |
597 | |
598 /* XXX: if no jabber:x:data, but jabber:x:oob is there, use that */ | |
599 | |
600 /* as a last resort, use the old jabber:iq:register syntax */ | |
601 | |
7072 | 602 fields = gaim_request_fields_new(); |
603 group = gaim_request_field_group_new(NULL); | |
604 gaim_request_fields_add_group(fields, group); | |
605 | |
606 field = gaim_request_field_string_new("username", _("Username"), | |
607 js->user->node, FALSE); | |
608 gaim_request_field_group_add_field(group, field); | |
609 | |
610 field = gaim_request_field_string_new("password", _("Password"), | |
611 gaim_account_get_password(js->gc->account), FALSE); | |
612 gaim_request_field_string_set_masked(field, TRUE); | |
613 gaim_request_field_group_add_field(group, field); | |
614 | |
615 if(xmlnode_get_child(query, "name")) { | |
616 field = gaim_request_field_string_new("name", _("Name"), | |
617 gaim_account_get_alias(js->gc->account), FALSE); | |
618 gaim_request_field_group_add_field(group, field); | |
619 } | |
620 if(xmlnode_get_child(query, "email")) { | |
621 field = gaim_request_field_string_new("email", _("E-Mail"), | |
622 NULL, FALSE); | |
623 gaim_request_field_group_add_field(group, field); | |
624 } | |
625 if(xmlnode_get_child(query, "nick")) { | |
626 field = gaim_request_field_string_new("nick", _("Nickname"), | |
627 NULL, FALSE); | |
628 gaim_request_field_group_add_field(group, field); | |
629 } | |
630 if(xmlnode_get_child(query, "first")) { | |
631 field = gaim_request_field_string_new("first", _("First Name"), | |
632 NULL, FALSE); | |
633 gaim_request_field_group_add_field(group, field); | |
634 } | |
635 if(xmlnode_get_child(query, "last")) { | |
636 field = gaim_request_field_string_new("last", _("Last Name"), | |
637 NULL, FALSE); | |
638 gaim_request_field_group_add_field(group, field); | |
639 } | |
640 if(xmlnode_get_child(query, "address")) { | |
641 field = gaim_request_field_string_new("address", _("Address"), | |
642 NULL, FALSE); | |
643 gaim_request_field_group_add_field(group, field); | |
644 } | |
645 if(xmlnode_get_child(query, "city")) { | |
646 field = gaim_request_field_string_new("city", _("City"), | |
647 NULL, FALSE); | |
648 gaim_request_field_group_add_field(group, field); | |
649 } | |
650 if(xmlnode_get_child(query, "state")) { | |
651 field = gaim_request_field_string_new("state", _("State"), | |
652 NULL, FALSE); | |
653 gaim_request_field_group_add_field(group, field); | |
654 } | |
655 if(xmlnode_get_child(query, "zip")) { | |
656 field = gaim_request_field_string_new("zip", _("Postal Code"), | |
657 NULL, FALSE); | |
658 gaim_request_field_group_add_field(group, field); | |
659 } | |
660 if(xmlnode_get_child(query, "phone")) { | |
661 field = gaim_request_field_string_new("phone", _("Phone"), | |
662 NULL, FALSE); | |
663 gaim_request_field_group_add_field(group, field); | |
664 } | |
665 if(xmlnode_get_child(query, "url")) { | |
666 field = gaim_request_field_string_new("url", _("URL"), | |
667 NULL, FALSE); | |
668 gaim_request_field_group_add_field(group, field); | |
669 } | |
670 if(xmlnode_get_child(query, "date")) { | |
671 field = gaim_request_field_string_new("date", _("Date"), | |
672 NULL, FALSE); | |
673 gaim_request_field_group_add_field(group, field); | |
674 } | |
675 | |
676 if((y = xmlnode_get_child(query, "instructions"))) | |
677 instructions = xmlnode_get_data(y); | |
678 else | |
679 instructions = g_strdup(_("Please fill out the information below " | |
680 "to register your new account.")); | |
681 | |
682 gaim_request_fields(js->gc, _("Register New Jabber Account"), | |
683 _("Register New Jabber Account"), instructions, fields, | |
684 _("Register"), G_CALLBACK(jabber_register_cb), | |
685 _("Cancel"), G_CALLBACK(jabber_register_cancel_cb), js); | |
686 } | |
687 } | |
688 | |
8016 | 689 void jabber_register_start(JabberStream *js) |
7072 | 690 { |
691 JabberIq *iq; | |
692 | |
693 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:register"); | |
694 jabber_iq_send(iq); | |
695 } | |
696 | |
697 static void jabber_register_account(GaimAccount *account) | |
698 { | |
699 GaimConnection *gc = gaim_account_get_connection(account); | |
700 JabberStream *js; | |
701 const char *connect_server = gaim_account_get_string(account, | |
702 "connect_server", ""); | |
703 const char *server; | |
704 int rc; | |
705 | |
706 js = gc->proto_data = g_new0(JabberStream, 1); | |
707 js->gc = gc; | |
708 js->registration = TRUE; | |
709 js->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, | |
7395 | 710 g_free, g_free); |
7072 | 711 js->user = jabber_id_new(gaim_account_get_username(account)); |
7322 | 712 js->next_id = g_random_int(); |
7072 | 713 |
7310 | 714 if(!js->user) { |
715 gaim_connection_error(gc, _("Invalid Jabber ID")); | |
716 return; | |
717 } | |
718 | |
7147 | 719 if(!js->user->resource) { |
720 char *me; | |
721 js->user->resource = g_strdup("Gaim"); | |
722 if(!js->user->node) { | |
723 js->user->node = js->user->domain; | |
724 js->user->domain = g_strdup("jabber.org"); | |
725 } | |
726 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, | |
727 js->user->resource); | |
728 gaim_account_set_username(account, me); | |
729 g_free(me); | |
730 } | |
731 | |
7072 | 732 server = connect_server[0] ? connect_server : js->user->domain; |
733 | |
734 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); | |
735 | |
7630 | 736 if(gaim_account_get_bool(account, "old_ssl", FALSE)) { |
737 if(gaim_ssl_is_supported()) { | |
738 js->gsc = gaim_ssl_connect(account, server, | |
739 gaim_account_get_int(account, "port", 5222), | |
740 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); | |
741 } else { | |
742 gaim_connection_error(gc, _("SSL support unavailable")); | |
743 } | |
7072 | 744 } |
745 | |
746 if(!js->gsc) { | |
747 rc = gaim_proxy_connect(account, server, | |
748 gaim_account_get_int(account, "port", 5222), | |
749 jabber_login_callback, gc); | |
750 | |
751 if (rc != 0) | |
752 gaim_connection_error(gc, _("Unable to create socket")); | |
753 } | |
754 } | |
755 | |
5572 | 756 static void jabber_close(GaimConnection *gc) |
2086 | 757 { |
7014 | 758 JabberStream *js = gc->proto_data; |
2956 | 759 |
7642 | 760 jabber_send_raw(js, "</stream:stream>", -1); |
3311 | 761 |
7014 | 762 if(js->gsc) { |
763 gaim_ssl_close(js->gsc); | |
764 } else { | |
7072 | 765 if(js->gc->inpa) |
766 gaim_input_remove(js->gc->inpa); | |
7014 | 767 close(js->fd); |
768 } | |
3311 | 769 |
7587 | 770 if(js->context) |
771 g_markup_parse_context_free(js->context); | |
7072 | 772 if(js->callbacks) |
773 g_hash_table_destroy(js->callbacks); | |
774 if(js->buddies) | |
775 g_hash_table_destroy(js->buddies); | |
776 if(js->chats) | |
777 g_hash_table_destroy(js->chats); | |
8043 | 778 while(js->chat_servers) { |
779 g_free(js->chat_servers->data); | |
780 js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers); | |
781 } | |
7014 | 782 if(js->stream_id) |
783 g_free(js->stream_id); | |
7587 | 784 if(js->user) |
785 jabber_id_free(js->user); | |
7014 | 786 g_free(js); |
5093 | 787 } |
788 | |
7014 | 789 void jabber_stream_set_state(JabberStream *js, JabberStreamState state) |
3105 | 790 { |
7014 | 791 js->state = state; |
792 switch(state) { | |
793 case JABBER_STREAM_OFFLINE: | |
794 break; | |
795 case JABBER_STREAM_CONNECTING: | |
796 gaim_connection_update_progress(js->gc, _("Connecting"), 1, | |
797 JABBER_CONNECT_STEPS); | |
798 break; | |
799 case JABBER_STREAM_INITIALIZING: | |
800 gaim_connection_update_progress(js->gc, _("Initializing Stream"), | |
801 js->gsc ? 5 : 2, JABBER_CONNECT_STEPS); | |
802 jabber_stream_init(js); | |
803 jabber_parser_setup(js); | |
804 break; | |
805 case JABBER_STREAM_AUTHENTICATING: | |
806 gaim_connection_update_progress(js->gc, _("Authenticating"), | |
807 js->gsc ? 6 : 3, JABBER_CONNECT_STEPS); | |
8016 | 808 if(js->protocol_version == JABBER_PROTO_0_9) { |
809 if(js->registration) | |
810 jabber_register_start(js); | |
811 else | |
812 jabber_auth_start_old(js); | |
813 } | |
7014 | 814 break; |
815 case JABBER_STREAM_REINITIALIZING: | |
816 gaim_connection_update_progress(js->gc, _("Re-initializing Stream"), | |
817 6, JABBER_CONNECT_STEPS); | |
818 jabber_stream_init(js); | |
819 break; | |
820 case JABBER_STREAM_CONNECTED: | |
821 gaim_connection_set_state(js->gc, GAIM_CONNECTED); | |
822 jabber_roster_request(js); | |
823 jabber_presence_send(js->gc, js->gc->away_state, js->gc->away); | |
8043 | 824 jabber_iq_disco_server(js); |
7014 | 825 serv_finish_login(js->gc); |
826 break; | |
3105 | 827 } |
828 } | |
829 | |
7014 | 830 char *jabber_get_next_id(JabberStream *js) |
2086 | 831 { |
7322 | 832 return g_strdup_printf("gaim%x", js->next_id++); |
2086 | 833 } |
834 | |
7923 | 835 |
836 static void jabber_idle_set(GaimConnection *gc, int idle) | |
3340 | 837 { |
7014 | 838 JabberStream *js = gc->proto_data; |
3340 | 839 |
7014 | 840 js->idle = idle ? time(NULL) - idle : idle; |
3314 | 841 } |
842 | |
6695 | 843 static const char *jabber_list_icon(GaimAccount *a, GaimBuddy *b) |
2086 | 844 { |
4687 | 845 return "jabber"; |
846 } | |
4916 | 847 |
7014 | 848 static void jabber_list_emblems(GaimBuddy *b, char **se, char **sw, |
849 char **nw, char **ne) | |
4916 | 850 { |
7014 | 851 JabberStream *js; |
852 JabberBuddy *jb; | |
853 | |
854 if(!b->account->gc) | |
855 return; | |
856 js = b->account->gc->proto_data; | |
857 jb = jabber_buddy_find(js, b->name, FALSE); | |
5135 | 858 |
859 if(!GAIM_BUDDY_IS_ONLINE(b)) { | |
7014 | 860 if(jb && jb->error_msg) |
4927 | 861 *nw = "error"; |
5135 | 862 |
7014 | 863 if(jb && (jb->subscription & JABBER_SUB_PENDING || |
864 !(jb->subscription & JABBER_SUB_TO))) | |
5135 | 865 *se = "notauthorized"; |
866 else | |
867 *se = "offline"; | |
4916 | 868 } else { |
869 switch (b->uc) { | |
7014 | 870 case JABBER_STATE_AWAY: |
871 *se = "away"; | |
872 break; | |
873 case JABBER_STATE_CHAT: | |
874 *se = "chat"; | |
875 break; | |
876 case JABBER_STATE_XA: | |
877 *se = "extendedaway"; | |
878 break; | |
879 case JABBER_STATE_DND: | |
8193 | 880 *se = "dnd"; |
7014 | 881 break; |
882 case JABBER_STATE_ERROR: | |
883 *se = "error"; | |
884 break; | |
4916 | 885 } |
2086 | 886 } |
4916 | 887 } |
2086 | 888 |
7014 | 889 static char *jabber_status_text(GaimBuddy *b) |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
890 { |
7014 | 891 JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name, |
892 FALSE); | |
893 char *ret = NULL; | |
5234 | 894 |
7014 | 895 if(jb && !GAIM_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) { |
896 ret = g_strdup(_("Not Authorized")); | |
897 } else if(jb && !GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) { | |
898 ret = g_strdup(jb->error_msg); | |
2956 | 899 } else { |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
900 char *stripped; |
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
901 |
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
902 stripped = gaim_markup_strip_html(jabber_buddy_get_status_msg(jb)); |
2956 | 903 |
7014 | 904 if(!stripped && b->uc & UC_UNAVAILABLE) |
905 stripped = g_strdup(jabber_get_state_string(b->uc)); | |
2086 | 906 |
7014 | 907 if(stripped) { |
908 ret = g_markup_escape_text(stripped, -1); | |
909 g_free(stripped); | |
910 } | |
2086 | 911 } |
912 | |
7014 | 913 return ret; |
2956 | 914 } |
915 | |
6695 | 916 static char *jabber_tooltip_text(GaimBuddy *b) |
4744 | 917 { |
7014 | 918 JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name, |
919 FALSE); | |
8194 | 920 GString *ret = g_string_new(""); |
921 char *r = NULL; | |
7014 | 922 |
8194 | 923 if(jb) { |
924 JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, NULL); | |
925 const char *sub; | |
926 if(jb->subscription & JABBER_SUB_FROM) { | |
927 if(jb->subscription & JABBER_SUB_TO) | |
928 sub = _("Both"); | |
929 else if(jb->subscription & JABBER_SUB_PENDING) | |
930 sub = _("From (To pending)"); | |
931 else | |
932 sub = _("From"); | |
933 } else { | |
934 if(jb->subscription & JABBER_SUB_TO) | |
935 sub = _("To"); | |
936 else if(jb->subscription & JABBER_SUB_PENDING) | |
937 sub = _("None (To pending)"); | |
938 else | |
939 sub = _("None"); | |
940 } | |
941 g_string_append_printf(ret, "<b>%s:</b> %s\n", _("Subscription"), sub); | |
942 | |
943 if(jbr) { | |
944 char *text = NULL; | |
945 if(jbr->status) { | |
946 char *stripped; | |
947 stripped = gaim_markup_strip_html(jbr->status); | |
948 text = g_markup_escape_text(stripped, -1); | |
949 g_free(stripped); | |
950 } | |
951 | |
952 g_string_append_printf(ret, "<b>%s:</b> %s%s%s\n", | |
953 _("Status"), | |
954 jabber_get_state_string(jbr->state), | |
955 text ? ": " : "", | |
956 text ? text : ""); | |
957 if(text) | |
958 g_free(text); | |
959 } else if(!GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) { | |
960 g_string_append_printf(ret, "<b>%s:</b> %s\n", | |
961 _("Error"), jb->error_msg); | |
962 } | |
4745 | 963 } |
4744 | 964 |
8194 | 965 if(ret->len > 0) { |
966 g_string_truncate(ret, ret->len-1); | |
967 r = ret->str; | |
968 g_string_free(ret, FALSE); | |
969 } else { | |
970 g_string_free(ret, TRUE); | |
971 } | |
972 | |
973 return r; | |
4732 | 974 } |
975 | |
7014 | 976 static GList *jabber_away_states(GaimConnection *gc) |
977 { | |
8166 | 978 JabberStream *js = gc->proto_data; |
2086 | 979 GList *m = NULL; |
980 | |
4982 | 981 m = g_list_append(m, _("Online")); |
982 m = g_list_append(m, _("Chatty")); | |
983 m = g_list_append(m, _("Away")); | |
984 m = g_list_append(m, _("Extended Away")); | |
985 m = g_list_append(m, _("Do Not Disturb")); | |
8166 | 986 if(js->protocol_version == JABBER_PROTO_0_9) |
987 m = g_list_append(m, _("Invisible")); | |
4110 | 988 m = g_list_append(m, GAIM_AWAY_CUSTOM); |
2086 | 989 |
990 return m; | |
991 } | |
992 | |
7395 | 993 static void |
994 jabber_password_change_result_cb(JabberStream *js, xmlnode *packet, | |
995 gpointer data) | |
7124 | 996 { |
997 const char *type; | |
998 | |
999 type = xmlnode_get_attrib(packet, "type"); | |
1000 | |
1001 if(!strcmp(type, "result")) { | |
1002 gaim_notify_info(js->gc, _("Password Changed"), _("Password Changed"), | |
1003 _("Your password has been changed.")); | |
1004 } else { | |
1005 xmlnode *error; | |
1006 char *buf, *error_txt = NULL; | |
1007 | |
1008 | |
1009 if((error = xmlnode_get_child(packet, "error"))) | |
1010 error_txt = xmlnode_get_data(error); | |
1011 | |
1012 if(error_txt) { | |
1013 buf = g_strdup_printf(_("Error changing password: %s"), | |
1014 error_txt); | |
1015 g_free(error_txt); | |
1016 } else { | |
1017 buf = g_strdup(_("Unknown error occurred changing password")); | |
1018 } | |
1019 | |
1020 gaim_notify_error(js->gc, _("Error"), _("Error"), buf); | |
1021 g_free(buf); | |
1022 } | |
1023 } | |
1024 | |
1025 static void jabber_password_change_cb(JabberStream *js, | |
1026 GaimRequestFields *fields) | |
1027 { | |
1028 const char *p1, *p2; | |
1029 JabberIq *iq; | |
1030 xmlnode *query, *y; | |
1031 | |
1032 p1 = gaim_request_fields_get_string(fields, "password1"); | |
1033 p2 = gaim_request_fields_get_string(fields, "password2"); | |
1034 | |
1035 if(strcmp(p1, p2)) { | |
1036 gaim_notify_error(js->gc, NULL, _("New passwords do not match."), NULL); | |
1037 return; | |
1038 } | |
1039 | |
1040 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
1041 | |
1042 xmlnode_set_attrib(iq->node, "to", js->user->domain); | |
1043 | |
1044 query = xmlnode_get_child(iq->node, "query"); | |
1045 | |
1046 y = xmlnode_new_child(query, "username"); | |
1047 xmlnode_insert_data(y, js->user->node, -1); | |
1048 y = xmlnode_new_child(query, "password"); | |
1049 xmlnode_insert_data(y, p1, -1); | |
1050 | |
7395 | 1051 jabber_iq_set_callback(iq, jabber_password_change_result_cb, NULL); |
7124 | 1052 |
1053 jabber_iq_send(iq); | |
1054 | |
1055 gaim_account_set_password(js->gc->account, p1); | |
1056 } | |
1057 | |
1058 static void jabber_password_change(GaimConnection *gc) | |
1059 { | |
1060 JabberStream *js = gc->proto_data; | |
1061 GaimRequestFields *fields; | |
1062 GaimRequestFieldGroup *group; | |
1063 GaimRequestField *field; | |
1064 | |
1065 fields = gaim_request_fields_new(); | |
1066 group = gaim_request_field_group_new(NULL); | |
1067 gaim_request_fields_add_group(fields, group); | |
1068 | |
1069 field = gaim_request_field_string_new("password1", _("Password"), | |
1070 "", FALSE); | |
1071 gaim_request_field_string_set_masked(field, TRUE); | |
1072 gaim_request_field_group_add_field(group, field); | |
1073 | |
1074 field = gaim_request_field_string_new("password2", _("Password (again)"), | |
1075 "", FALSE); | |
1076 gaim_request_field_string_set_masked(field, TRUE); | |
1077 gaim_request_field_group_add_field(group, field); | |
1078 | |
1079 gaim_request_fields(js->gc, _("Change Jabber Password"), | |
1080 _("Change Jabber Password"), _("Please enter your new password"), | |
1081 fields, _("OK"), G_CALLBACK(jabber_password_change_cb), | |
1082 _("Cancel"), NULL, js); | |
1083 } | |
1084 | |
5572 | 1085 static GList *jabber_actions(GaimConnection *gc) |
2956 | 1086 { |
7124 | 1087 JabberStream *js = gc->proto_data; |
2956 | 1088 GList *m = NULL; |
4333 | 1089 struct proto_actions_menu *pam; |
1090 | |
1091 pam = g_new0(struct proto_actions_menu, 1); | |
1092 pam->label = _("Set User Info"); | |
1093 pam->callback = jabber_setup_set_info; | |
1094 pam->gc = gc; | |
1095 m = g_list_append(m, pam); | |
1096 | |
7124 | 1097 if(js->protocol_version == JABBER_PROTO_0_9) { |
1098 pam = g_new0(struct proto_actions_menu, 1); | |
1099 pam->label = _("Change Password"); | |
1100 pam->callback = jabber_password_change; | |
1101 pam->gc = gc; | |
1102 m = g_list_append(m, pam); | |
1103 } | |
2956 | 1104 |
1105 return m; | |
1106 } | |
1107 | |
7999 | 1108 static GaimChat *jabber_find_blist_chat(GaimAccount *account, const char *name) |
1109 { | |
1110 GaimBlistNode *gnode, *cnode; | |
1111 JabberID *jid; | |
1112 | |
1113 if(!(jid = jabber_id_new(name))) | |
1114 return NULL; | |
1115 | |
1116 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { | |
1117 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
1118 GaimChat *chat = (GaimChat*)cnode; | |
1119 const char *room, *server; | |
1120 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
1121 continue; | |
1122 | |
1123 if(chat->account != account) | |
8011 | 1124 continue; |
7999 | 1125 |
1126 if(!(room = g_hash_table_lookup(chat->components, "room"))) | |
1127 continue; | |
1128 if(!(server = g_hash_table_lookup(chat->components, "server"))) | |
1129 continue; | |
1130 | |
8158 | 1131 if(jid->node && jid->domain && |
1132 !g_utf8_collate(room, jid->node) && !g_utf8_collate(server, jid->domain)) { | |
7999 | 1133 jabber_id_free(jid); |
1134 return chat; | |
1135 } | |
1136 } | |
1137 } | |
1138 jabber_id_free(jid); | |
1139 return NULL; | |
1140 } | |
1141 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1142 static GaimPluginProtocolInfo prpl_info = |
2086 | 1143 { |
7014 | 1144 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1145 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1146 NULL, |
8170 | 1147 NULL, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1148 jabber_list_icon, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1149 jabber_list_emblems, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1150 jabber_status_text, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1151 jabber_tooltip_text, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1152 jabber_away_states, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1153 jabber_actions, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1154 jabber_buddy_menu, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1155 jabber_chat_info, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1156 jabber_login, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1157 jabber_close, |
7014 | 1158 jabber_message_send_im, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1159 jabber_set_info, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1160 jabber_send_typing, |
7014 | 1161 jabber_buddy_get_info, |
1162 jabber_presence_send, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1163 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1164 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1165 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1166 NULL, |
7014 | 1167 jabber_idle_set, |
7514 | 1168 NULL, |
7014 | 1169 jabber_roster_add_buddy, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1170 NULL, |
7014 | 1171 jabber_roster_remove_buddy, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1172 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1173 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1174 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1175 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1176 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1177 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1178 NULL, |
7014 | 1179 jabber_chat_join, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1180 jabber_chat_invite, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1181 jabber_chat_leave, |
7400 | 1182 NULL, |
7014 | 1183 jabber_message_send_chat, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1184 jabber_keepalive, |
7072 | 1185 jabber_register_account, |
7014 | 1186 jabber_buddy_get_info_chat, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1187 NULL, |
7014 | 1188 jabber_roster_alias_change, |
1189 jabber_roster_group_change, | |
1190 jabber_roster_group_rename, | |
1191 NULL, | |
1192 NULL, /* convo_closed */ /* XXX: thread_ids */ | |
7398 | 1193 jabber_normalize, |
1194 NULL, /* set_buddy_icon */ | |
1195 NULL, /* remove_group */ | |
7971 | 1196 jabber_chat_buddy_real_name, |
7999 | 1197 jabber_chat_set_topic, |
8113 | 1198 jabber_find_blist_chat, |
1199 jabber_roomlist_get_list, | |
1200 jabber_roomlist_cancel, | |
1201 NULL | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1202 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1203 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1204 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1205 { |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1206 2, /**< api_version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1207 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1208 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1209 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1210 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1211 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1212 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1213 "prpl-jabber", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1214 "Jabber", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1215 VERSION, /**< version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1216 /** summary */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1217 N_("Jabber Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1218 /** description */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1219 N_("Jabber Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1220 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
1221 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1222 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1223 NULL, /**< load */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1224 NULL, /**< unload */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1225 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1226 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1227 NULL, /**< ui_info */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1228 &prpl_info /**< extra_info */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1229 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1230 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1231 static void |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5894
diff
changeset
|
1232 init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1233 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1234 GaimAccountUserSplit *split; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1235 GaimAccountOption *option; |
8170 | 1236 struct proto_pref *ppref; |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1237 |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1238 split = gaim_account_user_split_new(_("Server"), "jabber.org", '@'); |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1239 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1240 |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1241 split = gaim_account_user_split_new(_("Resource"), "Gaim", '/'); |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1242 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1243 |
7630 | 1244 option = gaim_account_option_bool_new(_("Use TLS if available"), "use_tls", |
1245 TRUE); | |
1246 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
1247 option); | |
1248 | |
1249 option = gaim_account_option_bool_new(_("Force old SSL"), "old_ssl", FALSE); | |
7124 | 1250 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
1251 option); | |
6764 | 1252 |
8086 | 1253 option = gaim_account_option_bool_new( |
1254 _("Allow plaintext auth over unencrypted streams"), | |
1255 "auth_plain_in_clear", FALSE); | |
1256 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
1257 option); | |
1258 | |
7014 | 1259 option = gaim_account_option_int_new(_("Port"), "port", 5222); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1260 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
7014 | 1261 option); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1262 |
5685
43ea75092684
[gaim-migrate @ 6106]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
1263 option = gaim_account_option_string_new(_("Connect server"), |
7014 | 1264 "connect_server", NULL); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1265 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
7014 | 1266 option); |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1267 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1268 my_protocol = plugin; |
7014 | 1269 |
1270 gaim_prefs_add_none("/plugins/prpl/jabber"); | |
1271 gaim_prefs_add_bool("/plugins/prpl/jabber/hide_os", FALSE); | |
8170 | 1272 |
1273 ppref = g_new0(struct proto_pref, 1); | |
1274 ppref->key = NULL; | |
1275 ppref->label = _("Privacy"); | |
1276 prpl_info.protocol_prefs = g_list_append(prpl_info.protocol_prefs, ppref); | |
1277 | |
1278 ppref = g_new0(struct proto_pref, 1); | |
1279 ppref->key = "/plugins/prpl/jabber/hide_os"; | |
1280 ppref->label = _("Hide Operating System"); /* XXX: come up with a better name for this */ | |
1281 prpl_info.protocol_prefs = g_list_append(prpl_info.protocol_prefs, ppref); | |
2086 | 1282 } |
1283 | |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5894
diff
changeset
|
1284 GAIM_INIT_PLUGIN(jabber, init_plugin, info); |