Mercurial > pidgin.yaz
annotate src/protocols/jabber/jabber.c @ 11939:85c25a32bb48
[gaim-migrate @ 14230]
As http://www.xmpp.org/xmppimpl.html states:
If the default value for the resource is the name of the Jabber client (the
program), people tend to think it is a cryptic field that should not be
changed and leave it like that and it totally defeats the sense of resource.
Most people won't ever understand the big picture of how resources work, but
if the default value is 'Home' or 'Office' people will feel more confident to
change it, specially if it doesn't match the reality.
committer: Tailor Script <tailor@pidgin.im>
author | Etan Reisner <pidgin@unreliablesource.net> |
---|---|
date | Wed, 02 Nov 2005 02:21:43 +0000 |
parents | fa742ad8068c |
children | cbebda5f019c |
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" | |
9030 | 25 #include "blist.h" |
9130 | 26 #include "cmds.h" |
10740 | 27 #include "connection.h" |
7014 | 28 #include "debug.h" |
11387 | 29 #include "dnssrv.h" |
7014 | 30 #include "message.h" |
7072 | 31 #include "notify.h" |
8713 | 32 #include "pluginpref.h" |
7014 | 33 #include "prpl.h" |
7072 | 34 #include "request.h" |
7014 | 35 #include "server.h" |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
36 #include "util.h" |
9943 | 37 #include "version.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
38 |
7014 | 39 #include "auth.h" |
40 #include "buddy.h" | |
41 #include "chat.h" | |
8312 | 42 #include "disco.h" |
7014 | 43 #include "iq.h" |
44 #include "jutil.h" | |
45 #include "message.h" | |
46 #include "parser.h" | |
47 #include "presence.h" | |
48 #include "jabber.h" | |
49 #include "roster.h" | |
9466 | 50 #include "si.h" |
7923 | 51 #include "xdata.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5685
diff
changeset
|
52 |
7014 | 53 #define JABBER_CONNECT_STEPS (js->gsc ? 8 : 5) |
2086 | 54 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
55 static GaimPlugin *my_protocol = NULL; |
4249 | 56 |
7014 | 57 static void jabber_stream_init(JabberStream *js) |
58 { | |
59 char *open_stream; | |
3340 | 60 |
7014 | 61 open_stream = g_strdup_printf("<stream:stream to='%s' " |
62 "xmlns='jabber:client' " | |
7395 | 63 "xmlns:stream='http://etherx.jabber.org/streams' " |
64 "version='1.0'>", | |
7291 | 65 js->user->domain); |
3311 | 66 |
7642 | 67 jabber_send_raw(js, open_stream, -1); |
2086 | 68 |
7014 | 69 g_free(open_stream); |
2086 | 70 } |
71 | |
7395 | 72 static void |
73 jabber_session_initialized_cb(JabberStream *js, xmlnode *packet, gpointer data) | |
3311 | 74 { |
7014 | 75 const char *type = xmlnode_get_attrib(packet, "type"); |
76 if(type && !strcmp(type, "result")) { | |
77 jabber_stream_set_state(js, JABBER_STREAM_CONNECTED); | |
78 } else { | |
79 gaim_connection_error(js->gc, _("Error initializing session")); | |
3311 | 80 } |
81 } | |
82 | |
7014 | 83 static void jabber_session_init(JabberStream *js) |
3311 | 84 { |
7014 | 85 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); |
86 xmlnode *session; | |
3311 | 87 |
7395 | 88 jabber_iq_set_callback(iq, jabber_session_initialized_cb, NULL); |
3311 | 89 |
7014 | 90 session = xmlnode_new_child(iq->node, "session"); |
91 xmlnode_set_attrib(session, "xmlns", "urn:ietf:params:xml:ns:xmpp-session"); | |
3311 | 92 |
7014 | 93 jabber_iq_send(iq); |
3311 | 94 } |
95 | |
7395 | 96 static void jabber_bind_result_cb(JabberStream *js, xmlnode *packet, |
97 gpointer data) | |
98 { | |
8401 | 99 const char *type = xmlnode_get_attrib(packet, "type"); |
100 xmlnode *bind; | |
101 | |
102 if(type && !strcmp(type, "result") && | |
103 (bind = xmlnode_get_child_with_namespace(packet, "bind", "urn:ietf:params:xml:ns:xmpp-bind"))) { | |
104 xmlnode *jid; | |
105 char *full_jid; | |
106 if((jid = xmlnode_get_child(bind, "jid")) && (full_jid = xmlnode_get_data(jid))) { | |
10289 | 107 JabberBuddy *my_jb = NULL; |
8401 | 108 jabber_id_free(js->user); |
109 if(!(js->user = jabber_id_new(full_jid))) { | |
110 gaim_connection_error(js->gc, _("Invalid response from server.")); | |
111 } | |
10289 | 112 if((my_jb = jabber_buddy_find(js, full_jid, TRUE))) |
113 my_jb->subscription |= JABBER_SUB_BOTH; | |
10504 | 114 g_free(full_jid); |
8401 | 115 } |
116 } else { | |
117 char *msg = jabber_parse_error(js, packet); | |
118 gaim_connection_error(js->gc, msg); | |
119 g_free(msg); | |
120 } | |
7395 | 121 |
122 jabber_session_init(js); | |
123 } | |
124 | |
125 static void jabber_stream_features_parse(JabberStream *js, xmlnode *packet) | |
126 { | |
8296 | 127 if(xmlnode_get_child(packet, "starttls")) { |
128 if(jabber_process_starttls(js, packet)) | |
129 return; | |
130 } | |
131 | |
10988 | 132 if(js->registration) { |
133 jabber_register_start(js); | |
134 } else if(xmlnode_get_child(packet, "mechanisms")) { | |
7395 | 135 jabber_auth_start(js, packet); |
136 } else if(xmlnode_get_child(packet, "bind")) { | |
137 xmlnode *bind, *resource; | |
138 JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET); | |
139 bind = xmlnode_new_child(iq->node, "bind"); | |
140 xmlnode_set_attrib(bind, "xmlns", "urn:ietf:params:xml:ns:xmpp-bind"); | |
141 resource = xmlnode_new_child(bind, "resource"); | |
142 xmlnode_insert_data(resource, js->user->resource, -1); | |
143 | |
144 jabber_iq_set_callback(iq, jabber_bind_result_cb, NULL); | |
145 | |
146 jabber_iq_send(iq); | |
8296 | 147 } else /* if(xmlnode_get_child_with_namespace(packet, "auth")) */ { |
148 /* If we get an empty stream:features packet, or we explicitly get | |
149 * an auth feature with namespace http://jabber.org/features/iq-auth | |
150 * we should revert back to iq:auth authentication, even though we're | |
151 * connecting to an XMPP server. */ | |
152 js->auth_type = JABBER_AUTH_IQ_AUTH; | |
153 jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING); | |
7395 | 154 } |
155 } | |
156 | |
7014 | 157 static void jabber_stream_handle_error(JabberStream *js, xmlnode *packet) |
3311 | 158 { |
8401 | 159 char *msg = jabber_parse_error(js, packet); |
3311 | 160 |
8401 | 161 gaim_connection_error(js->gc, msg); |
162 g_free(msg); | |
2086 | 163 } |
164 | |
7014 | 165 static void tls_init(JabberStream *js); |
2086 | 166 |
7014 | 167 void jabber_process_packet(JabberStream *js, xmlnode *packet) |
2086 | 168 { |
7014 | 169 if(!strcmp(packet->name, "iq")) { |
7395 | 170 jabber_iq_parse(js, packet); |
7014 | 171 } else if(!strcmp(packet->name, "presence")) { |
172 jabber_presence_parse(js, packet); | |
173 } else if(!strcmp(packet->name, "message")) { | |
174 jabber_message_parse(js, packet); | |
175 } else if(!strcmp(packet->name, "stream:features")) { | |
7395 | 176 jabber_stream_features_parse(js, packet); |
7014 | 177 } else if(!strcmp(packet->name, "stream:error")) { |
178 jabber_stream_handle_error(js, packet); | |
179 } else if(!strcmp(packet->name, "challenge")) { | |
180 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
181 jabber_auth_handle_challenge(js, packet); | |
182 } else if(!strcmp(packet->name, "success")) { | |
183 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
184 jabber_auth_handle_success(js, packet); | |
185 } else if(!strcmp(packet->name, "failure")) { | |
186 if(js->state == JABBER_STREAM_AUTHENTICATING) | |
187 jabber_auth_handle_failure(js, packet); | |
188 } else if(!strcmp(packet->name, "proceed")) { | |
189 if(js->state == JABBER_STREAM_AUTHENTICATING && !js->gsc) | |
190 tls_init(js); | |
191 } else { | |
192 gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown packet: %s\n", | |
193 packet->name); | |
2086 | 194 } |
195 } | |
196 | |
7642 | 197 void jabber_send_raw(JabberStream *js, const char *data, int len) |
2086 | 198 { |
7014 | 199 int ret; |
2086 | 200 |
7014 | 201 /* because printing a tab to debug every minute gets old */ |
202 if(strcmp(data, "\t")) | |
8401 | 203 gaim_debug(GAIM_DEBUG_MISC, "jabber", "Sending%s: %s\n", |
7014 | 204 js->gsc ? " (ssl)" : "", data); |
2086 | 205 |
7014 | 206 if(js->gsc) { |
7642 | 207 ret = gaim_ssl_write(js->gsc, data, len == -1 ? strlen(data) : len); |
7014 | 208 } else { |
8013 | 209 if(js->fd < 0) |
210 return; | |
7642 | 211 ret = write(js->fd, data, len == -1 ? strlen(data) : len); |
2814
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
212 } |
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
213 |
7014 | 214 if(ret < 0) |
215 gaim_connection_error(js->gc, _("Write error")); | |
216 | |
2814
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
217 } |
f4f9e5a01890
[gaim-migrate @ 2827]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2800
diff
changeset
|
218 |
7014 | 219 void jabber_send(JabberStream *js, xmlnode *packet) |
2086 | 220 { |
7014 | 221 char *txt; |
7642 | 222 int len; |
2086 | 223 |
7642 | 224 txt = xmlnode_to_str(packet, &len); |
225 jabber_send_raw(js, txt, len); | |
7014 | 226 g_free(txt); |
2086 | 227 } |
228 | |
7014 | 229 static void jabber_keepalive(GaimConnection *gc) |
2086 | 230 { |
7642 | 231 jabber_send_raw(gc->proto_data, "\t", -1); |
2086 | 232 } |
233 | |
7014 | 234 static void |
235 jabber_recv_cb_ssl(gpointer data, GaimSslConnection *gsc, | |
6764 | 236 GaimInputCondition cond) |
237 { | |
7014 | 238 GaimConnection *gc = data; |
239 JabberStream *js = gc->proto_data; | |
6764 | 240 int len; |
7014 | 241 static char buf[4096]; |
6768 | 242 |
7014 | 243 if(!g_list_find(gaim_connections_get_all(), gc)) { |
6768 | 244 gaim_ssl_close(gsc); |
245 return; | |
246 } | |
247 | |
7014 | 248 if((len = gaim_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) { |
6764 | 249 buf[len] = '\0'; |
7014 | 250 gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (ssl)(%d): %s\n", len, buf); |
251 jabber_parser_process(js, buf, len); | |
7177 | 252 } else { |
253 gaim_connection_error(gc, _("Read Error")); | |
2086 | 254 } |
255 } | |
256 | |
7014 | 257 static void |
258 jabber_recv_cb(gpointer data, gint source, GaimInputCondition condition) | |
2086 | 259 { |
5572 | 260 GaimConnection *gc = data; |
7014 | 261 JabberStream *js = gc->proto_data; |
262 int len; | |
263 static char buf[4096]; | |
2086 | 264 |
7014 | 265 if(!g_list_find(gaim_connections_get_all(), gc)) |
266 return; | |
2956 | 267 |
7014 | 268 if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) { |
269 buf[len] = '\0'; | |
270 gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (%d): %s\n", len, buf); | |
271 jabber_parser_process(js, buf, len); | |
7177 | 272 } else { |
273 gaim_connection_error(gc, _("Read Error")); | |
7014 | 274 } |
2086 | 275 } |
276 | |
7014 | 277 static void |
278 jabber_login_callback_ssl(gpointer data, GaimSslConnection *gsc, | |
6764 | 279 GaimInputCondition cond) |
280 { | |
281 GaimConnection *gc = data; | |
7014 | 282 JabberStream *js = gc->proto_data; |
6764 | 283 |
7014 | 284 if(!g_list_find(gaim_connections_get_all(), gc)) { |
6764 | 285 gaim_ssl_close(gsc); |
286 return; | |
287 } | |
288 | |
7014 | 289 js->gsc = gsc; |
6764 | 290 |
7014 | 291 if(js->state == JABBER_STREAM_CONNECTING) |
7642 | 292 jabber_send_raw(js, "<?xml version='1.0' ?>", -1); |
6764 | 293 |
7014 | 294 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
295 gaim_ssl_input_add(gsc, jabber_recv_cb_ssl, gc); | |
6764 | 296 } |
297 | |
7014 | 298 |
299 static void | |
300 jabber_login_callback(gpointer data, gint source, GaimInputCondition cond) | |
6764 | 301 { |
5572 | 302 GaimConnection *gc = data; |
7014 | 303 JabberStream *js = gc->proto_data; |
2086 | 304 |
8783 | 305 if (source < 0) { |
306 gaim_connection_error(gc, _("Couldn't connect to host")); | |
307 return; | |
308 } | |
309 | |
7014 | 310 if(!g_list_find(gaim_connections_get_all(), gc)) { |
2086 | 311 close(source); |
312 return; | |
313 } | |
314 | |
7014 | 315 js->fd = source; |
2956 | 316 |
7014 | 317 if(js->state == JABBER_STREAM_CONNECTING) |
7642 | 318 jabber_send_raw(js, "<?xml version='1.0' ?>", -1); |
2300
d2686f757d6e
[gaim-migrate @ 2310]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2289
diff
changeset
|
319 |
7014 | 320 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
321 gc->inpa = gaim_input_add(js->fd, GAIM_INPUT_READ, jabber_recv_cb, gc); | |
322 } | |
2086 | 323 |
7014 | 324 static void |
7426 | 325 jabber_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, |
326 gpointer data) | |
327 { | |
328 GaimConnection *gc = data; | |
8360 | 329 JabberStream *js = gc->proto_data; |
7426 | 330 |
331 switch(error) { | |
8362 | 332 case GAIM_SSL_CONNECT_FAILED: |
333 gaim_connection_error(gc, _("Connection Failed")); | |
334 break; | |
7426 | 335 case GAIM_SSL_HANDSHAKE_FAILED: |
336 gaim_connection_error(gc, _("SSL Handshake Failed")); | |
337 break; | |
338 } | |
8360 | 339 |
340 js->gsc = NULL; | |
7426 | 341 } |
342 | |
7427 | 343 static void tls_init(JabberStream *js) |
344 { | |
345 gaim_input_remove(js->gc->inpa); | |
346 js->gc->inpa = 0; | |
347 js->gsc = gaim_ssl_connect_fd(js->gc->account, js->fd, | |
348 jabber_login_callback_ssl, jabber_ssl_connect_failure, js->gc); | |
349 } | |
350 | |
11387 | 351 static void jabber_login_connect(JabberStream *js, const char *server, int port) |
352 { | |
353 int rc; | |
354 | |
355 rc = gaim_proxy_connect(js->gc->account, server, | |
356 port, jabber_login_callback, js->gc); | |
357 | |
358 if (rc != 0) | |
359 gaim_connection_error(js->gc, _("Unable to create socket")); | |
360 } | |
361 | |
362 static void srv_resolved_cb(struct srv_response *resp, int results, gpointer data) | |
363 { | |
364 JabberStream *js = (JabberStream*)data; | |
365 int config_port = gaim_account_get_int(js->gc->account, "port", 0); | |
366 | |
367 if(results) { | |
368 jabber_login_connect(js, resp->hostname, config_port ? config_port : resp->port); | |
369 g_free(resp); | |
370 } else { | |
371 jabber_login_connect(js, js->user->domain, config_port); | |
372 } | |
373 } | |
374 | |
375 | |
7427 | 376 |
7426 | 377 static void |
11837 | 378 jabber_login(GaimAccount *account) |
2086 | 379 { |
7014 | 380 GaimConnection *gc = gaim_account_get_connection(account); |
381 const char *connect_server = gaim_account_get_string(account, | |
382 "connect_server", ""); | |
383 JabberStream *js; | |
10289 | 384 JabberBuddy *my_jb = NULL; |
2086 | 385 |
7014 | 386 gc->flags |= GAIM_CONNECTION_HTML; |
387 js = gc->proto_data = g_new0(JabberStream, 1); | |
388 js->gc = gc; | |
8013 | 389 js->fd = -1; |
8312 | 390 js->iq_callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, |
391 g_free, g_free); | |
392 js->disco_callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, | |
7395 | 393 g_free, g_free); |
7014 | 394 js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal, |
7116 | 395 g_free, (GDestroyNotify)jabber_buddy_free); |
7014 | 396 js->chats = g_hash_table_new_full(g_str_hash, g_str_equal, |
8396 | 397 g_free, (GDestroyNotify)jabber_chat_free); |
8043 | 398 js->chat_servers = g_list_append(NULL, g_strdup("conference.jabber.org")); |
7014 | 399 js->user = jabber_id_new(gaim_account_get_username(account)); |
7322 | 400 js->next_id = g_random_int(); |
5613 | 401 |
7310 | 402 if(!js->user) { |
403 gaim_connection_error(gc, _("Invalid Jabber ID")); | |
404 return; | |
405 } | |
406 | |
7147 | 407 if(!js->user->resource) { |
408 char *me; | |
11939
85c25a32bb48
[gaim-migrate @ 14230]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11837
diff
changeset
|
409 js->user->resource = g_strdup("Home"); |
7147 | 410 if(!js->user->node) { |
411 js->user->node = js->user->domain; | |
412 js->user->domain = g_strdup("jabber.org"); | |
413 } | |
414 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, | |
415 js->user->resource); | |
416 gaim_account_set_username(account, me); | |
417 g_free(me); | |
7145 | 418 } |
419 | |
10289 | 420 if((my_jb = jabber_buddy_find(js, gaim_account_get_username(account), TRUE))) |
421 my_jb->subscription |= JABBER_SUB_BOTH; | |
422 | |
7014 | 423 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); |
2956 | 424 |
11387 | 425 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ |
426 if(gaim_account_get_bool(js->gc->account, "old_ssl", FALSE)) { | |
7630 | 427 if(gaim_ssl_is_supported()) { |
11387 | 428 js->gsc = gaim_ssl_connect(js->gc->account, |
429 connect_server[0] ? connect_server : js->user->domain, | |
430 gaim_account_get_int(account, "port", 5223), jabber_login_callback_ssl, | |
431 jabber_ssl_connect_failure, js->gc); | |
7630 | 432 } else { |
11387 | 433 gaim_connection_error(js->gc, _("SSL support unavailable")); |
7630 | 434 } |
3311 | 435 } |
3770 | 436 |
11387 | 437 /* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll |
438 * invoke the magic of SRV lookups, to figure out host and port */ | |
7014 | 439 if(!js->gsc) { |
11387 | 440 if(connect_server[0]) { |
441 jabber_login_connect(js, connect_server, gaim_account_get_int(account, "port", 5222)); | |
442 } else { | |
443 gaim_srv_resolve("xmpp-client", "tcp", js->user->domain, srv_resolved_cb, js); | |
444 } | |
2956 | 445 } |
2086 | 446 } |
447 | |
11387 | 448 |
7072 | 449 static gboolean |
450 conn_close_cb(gpointer data) | |
451 { | |
452 JabberStream *js = data; | |
10740 | 453 GaimAccount *account = gaim_connection_get_account(js->gc); |
454 | |
455 gaim_account_disconnect(account); | |
456 | |
7072 | 457 return FALSE; |
458 } | |
459 | |
460 static void | |
461 jabber_connection_schedule_close(JabberStream *js) | |
462 { | |
8273
f24172f53650
[gaim-migrate @ 8997]
Christian Hammond <chipx86@chipx86.com>
parents:
8194
diff
changeset
|
463 gaim_timeout_add(0, conn_close_cb, js); |
7072 | 464 } |
465 | |
466 static void | |
7395 | 467 jabber_registration_result_cb(JabberStream *js, xmlnode *packet, gpointer data) |
7072 | 468 { |
469 const char *type = xmlnode_get_attrib(packet, "type"); | |
470 char *buf; | |
471 | |
472 if(!strcmp(type, "result")) { | |
473 buf = g_strdup_printf(_("Registration of %s@%s successful"), | |
474 js->user->node, js->user->domain); | |
475 gaim_notify_info(NULL, _("Registration Successful"), | |
476 _("Registration Successful"), buf); | |
477 g_free(buf); | |
478 } else { | |
8401 | 479 char *msg = jabber_parse_error(js, packet); |
7072 | 480 |
8401 | 481 if(!msg) |
482 msg = g_strdup(_("Unknown Error")); | |
7072 | 483 |
484 gaim_notify_error(NULL, _("Registration Failed"), | |
8401 | 485 _("Registration Failed"), msg); |
486 g_free(msg); | |
7072 | 487 } |
488 jabber_connection_schedule_close(js); | |
489 } | |
490 | |
491 static void | |
492 jabber_register_cb(JabberStream *js, GaimRequestFields *fields) | |
493 { | |
494 GList *groups, *flds; | |
495 xmlnode *query, *y; | |
496 JabberIq *iq; | |
7264 | 497 char *username; |
7072 | 498 |
499 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
500 query = xmlnode_get_child(iq->node, "query"); | |
501 | |
502 for(groups = gaim_request_fields_get_groups(fields); groups; | |
503 groups = groups->next) { | |
504 for(flds = gaim_request_field_group_get_fields(groups->data); | |
505 flds; flds = flds->next) { | |
506 GaimRequestField *field = flds->data; | |
507 const char *id = gaim_request_field_get_id(field); | |
508 const char *value = gaim_request_field_string_get_value(field); | |
509 | |
510 if(!strcmp(id, "username")) { | |
511 y = xmlnode_new_child(query, "username"); | |
512 } else if(!strcmp(id, "password")) { | |
513 y = xmlnode_new_child(query, "password"); | |
514 } else if(!strcmp(id, "name")) { | |
515 y = xmlnode_new_child(query, "name"); | |
516 } else if(!strcmp(id, "email")) { | |
517 y = xmlnode_new_child(query, "email"); | |
518 } else if(!strcmp(id, "nick")) { | |
519 y = xmlnode_new_child(query, "nick"); | |
520 } else if(!strcmp(id, "first")) { | |
521 y = xmlnode_new_child(query, "first"); | |
522 } else if(!strcmp(id, "last")) { | |
523 y = xmlnode_new_child(query, "last"); | |
524 } else if(!strcmp(id, "address")) { | |
525 y = xmlnode_new_child(query, "address"); | |
526 } else if(!strcmp(id, "city")) { | |
527 y = xmlnode_new_child(query, "city"); | |
528 } else if(!strcmp(id, "state")) { | |
529 y = xmlnode_new_child(query, "state"); | |
530 } else if(!strcmp(id, "zip")) { | |
531 y = xmlnode_new_child(query, "zip"); | |
532 } else if(!strcmp(id, "phone")) { | |
533 y = xmlnode_new_child(query, "phone"); | |
534 } else if(!strcmp(id, "url")) { | |
535 y = xmlnode_new_child(query, "url"); | |
536 } else if(!strcmp(id, "date")) { | |
537 y = xmlnode_new_child(query, "date"); | |
538 } else { | |
539 continue; | |
540 } | |
541 xmlnode_insert_data(y, value, -1); | |
7264 | 542 if(!strcmp(id, "username")) { |
543 if(js->user->node) | |
544 g_free(js->user->node); | |
545 js->user->node = g_strdup(value); | |
546 } | |
7072 | 547 } |
548 } | |
549 | |
7264 | 550 username = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, |
551 js->user->resource); | |
552 gaim_account_set_username(js->gc->account, username); | |
553 g_free(username); | |
554 | |
7395 | 555 jabber_iq_set_callback(iq, jabber_registration_result_cb, NULL); |
7072 | 556 |
557 jabber_iq_send(iq); | |
558 | |
559 } | |
560 | |
561 static void | |
562 jabber_register_cancel_cb(JabberStream *js, GaimRequestFields *fields) | |
563 { | |
564 jabber_connection_schedule_close(js); | |
565 } | |
566 | |
7923 | 567 static void jabber_register_x_data_cb(JabberStream *js, xmlnode *result, gpointer data) |
568 { | |
569 xmlnode *query; | |
570 JabberIq *iq; | |
571 | |
572 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
573 query = xmlnode_get_child(iq->node, "query"); | |
574 | |
575 xmlnode_insert_child(query, result); | |
576 | |
577 jabber_iq_set_callback(iq, jabber_registration_result_cb, NULL); | |
578 jabber_iq_send(iq); | |
579 } | |
580 | |
7072 | 581 void jabber_register_parse(JabberStream *js, xmlnode *packet) |
582 { | |
583 if(js->registration) { | |
584 GaimRequestFields *fields; | |
585 GaimRequestFieldGroup *group; | |
586 GaimRequestField *field; | |
7923 | 587 xmlnode *query, *x, *y; |
7072 | 588 char *instructions; |
589 | |
590 /* get rid of the login thingy */ | |
591 gaim_connection_set_state(js->gc, GAIM_CONNECTED); | |
592 | |
593 query = xmlnode_get_child(packet, "query"); | |
594 | |
595 if(xmlnode_get_child(query, "registered")) { | |
596 gaim_notify_error(NULL, _("Already Registered"), | |
597 _("Already Registered"), NULL); | |
598 jabber_connection_schedule_close(js); | |
599 return; | |
600 } | |
601 | |
8398 | 602 if((x = xmlnode_get_child_with_namespace(packet, "x", |
603 "jabber:x:data"))) { | |
604 jabber_x_data_request(js, x, jabber_register_x_data_cb, NULL); | |
605 return; | |
606 } else if((x = xmlnode_get_child_with_namespace(packet, "x", | |
607 "jabber:x:oob"))) { | |
608 xmlnode *url; | |
7923 | 609 |
8398 | 610 if((url = xmlnode_get_child(x, "url"))) { |
611 char *href; | |
612 if((href = xmlnode_get_data(url))) { | |
10240
95ca0db2d01d
[gaim-migrate @ 11377]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
10216
diff
changeset
|
613 gaim_notify_uri(NULL, href); |
8398 | 614 g_free(href); |
615 js->gc->wants_to_die = TRUE; | |
616 jabber_connection_schedule_close(js); | |
617 return; | |
618 } | |
7923 | 619 } |
620 } | |
621 | |
622 /* as a last resort, use the old jabber:iq:register syntax */ | |
623 | |
7072 | 624 fields = gaim_request_fields_new(); |
625 group = gaim_request_field_group_new(NULL); | |
626 gaim_request_fields_add_group(fields, group); | |
627 | |
628 field = gaim_request_field_string_new("username", _("Username"), | |
629 js->user->node, FALSE); | |
630 gaim_request_field_group_add_field(group, field); | |
631 | |
632 field = gaim_request_field_string_new("password", _("Password"), | |
10740 | 633 gaim_connection_get_password(js->gc), FALSE); |
7072 | 634 gaim_request_field_string_set_masked(field, TRUE); |
635 gaim_request_field_group_add_field(group, field); | |
636 | |
637 if(xmlnode_get_child(query, "name")) { | |
638 field = gaim_request_field_string_new("name", _("Name"), | |
639 gaim_account_get_alias(js->gc->account), FALSE); | |
640 gaim_request_field_group_add_field(group, field); | |
641 } | |
642 if(xmlnode_get_child(query, "email")) { | |
643 field = gaim_request_field_string_new("email", _("E-Mail"), | |
644 NULL, FALSE); | |
645 gaim_request_field_group_add_field(group, field); | |
646 } | |
647 if(xmlnode_get_child(query, "nick")) { | |
648 field = gaim_request_field_string_new("nick", _("Nickname"), | |
649 NULL, FALSE); | |
650 gaim_request_field_group_add_field(group, field); | |
651 } | |
652 if(xmlnode_get_child(query, "first")) { | |
653 field = gaim_request_field_string_new("first", _("First Name"), | |
654 NULL, FALSE); | |
655 gaim_request_field_group_add_field(group, field); | |
656 } | |
657 if(xmlnode_get_child(query, "last")) { | |
658 field = gaim_request_field_string_new("last", _("Last Name"), | |
659 NULL, FALSE); | |
660 gaim_request_field_group_add_field(group, field); | |
661 } | |
662 if(xmlnode_get_child(query, "address")) { | |
663 field = gaim_request_field_string_new("address", _("Address"), | |
664 NULL, FALSE); | |
665 gaim_request_field_group_add_field(group, field); | |
666 } | |
667 if(xmlnode_get_child(query, "city")) { | |
668 field = gaim_request_field_string_new("city", _("City"), | |
669 NULL, FALSE); | |
670 gaim_request_field_group_add_field(group, field); | |
671 } | |
672 if(xmlnode_get_child(query, "state")) { | |
673 field = gaim_request_field_string_new("state", _("State"), | |
674 NULL, FALSE); | |
675 gaim_request_field_group_add_field(group, field); | |
676 } | |
677 if(xmlnode_get_child(query, "zip")) { | |
678 field = gaim_request_field_string_new("zip", _("Postal Code"), | |
679 NULL, FALSE); | |
680 gaim_request_field_group_add_field(group, field); | |
681 } | |
682 if(xmlnode_get_child(query, "phone")) { | |
683 field = gaim_request_field_string_new("phone", _("Phone"), | |
684 NULL, FALSE); | |
685 gaim_request_field_group_add_field(group, field); | |
686 } | |
687 if(xmlnode_get_child(query, "url")) { | |
688 field = gaim_request_field_string_new("url", _("URL"), | |
689 NULL, FALSE); | |
690 gaim_request_field_group_add_field(group, field); | |
691 } | |
692 if(xmlnode_get_child(query, "date")) { | |
693 field = gaim_request_field_string_new("date", _("Date"), | |
694 NULL, FALSE); | |
695 gaim_request_field_group_add_field(group, field); | |
696 } | |
697 | |
698 if((y = xmlnode_get_child(query, "instructions"))) | |
699 instructions = xmlnode_get_data(y); | |
700 else | |
701 instructions = g_strdup(_("Please fill out the information below " | |
702 "to register your new account.")); | |
703 | |
704 gaim_request_fields(js->gc, _("Register New Jabber Account"), | |
705 _("Register New Jabber Account"), instructions, fields, | |
706 _("Register"), G_CALLBACK(jabber_register_cb), | |
707 _("Cancel"), G_CALLBACK(jabber_register_cancel_cb), js); | |
708 } | |
709 } | |
710 | |
8016 | 711 void jabber_register_start(JabberStream *js) |
7072 | 712 { |
713 JabberIq *iq; | |
714 | |
715 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:register"); | |
716 jabber_iq_send(iq); | |
717 } | |
718 | |
719 static void jabber_register_account(GaimAccount *account) | |
720 { | |
721 GaimConnection *gc = gaim_account_get_connection(account); | |
722 JabberStream *js; | |
10289 | 723 JabberBuddy *my_jb = NULL; |
7072 | 724 const char *connect_server = gaim_account_get_string(account, |
725 "connect_server", ""); | |
726 const char *server; | |
727 int rc; | |
728 | |
729 js = gc->proto_data = g_new0(JabberStream, 1); | |
730 js->gc = gc; | |
731 js->registration = TRUE; | |
8312 | 732 js->iq_callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, |
733 g_free, g_free); | |
734 js->disco_callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, | |
7395 | 735 g_free, g_free); |
7072 | 736 js->user = jabber_id_new(gaim_account_get_username(account)); |
7322 | 737 js->next_id = g_random_int(); |
7072 | 738 |
7310 | 739 if(!js->user) { |
740 gaim_connection_error(gc, _("Invalid Jabber ID")); | |
741 return; | |
742 } | |
743 | |
7147 | 744 if(!js->user->resource) { |
745 char *me; | |
11939
85c25a32bb48
[gaim-migrate @ 14230]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11837
diff
changeset
|
746 js->user->resource = g_strdup("Home"); |
7147 | 747 if(!js->user->node) { |
748 js->user->node = js->user->domain; | |
749 js->user->domain = g_strdup("jabber.org"); | |
750 } | |
751 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, | |
752 js->user->resource); | |
753 gaim_account_set_username(account, me); | |
754 g_free(me); | |
755 } | |
756 | |
10289 | 757 if((my_jb = jabber_buddy_find(js, gaim_account_get_username(account), TRUE))) |
758 my_jb->subscription |= JABBER_SUB_BOTH; | |
759 | |
7072 | 760 server = connect_server[0] ? connect_server : js->user->domain; |
761 | |
762 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); | |
763 | |
7630 | 764 if(gaim_account_get_bool(account, "old_ssl", FALSE)) { |
765 if(gaim_ssl_is_supported()) { | |
766 js->gsc = gaim_ssl_connect(account, server, | |
767 gaim_account_get_int(account, "port", 5222), | |
768 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); | |
769 } else { | |
770 gaim_connection_error(gc, _("SSL support unavailable")); | |
771 } | |
7072 | 772 } |
773 | |
774 if(!js->gsc) { | |
775 rc = gaim_proxy_connect(account, server, | |
776 gaim_account_get_int(account, "port", 5222), | |
777 jabber_login_callback, gc); | |
778 | |
779 if (rc != 0) | |
780 gaim_connection_error(gc, _("Unable to create socket")); | |
781 } | |
782 } | |
783 | |
5572 | 784 static void jabber_close(GaimConnection *gc) |
2086 | 785 { |
7014 | 786 JabberStream *js = gc->proto_data; |
2956 | 787 |
10216 | 788 jabber_presence_send(gc->account, NULL); |
7642 | 789 jabber_send_raw(js, "</stream:stream>", -1); |
3311 | 790 |
7014 | 791 if(js->gsc) { |
792 gaim_ssl_close(js->gsc); | |
8360 | 793 } else if (js->fd > 0) { |
7072 | 794 if(js->gc->inpa) |
795 gaim_input_remove(js->gc->inpa); | |
7014 | 796 close(js->fd); |
797 } | |
3311 | 798 |
7587 | 799 if(js->context) |
800 g_markup_parse_context_free(js->context); | |
8312 | 801 if(js->iq_callbacks) |
802 g_hash_table_destroy(js->iq_callbacks); | |
803 if(js->disco_callbacks) | |
804 g_hash_table_destroy(js->disco_callbacks); | |
7072 | 805 if(js->buddies) |
806 g_hash_table_destroy(js->buddies); | |
807 if(js->chats) | |
808 g_hash_table_destroy(js->chats); | |
8043 | 809 while(js->chat_servers) { |
810 g_free(js->chat_servers->data); | |
811 js->chat_servers = g_list_delete_link(js->chat_servers, js->chat_servers); | |
812 } | |
11675 | 813 while(js->user_directories) { |
814 g_free(js->user_directories->data); | |
815 js->user_directories = g_list_delete_link(js->user_directories, js->user_directories); | |
816 } | |
7014 | 817 if(js->stream_id) |
818 g_free(js->stream_id); | |
7587 | 819 if(js->user) |
820 jabber_id_free(js->user); | |
10189 | 821 if(js->avatar_hash) |
822 g_free(js->avatar_hash); | |
7014 | 823 g_free(js); |
11389 | 824 |
825 gc->proto_data = NULL; | |
5093 | 826 } |
827 | |
7014 | 828 void jabber_stream_set_state(JabberStream *js, JabberStreamState state) |
3105 | 829 { |
9954 | 830 GaimPresence *gpresence; |
831 GaimStatus *status; | |
832 | |
7014 | 833 js->state = state; |
834 switch(state) { | |
835 case JABBER_STREAM_OFFLINE: | |
836 break; | |
837 case JABBER_STREAM_CONNECTING: | |
838 gaim_connection_update_progress(js->gc, _("Connecting"), 1, | |
839 JABBER_CONNECT_STEPS); | |
840 break; | |
841 case JABBER_STREAM_INITIALIZING: | |
842 gaim_connection_update_progress(js->gc, _("Initializing Stream"), | |
843 js->gsc ? 5 : 2, JABBER_CONNECT_STEPS); | |
844 jabber_stream_init(js); | |
845 jabber_parser_setup(js); | |
846 break; | |
847 case JABBER_STREAM_AUTHENTICATING: | |
848 gaim_connection_update_progress(js->gc, _("Authenticating"), | |
849 js->gsc ? 6 : 3, JABBER_CONNECT_STEPS); | |
8296 | 850 if(js->protocol_version == JABBER_PROTO_0_9 && js->registration) { |
851 jabber_register_start(js); | |
852 } else if(js->auth_type == JABBER_AUTH_IQ_AUTH) { | |
853 jabber_auth_start_old(js); | |
8016 | 854 } |
7014 | 855 break; |
856 case JABBER_STREAM_REINITIALIZING: | |
857 gaim_connection_update_progress(js->gc, _("Re-initializing Stream"), | |
858 6, JABBER_CONNECT_STEPS); | |
859 jabber_stream_init(js); | |
860 break; | |
861 case JABBER_STREAM_CONNECTED: | |
862 jabber_roster_request(js); | |
9954 | 863 gpresence = gaim_account_get_presence(js->gc->account); |
864 status = gaim_presence_get_active_status(gpresence); | |
10216 | 865 jabber_presence_send(js->gc->account, status); |
10941 | 866 gaim_connection_set_state(js->gc, GAIM_CONNECTED); |
8312 | 867 jabber_disco_items_server(js); |
7014 | 868 break; |
3105 | 869 } |
870 } | |
871 | |
7014 | 872 char *jabber_get_next_id(JabberStream *js) |
2086 | 873 { |
7322 | 874 return g_strdup_printf("gaim%x", js->next_id++); |
2086 | 875 } |
876 | |
7923 | 877 |
878 static void jabber_idle_set(GaimConnection *gc, int idle) | |
3340 | 879 { |
7014 | 880 JabberStream *js = gc->proto_data; |
3340 | 881 |
7014 | 882 js->idle = idle ? time(NULL) - idle : idle; |
3314 | 883 } |
884 | |
6695 | 885 static const char *jabber_list_icon(GaimAccount *a, GaimBuddy *b) |
2086 | 886 { |
4687 | 887 return "jabber"; |
888 } | |
4916 | 889 |
9954 | 890 static void jabber_list_emblems(GaimBuddy *b, const char **se, const char **sw, |
891 const char **nw, const char **ne) | |
4916 | 892 { |
7014 | 893 JabberStream *js; |
894 JabberBuddy *jb; | |
895 | |
896 if(!b->account->gc) | |
897 return; | |
898 js = b->account->gc->proto_data; | |
899 jb = jabber_buddy_find(js, b->name, FALSE); | |
5135 | 900 |
901 if(!GAIM_BUDDY_IS_ONLINE(b)) { | |
7014 | 902 if(jb && jb->error_msg) |
4927 | 903 *nw = "error"; |
5135 | 904 |
7014 | 905 if(jb && (jb->subscription & JABBER_SUB_PENDING || |
906 !(jb->subscription & JABBER_SUB_TO))) | |
5135 | 907 *se = "notauthorized"; |
908 else | |
909 *se = "offline"; | |
4916 | 910 } else { |
9954 | 911 GaimStatusType *status_type = gaim_status_get_type(gaim_presence_get_active_status(gaim_buddy_get_presence(b))); |
912 | |
11522 | 913 if(gaim_status_type_get_primitive(status_type) > GAIM_STATUS_AVAILABLE) { |
9954 | 914 *se = gaim_status_type_get_id(status_type); |
915 if(!strcmp(*se, "xa")) | |
7014 | 916 *se = "extendedaway"; |
4916 | 917 } |
2086 | 918 } |
4916 | 919 } |
2086 | 920 |
7014 | 921 static char *jabber_status_text(GaimBuddy *b) |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
922 { |
7014 | 923 JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name, |
924 FALSE); | |
925 char *ret = NULL; | |
5234 | 926 |
7014 | 927 if(jb && !GAIM_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) { |
928 ret = g_strdup(_("Not Authorized")); | |
929 } else if(jb && !GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) { | |
930 ret = g_strdup(jb->error_msg); | |
2956 | 931 } else { |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
932 char *stripped; |
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7072
diff
changeset
|
933 |
9954 | 934 if(!(stripped = gaim_markup_strip_html(jabber_buddy_get_status_msg(jb)))) { |
935 GaimStatus *status = gaim_presence_get_active_status(gaim_buddy_get_presence(b)); | |
2956 | 936 |
9954 | 937 if(!gaim_status_is_available(status)) |
938 stripped = g_strdup(gaim_status_get_name(status)); | |
939 } | |
2086 | 940 |
7014 | 941 if(stripped) { |
942 ret = g_markup_escape_text(stripped, -1); | |
943 g_free(stripped); | |
944 } | |
2086 | 945 } |
946 | |
7014 | 947 return ret; |
2956 | 948 } |
949 | |
6695 | 950 static char *jabber_tooltip_text(GaimBuddy *b) |
4744 | 951 { |
11609 | 952 JabberBuddy *jb; |
953 GString *ret; | |
954 | |
955 g_return_val_if_fail(b != NULL, NULL); | |
956 g_return_val_if_fail(b->account != NULL, NULL); | |
957 g_return_val_if_fail(b->account->gc != NULL, NULL); | |
958 g_return_val_if_fail(b->account->gc->proto_data != NULL, NULL); | |
959 | |
960 jb = jabber_buddy_find(b->account->gc->proto_data, b->name, | |
7014 | 961 FALSE); |
11609 | 962 ret = g_string_new(""); |
7014 | 963 |
8194 | 964 if(jb) { |
11609 | 965 JabberBuddyResource *jbr = NULL; |
8194 | 966 const char *sub; |
11609 | 967 GList *l; |
968 | |
8194 | 969 if(jb->subscription & JABBER_SUB_FROM) { |
970 if(jb->subscription & JABBER_SUB_TO) | |
971 sub = _("Both"); | |
972 else if(jb->subscription & JABBER_SUB_PENDING) | |
973 sub = _("From (To pending)"); | |
974 else | |
975 sub = _("From"); | |
976 } else { | |
977 if(jb->subscription & JABBER_SUB_TO) | |
978 sub = _("To"); | |
979 else if(jb->subscription & JABBER_SUB_PENDING) | |
980 sub = _("None (To pending)"); | |
981 else | |
982 sub = _("None"); | |
983 } | |
8591 | 984 g_string_append_printf(ret, "\n<b>%s:</b> %s", _("Subscription"), sub); |
8194 | 985 |
11609 | 986 for(l=jb->resources; l; l = l->next) { |
8194 | 987 char *text = NULL; |
11609 | 988 char *res = NULL; |
989 | |
990 jbr = l->data; | |
991 | |
8194 | 992 if(jbr->status) { |
11646 | 993 char *tmp; |
994 text = gaim_strreplace(jbr->status, "\n", "<br />\n"); | |
995 tmp = gaim_markup_strip_html(text); | |
996 g_free(text); | |
997 text = g_markup_escape_text(tmp, -1); | |
998 g_free(tmp); | |
8194 | 999 } |
1000 | |
11609 | 1001 if(jbr->name) |
11610 | 1002 res = g_strdup_printf(" (%s)", jbr->name); |
11609 | 1003 |
1004 g_string_append_printf(ret, "\n<b>%s%s:</b> %s%s%s", | |
8194 | 1005 _("Status"), |
11609 | 1006 res ? res : "", |
9954 | 1007 jabber_buddy_state_get_name(jbr->state), |
8194 | 1008 text ? ": " : "", |
1009 text ? text : ""); | |
1010 if(text) | |
1011 g_free(text); | |
11609 | 1012 if(res) |
1013 g_free(res); | |
1014 } | |
1015 | |
1016 if(!GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) { | |
8591 | 1017 g_string_append_printf(ret, "\n<b>%s:</b> %s", |
8194 | 1018 _("Error"), jb->error_msg); |
1019 } | |
4745 | 1020 } |
4744 | 1021 |
8591 | 1022 return g_string_free(ret, FALSE); |
4732 | 1023 } |
1024 | |
9954 | 1025 static GList *jabber_status_types(GaimAccount *account) |
7014 | 1026 { |
9954 | 1027 GaimStatusType *type; |
1028 GList *types = NULL; | |
11568 | 1029 GaimValue *priority_value; |
9954 | 1030 |
9980 | 1031 type = gaim_status_type_new_with_attrs(GAIM_STATUS_OFFLINE, "offline", |
1032 _("Offline"), FALSE, TRUE, FALSE, "message", _("Message"), | |
1033 gaim_value_new(GAIM_TYPE_STRING), NULL); | |
9954 | 1034 types = g_list_append(types, type); |
1035 | |
11568 | 1036 priority_value = gaim_value_new(GAIM_TYPE_INT); |
11569 | 1037 gaim_value_set_int(priority_value, 1); |
10486 | 1038 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, "available", |
1039 _("Available"), TRUE, TRUE, FALSE, "priority", _("Priority"), | |
11568 | 1040 priority_value, "message", _("Message"), |
9980 | 1041 gaim_value_new(GAIM_TYPE_STRING), NULL); |
1042 types = g_list_append(types, type); | |
1043 | |
11568 | 1044 priority_value = gaim_value_new(GAIM_TYPE_INT); |
11569 | 1045 gaim_value_set_int(priority_value, 1); |
9980 | 1046 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AVAILABLE, "chat", |
1047 _("Chatty"), TRUE, TRUE, FALSE, "priority", _("Priority"), | |
11568 | 1048 priority_value, "message", _("Message"), |
9980 | 1049 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9954 | 1050 types = g_list_append(types, type); |
2086 | 1051 |
11568 | 1052 priority_value = gaim_value_new(GAIM_TYPE_INT); |
11569 | 1053 gaim_value_set_int(priority_value, 0); |
9980 | 1054 type = gaim_status_type_new_with_attrs(GAIM_STATUS_AWAY, "away", |
1055 _("Away"), TRUE, TRUE, FALSE, "priority", _("Priority"), | |
11568 | 1056 priority_value, "message", _("Message"), |
9980 | 1057 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9954 | 1058 types = g_list_append(types, type); |
1059 | |
11568 | 1060 priority_value = gaim_value_new(GAIM_TYPE_INT); |
11569 | 1061 gaim_value_set_int(priority_value, 0); |
9980 | 1062 type = gaim_status_type_new_with_attrs(GAIM_STATUS_EXTENDED_AWAY, "xa", |
1063 _("Extended Away"), TRUE, TRUE, FALSE, "priority", _("Priority"), | |
11568 | 1064 priority_value, "message", _("Message"), |
9980 | 1065 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9954 | 1066 types = g_list_append(types, type); |
1067 | |
11568 | 1068 priority_value = gaim_value_new(GAIM_TYPE_INT); |
11569 | 1069 gaim_value_set_int(priority_value, 0); |
9980 | 1070 type = gaim_status_type_new_with_attrs(GAIM_STATUS_UNAVAILABLE, "dnd", |
1071 _("Do Not Disturb"), TRUE, TRUE, FALSE, "priority", _("Priority"), | |
11568 | 1072 priority_value, "message", _("Message"), |
9980 | 1073 gaim_value_new(GAIM_TYPE_STRING), NULL); |
9954 | 1074 types = g_list_append(types, type); |
1075 | |
1076 /* | |
8166 | 1077 if(js->protocol_version == JABBER_PROTO_0_9) |
1078 m = g_list_append(m, _("Invisible")); | |
10009 | 1079 */ |
2086 | 1080 |
9954 | 1081 return types; |
2086 | 1082 } |
1083 | |
7395 | 1084 static void |
1085 jabber_password_change_result_cb(JabberStream *js, xmlnode *packet, | |
1086 gpointer data) | |
7124 | 1087 { |
1088 const char *type; | |
1089 | |
1090 type = xmlnode_get_attrib(packet, "type"); | |
1091 | |
9414 | 1092 if(type && !strcmp(type, "result")) { |
7124 | 1093 gaim_notify_info(js->gc, _("Password Changed"), _("Password Changed"), |
1094 _("Your password has been changed.")); | |
1095 } else { | |
8401 | 1096 char *msg = jabber_parse_error(js, packet); |
7124 | 1097 |
8401 | 1098 gaim_notify_error(js->gc, _("Error changing password"), |
1099 _("Error changing password"), msg); | |
1100 g_free(msg); | |
7124 | 1101 } |
1102 } | |
1103 | |
1104 static void jabber_password_change_cb(JabberStream *js, | |
1105 GaimRequestFields *fields) | |
1106 { | |
1107 const char *p1, *p2; | |
1108 JabberIq *iq; | |
1109 xmlnode *query, *y; | |
1110 | |
1111 p1 = gaim_request_fields_get_string(fields, "password1"); | |
1112 p2 = gaim_request_fields_get_string(fields, "password2"); | |
1113 | |
1114 if(strcmp(p1, p2)) { | |
1115 gaim_notify_error(js->gc, NULL, _("New passwords do not match."), NULL); | |
1116 return; | |
1117 } | |
1118 | |
1119 iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:register"); | |
1120 | |
1121 xmlnode_set_attrib(iq->node, "to", js->user->domain); | |
1122 | |
1123 query = xmlnode_get_child(iq->node, "query"); | |
1124 | |
1125 y = xmlnode_new_child(query, "username"); | |
1126 xmlnode_insert_data(y, js->user->node, -1); | |
1127 y = xmlnode_new_child(query, "password"); | |
1128 xmlnode_insert_data(y, p1, -1); | |
1129 | |
7395 | 1130 jabber_iq_set_callback(iq, jabber_password_change_result_cb, NULL); |
7124 | 1131 |
1132 jabber_iq_send(iq); | |
1133 | |
1134 gaim_account_set_password(js->gc->account, p1); | |
1135 } | |
1136 | |
9015 | 1137 static void jabber_password_change(GaimPluginAction *action) |
7124 | 1138 { |
9015 | 1139 |
1140 GaimConnection *gc = (GaimConnection *) action->context; | |
7124 | 1141 JabberStream *js = gc->proto_data; |
1142 GaimRequestFields *fields; | |
1143 GaimRequestFieldGroup *group; | |
1144 GaimRequestField *field; | |
1145 | |
1146 fields = gaim_request_fields_new(); | |
1147 group = gaim_request_field_group_new(NULL); | |
1148 gaim_request_fields_add_group(fields, group); | |
1149 | |
1150 field = gaim_request_field_string_new("password1", _("Password"), | |
1151 "", FALSE); | |
1152 gaim_request_field_string_set_masked(field, TRUE); | |
1153 gaim_request_field_group_add_field(group, field); | |
1154 | |
1155 field = gaim_request_field_string_new("password2", _("Password (again)"), | |
1156 "", FALSE); | |
1157 gaim_request_field_string_set_masked(field, TRUE); | |
1158 gaim_request_field_group_add_field(group, field); | |
1159 | |
1160 gaim_request_fields(js->gc, _("Change Jabber Password"), | |
1161 _("Change Jabber Password"), _("Please enter your new password"), | |
1162 fields, _("OK"), G_CALLBACK(jabber_password_change_cb), | |
1163 _("Cancel"), NULL, js); | |
1164 } | |
1165 | |
9015 | 1166 static GList *jabber_actions(GaimPlugin *plugin, gpointer context) |
2956 | 1167 { |
1168 GList *m = NULL; | |
9015 | 1169 GaimPluginAction *act; |
4333 | 1170 |
9015 | 1171 act = gaim_plugin_action_new(_("Set User Info"), |
1172 jabber_setup_set_info); | |
1173 m = g_list_append(m, act); | |
4333 | 1174 |
8296 | 1175 /* if (js->protocol_options & CHANGE_PASSWORD) { */ |
9015 | 1176 act = gaim_plugin_action_new(_("Change Password"), |
1177 jabber_password_change); | |
1178 m = g_list_append(m, act); | |
8296 | 1179 /* } */ |
2956 | 1180 |
11675 | 1181 act = gaim_plugin_action_new(_("Search for users"), |
1182 jabber_user_search_begin); | |
1183 m = g_list_append(m, act); | |
1184 | |
2956 | 1185 return m; |
1186 } | |
1187 | |
7999 | 1188 static GaimChat *jabber_find_blist_chat(GaimAccount *account, const char *name) |
1189 { | |
1190 GaimBlistNode *gnode, *cnode; | |
1191 JabberID *jid; | |
1192 | |
1193 if(!(jid = jabber_id_new(name))) | |
1194 return NULL; | |
1195 | |
1196 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { | |
1197 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
1198 GaimChat *chat = (GaimChat*)cnode; | |
1199 const char *room, *server; | |
1200 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
1201 continue; | |
1202 | |
1203 if(chat->account != account) | |
8011 | 1204 continue; |
7999 | 1205 |
1206 if(!(room = g_hash_table_lookup(chat->components, "room"))) | |
1207 continue; | |
1208 if(!(server = g_hash_table_lookup(chat->components, "server"))) | |
1209 continue; | |
1210 | |
8158 | 1211 if(jid->node && jid->domain && |
1212 !g_utf8_collate(room, jid->node) && !g_utf8_collate(server, jid->domain)) { | |
7999 | 1213 jabber_id_free(jid); |
1214 return chat; | |
1215 } | |
1216 } | |
1217 } | |
1218 jabber_id_free(jid); | |
1219 return NULL; | |
1220 } | |
1221 | |
8400 | 1222 static void jabber_convo_closed(GaimConnection *gc, const char *who) |
1223 { | |
1224 JabberStream *js = gc->proto_data; | |
1225 JabberID *jid; | |
1226 JabberBuddy *jb; | |
1227 JabberBuddyResource *jbr; | |
1228 | |
1229 if(!(jid = jabber_id_new(who))) | |
1230 return; | |
1231 | |
1232 if((jb = jabber_buddy_find(js, who, TRUE)) && | |
1233 (jbr = jabber_buddy_find_resource(jb, jid->resource))) { | |
1234 if(jbr->thread_id) { | |
1235 g_free(jbr->thread_id); | |
1236 jbr->thread_id = NULL; | |
1237 } | |
1238 } | |
1239 | |
1240 jabber_id_free(jid); | |
1241 } | |
1242 | |
8401 | 1243 |
1244 char *jabber_parse_error(JabberStream *js, xmlnode *packet) | |
1245 { | |
1246 xmlnode *error; | |
1247 const char *code = NULL, *text = NULL; | |
1248 const char *xmlns = xmlnode_get_attrib(packet, "xmlns"); | |
1249 char *cdata = NULL; | |
1250 | |
1251 if((error = xmlnode_get_child(packet, "error"))) { | |
1252 cdata = xmlnode_get_data(error); | |
1253 code = xmlnode_get_attrib(error, "code"); | |
1254 | |
1255 /* Stanza errors */ | |
1256 if(xmlnode_get_child(error, "bad-request")) { | |
1257 text = _("Bad Request"); | |
1258 } else if(xmlnode_get_child(error, "conflict")) { | |
1259 text = _("Conflict"); | |
1260 } else if(xmlnode_get_child(error, "feature-not-implemented")) { | |
1261 text = _("Feature Not Implemented"); | |
1262 } else if(xmlnode_get_child(error, "forbidden")) { | |
1263 text = _("Forbidden"); | |
1264 } else if(xmlnode_get_child(error, "gone")) { | |
1265 text = _("Gone"); | |
1266 } else if(xmlnode_get_child(error, "internal-server-error")) { | |
1267 text = _("Internal Server Error"); | |
1268 } else if(xmlnode_get_child(error, "item-not-found")) { | |
1269 text = _("Item Not Found"); | |
1270 } else if(xmlnode_get_child(error, "jid-malformed")) { | |
1271 text = _("Malformed Jabber ID"); | |
1272 } else if(xmlnode_get_child(error, "not-acceptable")) { | |
1273 text = _("Not Acceptable"); | |
1274 } else if(xmlnode_get_child(error, "not-allowed")) { | |
1275 text = _("Not Allowed"); | |
1276 } else if(xmlnode_get_child(error, "not-authorized")) { | |
1277 text = _("Not Authorized"); | |
1278 } else if(xmlnode_get_child(error, "payment-required")) { | |
1279 text = _("Payment Required"); | |
1280 } else if(xmlnode_get_child(error, "recipient-unavailable")) { | |
1281 text = _("Recipient Unavailable"); | |
1282 } else if(xmlnode_get_child(error, "redirect")) { | |
1283 /* XXX */ | |
1284 } else if(xmlnode_get_child(error, "registration-required")) { | |
1285 text = _("Registration Required"); | |
1286 } else if(xmlnode_get_child(error, "remote-server-not-found")) { | |
1287 text = _("Remote Server Not Found"); | |
1288 } else if(xmlnode_get_child(error, "remote-server-timeout")) { | |
1289 text = _("Remote Server Timeout"); | |
1290 } else if(xmlnode_get_child(error, "resource-constraint")) { | |
1291 text = _("Server Overloaded"); | |
1292 } else if(xmlnode_get_child(error, "service-unavailable")) { | |
1293 text = _("Service Unavailable"); | |
1294 } else if(xmlnode_get_child(error, "subscription-required")) { | |
1295 text = _("Subscription Required"); | |
1296 } else if(xmlnode_get_child(error, "unexpected-request")) { | |
1297 text = _("Unexpected Request"); | |
1298 } else if(xmlnode_get_child(error, "undefined-condition")) { | |
1299 text = _("Unknown Error"); | |
1300 } | |
1301 } else if(xmlns && !strcmp(xmlns, "urn:ietf:params:xml:ns:xmpp-sasl")) { | |
1302 if(xmlnode_get_child(packet, "aborted")) { | |
1303 js->gc->wants_to_die = TRUE; | |
1304 text = _("Authorization Aborted"); | |
1305 } else if(xmlnode_get_child(error, "incorrect-encoding")) { | |
1306 text = _("Incorrect encoding in authorization"); | |
1307 } else if(xmlnode_get_child(error, "invalid-authzid")) { | |
1308 js->gc->wants_to_die = TRUE; | |
1309 text = _("Invalid authzid"); | |
1310 } else if(xmlnode_get_child(error, "invalid-mechanism")) { | |
1311 js->gc->wants_to_die = TRUE; | |
1312 text = _("Invalid Authorization Mechanism"); | |
1313 } else if(xmlnode_get_child(error, "mechanism-too-weak")) { | |
1314 js->gc->wants_to_die = TRUE; | |
1315 text = _("Authorization mechanism too weak"); | |
1316 } else if(xmlnode_get_child(error, "not-authorized")) { | |
1317 js->gc->wants_to_die = TRUE; | |
1318 text = _("Not Authorized"); | |
1319 } else if(xmlnode_get_child(error, "temporary-auth-failure")) { | |
1320 text = _("Temporary Authentication Failure"); | |
1321 } else { | |
1322 text = _("Authentication Failure"); | |
1323 } | |
8402 | 1324 } else if(!strcmp(packet->name, "stream:error")) { |
1325 if(xmlnode_get_child(packet, "bad-format")) { | |
1326 text = _("Bad Format"); | |
1327 } else if(xmlnode_get_child(packet, "bad-namespace-prefix")) { | |
1328 text = _("Bad Namespace Prefix"); | |
1329 } else if(xmlnode_get_child(packet, "conflict")) { | |
1330 js->gc->wants_to_die = TRUE; | |
1331 text = _("Resource Conflict"); | |
1332 } else if(xmlnode_get_child(packet, "connection-timeout")) { | |
1333 text = _("Connection Timeout"); | |
1334 } else if(xmlnode_get_child(packet, "host-gone")) { | |
1335 text = _("Host Gone"); | |
1336 } else if(xmlnode_get_child(packet, "host-unknown")) { | |
1337 text = _("Host Unknown"); | |
1338 } else if(xmlnode_get_child(packet, "improper-addressing")) { | |
1339 text = _("Improper Addressing"); | |
1340 } else if(xmlnode_get_child(packet, "internal-server-error")) { | |
1341 text = _("Internal Server Error"); | |
1342 } else if(xmlnode_get_child(packet, "invalid-id")) { | |
1343 text = _("Invalid ID"); | |
1344 } else if(xmlnode_get_child(packet, "invalid-namespace")) { | |
1345 text = _("Invalid Namespace"); | |
1346 } else if(xmlnode_get_child(packet, "invalid-xml")) { | |
1347 text = _("Invalid XML"); | |
1348 } else if(xmlnode_get_child(packet, "nonmatching-hosts")) { | |
1349 text = _("Non-matching Hosts"); | |
1350 } else if(xmlnode_get_child(packet, "not-authorized")) { | |
1351 text = _("Not Authorized"); | |
1352 } else if(xmlnode_get_child(packet, "policy-violation")) { | |
1353 text = _("Policy Violation"); | |
1354 } else if(xmlnode_get_child(packet, "remote-connection-failed")) { | |
1355 text = _("Remote Connection Failed"); | |
1356 } else if(xmlnode_get_child(packet, "resource-constraint")) { | |
1357 text = _("Resource Constraint"); | |
1358 } else if(xmlnode_get_child(packet, "restricted-xml")) { | |
1359 text = _("Restricted XML"); | |
1360 } else if(xmlnode_get_child(packet, "see-other-host")) { | |
1361 text = _("See Other Host"); | |
1362 } else if(xmlnode_get_child(packet, "system-shutdown")) { | |
1363 text = _("System Shutdown"); | |
1364 } else if(xmlnode_get_child(packet, "undefined-condition")) { | |
1365 text = _("Undefined Condition"); | |
1366 } else if(xmlnode_get_child(packet, "unsupported-encoding")) { | |
1367 text = _("Unsupported Encoding"); | |
1368 } else if(xmlnode_get_child(packet, "unsupported-stanza-type")) { | |
1369 text = _("Unsupported Stanza Type"); | |
1370 } else if(xmlnode_get_child(packet, "unsupported-version")) { | |
1371 text = _("Unsupported Version"); | |
1372 } else if(xmlnode_get_child(packet, "xml-not-well-formed")) { | |
1373 text = _("XML Not Well Formed"); | |
1374 } else { | |
1375 text = _("Stream Error"); | |
1376 } | |
8401 | 1377 } |
1378 | |
1379 if(text || cdata) { | |
1380 char *ret = g_strdup_printf("%s%s%s", code ? code : "", | |
1381 code ? ": " : "", text ? text : cdata); | |
1382 g_free(cdata); | |
1383 return ret; | |
1384 } else { | |
1385 return NULL; | |
1386 } | |
1387 } | |
1388 | |
9130 | 1389 static GaimCmdRet jabber_cmd_chat_config(GaimConversation *conv, |
9597 | 1390 const char *cmd, char **args, char **error, void *data) |
9130 | 1391 { |
1392 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1393 jabber_chat_request_room_configure(chat); | |
1394 return GAIM_CMD_RET_OK; | |
1395 } | |
1396 | |
1397 static GaimCmdRet jabber_cmd_chat_register(GaimConversation *conv, | |
9597 | 1398 const char *cmd, char **args, char **error, void *data) |
9130 | 1399 { |
1400 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1401 jabber_chat_register(chat); | |
1402 return GAIM_CMD_RET_OK; | |
1403 } | |
1404 | |
1405 static GaimCmdRet jabber_cmd_chat_topic(GaimConversation *conv, | |
9597 | 1406 const char *cmd, char **args, char **error, void *data) |
9130 | 1407 { |
1408 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1409 jabber_chat_change_topic(chat, args ? args[0] : NULL); | |
1410 return GAIM_CMD_RET_OK; | |
1411 } | |
1412 | |
1413 static GaimCmdRet jabber_cmd_chat_nick(GaimConversation *conv, | |
9597 | 1414 const char *cmd, char **args, char **error, void *data) |
9130 | 1415 { |
1416 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1417 | |
1418 if(!args || !args[0]) | |
1419 return GAIM_CMD_RET_FAILED; | |
1420 | |
1421 jabber_chat_change_nick(chat, args[0]); | |
1422 return GAIM_CMD_RET_OK; | |
1423 } | |
1424 | |
1425 static GaimCmdRet jabber_cmd_chat_part(GaimConversation *conv, | |
9597 | 1426 const char *cmd, char **args, char **error, void *data) |
9130 | 1427 { |
1428 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1429 jabber_chat_part(chat, args ? args[0] : NULL); | |
1430 return GAIM_CMD_RET_OK; | |
1431 } | |
1432 | |
9152 | 1433 static GaimCmdRet jabber_cmd_chat_ban(GaimConversation *conv, |
9597 | 1434 const char *cmd, char **args, char **error, void *data) |
9152 | 1435 { |
1436 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1437 | |
1438 if(!args || !args[0]) | |
1439 return GAIM_CMD_RET_FAILED; | |
1440 | |
1441 if(!jabber_chat_ban_user(chat, args[0], args[1])) { | |
1442 *error = g_strdup_printf(_("Unable to ban user %s"), args[0]); | |
1443 return GAIM_CMD_RET_FAILED; | |
1444 } | |
1445 | |
1446 return GAIM_CMD_RET_OK; | |
1447 } | |
1448 | |
11393 | 1449 static GaimCmdRet jabber_cmd_chat_affiliate(GaimConversation *conv, |
1450 const char *cmd, char **args, char **error, void *data) | |
1451 { | |
1452 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1453 | |
1454 if (!args || !args[0] || !args[1]) | |
1455 return GAIM_CMD_RET_FAILED; | |
1456 | |
1457 if ( | |
1458 strcmp(args[1], "owner") != 0 && | |
1459 strcmp(args[1], "admin") != 0 && | |
1460 strcmp(args[1], "member") != 0 && | |
1461 strcmp(args[1], "outcast") != 0 && | |
1462 strcmp(args[1], "none") != 0 | |
1463 ) { | |
1464 *error = g_strdup_printf(_("Unknown affiliation: \"%s\""), args[1]); | |
1465 return GAIM_CMD_RET_FAILED; | |
1466 } | |
1467 | |
1468 if (!jabber_chat_affiliate_user(chat, args[0], args[1])) { | |
1469 *error = g_strdup_printf(_("Unable to affiliate user %s as \"%s\""), args[0], args[1]); | |
1470 return GAIM_CMD_RET_FAILED; | |
1471 } | |
1472 | |
1473 return GAIM_CMD_RET_OK; | |
1474 } | |
1475 | |
9152 | 1476 static GaimCmdRet jabber_cmd_chat_invite(GaimConversation *conv, |
9597 | 1477 const char *cmd, char **args, char **error, void *data) |
9152 | 1478 { |
1479 if(!args || !args[0]) | |
1480 return GAIM_CMD_RET_FAILED; | |
1481 | |
1482 jabber_chat_invite(gaim_conversation_get_gc(conv), | |
1483 gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)), args[1] ? args[1] : "", | |
1484 args[0]); | |
1485 | |
1486 return GAIM_CMD_RET_OK; | |
1487 } | |
1488 | |
1489 static GaimCmdRet jabber_cmd_chat_join(GaimConversation *conv, | |
9597 | 1490 const char *cmd, char **args, char **error, void *data) |
9152 | 1491 { |
1492 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1493 GHashTable *components; | |
1494 | |
1495 if(!args || !args[0]) | |
1496 return GAIM_CMD_RET_FAILED; | |
1497 | |
1498 components = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); | |
1499 | |
1500 g_hash_table_replace(components, "room", args[0]); | |
1501 g_hash_table_replace(components, "server", chat->server); | |
1502 g_hash_table_replace(components, "handle", chat->handle); | |
1503 if(args[1]) | |
1504 g_hash_table_replace(components, "password", args[1]); | |
1505 | |
1506 jabber_chat_join(gaim_conversation_get_gc(conv), components); | |
1507 | |
1508 g_hash_table_destroy(components); | |
1509 return GAIM_CMD_RET_OK; | |
1510 } | |
1511 | |
1512 static GaimCmdRet jabber_cmd_chat_kick(GaimConversation *conv, | |
9597 | 1513 const char *cmd, char **args, char **error, void *data) |
9152 | 1514 { |
1515 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1516 | |
1517 if(!args || !args[0]) | |
1518 return GAIM_CMD_RET_FAILED; | |
1519 | |
1520 if(!jabber_chat_kick_user(chat, args[0], args[1])) { | |
1521 *error = g_strdup_printf(_("Unable to kick user %s"), args[0]); | |
1522 return GAIM_CMD_RET_FAILED; | |
1523 } | |
1524 | |
1525 return GAIM_CMD_RET_OK; | |
1526 } | |
1527 | |
1528 static GaimCmdRet jabber_cmd_chat_msg(GaimConversation *conv, | |
9597 | 1529 const char *cmd, char **args, char **error, void *data) |
9152 | 1530 { |
1531 JabberChat *chat = jabber_chat_find_by_conv(conv); | |
1532 char *who; | |
1533 | |
1534 who = g_strdup_printf("%s@%s/%s", chat->room, chat->server, args[0]); | |
1535 | |
1536 jabber_message_send_im(gaim_conversation_get_gc(conv), who, args[1], 0); | |
1537 | |
1538 g_free(who); | |
1539 return GAIM_CMD_RET_OK; | |
1540 } | |
1541 | |
9130 | 1542 static void jabber_register_commands(void) |
1543 { | |
1544 gaim_cmd_register("config", "", GAIM_CMD_P_PRPL, | |
9597 | 1545 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
1546 "prpl-jabber", jabber_cmd_chat_config, | |
1547 _("config: Configure a chat room."), NULL); | |
9130 | 1548 gaim_cmd_register("configure", "", GAIM_CMD_P_PRPL, |
9597 | 1549 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
1550 "prpl-jabber", jabber_cmd_chat_config, | |
1551 _("configure: Configure a chat room."), NULL); | |
9130 | 1552 gaim_cmd_register("nick", "s", GAIM_CMD_P_PRPL, |
9597 | 1553 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
1554 "prpl-jabber", jabber_cmd_chat_nick, | |
1555 _("nick <new nickname>: Change your nickname."), | |
1556 NULL); | |
9130 | 1557 gaim_cmd_register("part", "s", GAIM_CMD_P_PRPL, |
9597 | 1558 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1559 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1560 jabber_cmd_chat_part, _("part [room]: Leave the room."), | |
1561 NULL); | |
9130 | 1562 gaim_cmd_register("register", "", GAIM_CMD_P_PRPL, |
9597 | 1563 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
1564 "prpl-jabber", jabber_cmd_chat_register, | |
1565 _("register: Register with a chat room."), NULL); | |
9130 | 1566 /* XXX: there needs to be a core /topic cmd, methinks */ |
1567 gaim_cmd_register("topic", "s", GAIM_CMD_P_PRPL, | |
9597 | 1568 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1569 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1570 jabber_cmd_chat_topic, | |
1571 _("topic [new topic]: View or change the topic."), | |
1572 NULL); | |
9152 | 1573 gaim_cmd_register("ban", "ws", GAIM_CMD_P_PRPL, |
9597 | 1574 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1575 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1576 jabber_cmd_chat_ban, | |
1577 _("ban <user> [room]: Ban a user from the room."), | |
1578 NULL); | |
11393 | 1579 gaim_cmd_register("affiliate", "ws", GAIM_CMD_P_PRPL, |
1580 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | | |
1581 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1582 jabber_cmd_chat_affiliate, | |
1583 _("affiliate <user> <owner|admin|member|outcast|none>: Set a user's affiliation with the room."), | |
1584 NULL); | |
9152 | 1585 gaim_cmd_register("invite", "ws", GAIM_CMD_P_PRPL, |
9597 | 1586 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1587 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1588 jabber_cmd_chat_invite, | |
11158
2c930d591492
[gaim-migrate @ 13245]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11033
diff
changeset
|
1589 _("invite <user> [message]: Invite a user to the room."), |
9597 | 1590 NULL); |
9152 | 1591 gaim_cmd_register("join", "ws", GAIM_CMD_P_PRPL, |
9597 | 1592 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1593 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1594 jabber_cmd_chat_join, | |
1595 _("join: <room> [server]: Join a chat on this server."), | |
1596 NULL); | |
9152 | 1597 gaim_cmd_register("kick", "ws", GAIM_CMD_P_PRPL, |
9597 | 1598 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY | |
1599 GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", | |
1600 jabber_cmd_chat_kick, | |
1601 _("kick <user> [room]: Kick a user from the room."), | |
1602 NULL); | |
9152 | 1603 gaim_cmd_register("msg", "ws", GAIM_CMD_P_PRPL, |
9597 | 1604 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
1605 "prpl-jabber", jabber_cmd_chat_msg, | |
1606 _("msg <user> <message>: Send a private message to another user."), | |
1607 NULL); | |
9130 | 1608 } |
1609 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1610 static GaimPluginProtocolInfo prpl_info = |
2086 | 1611 { |
7014 | 1612 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME, |
9475 | 1613 NULL, /* user_splits */ |
1614 NULL, /* protocol_options */ | |
10189 | 1615 {"jpeg,gif,png", 0, 0, 96, 96, GAIM_ICON_SCALE_DISPLAY}, /* icon_spec */ |
9475 | 1616 jabber_list_icon, /* list_icon */ |
1617 jabber_list_emblems, /* list_emblems */ | |
1618 jabber_status_text, /* status_text */ | |
1619 jabber_tooltip_text, /* tooltip_text */ | |
9954 | 1620 jabber_status_types, /* status_types */ |
9475 | 1621 jabber_blist_node_menu, /* blist_node_menu */ |
1622 jabber_chat_info, /* chat_info */ | |
9754 | 1623 jabber_chat_info_defaults, /* chat_info_defaults */ |
9475 | 1624 jabber_login, /* login */ |
1625 jabber_close, /* close */ | |
1626 jabber_message_send_im, /* send_im */ | |
1627 jabber_set_info, /* set_info */ | |
1628 jabber_send_typing, /* send_typing */ | |
1629 jabber_buddy_get_info, /* get_info */ | |
10216 | 1630 jabber_presence_send, /* set_away */ |
9475 | 1631 jabber_idle_set, /* set_idle */ |
1632 NULL, /* change_passwd */ | |
1633 jabber_roster_add_buddy, /* add_buddy */ | |
1634 NULL, /* add_buddies */ | |
1635 jabber_roster_remove_buddy, /* remove_buddy */ | |
1636 NULL, /* remove_buddies */ | |
1637 NULL, /* add_permit */ | |
1638 NULL, /* add_deny */ | |
1639 NULL, /* rem_permit */ | |
1640 NULL, /* rem_deny */ | |
1641 NULL, /* set_permit_deny */ | |
1642 jabber_chat_join, /* join_chat */ | |
1643 NULL, /* reject_chat */ | |
9917 | 1644 jabber_get_chat_name, /* get_chat_name */ |
9475 | 1645 jabber_chat_invite, /* chat_invite */ |
1646 jabber_chat_leave, /* chat_leave */ | |
1647 NULL, /* chat_whisper */ | |
1648 jabber_message_send_chat, /* chat_send */ | |
1649 jabber_keepalive, /* keepalive */ | |
1650 jabber_register_account, /* register_user */ | |
1651 jabber_buddy_get_info_chat, /* get_cb_info */ | |
1652 NULL, /* get_cb_away */ | |
1653 jabber_roster_alias_change, /* alias_buddy */ | |
1654 jabber_roster_group_change, /* group_buddy */ | |
1655 jabber_roster_group_rename, /* rename_group */ | |
1656 NULL, /* buddy_free */ | |
1657 jabber_convo_closed, /* convo_closed */ | |
1658 jabber_normalize, /* normalize */ | |
10189 | 1659 jabber_set_buddy_icon, /* set_buddy_icon */ |
9475 | 1660 NULL, /* remove_group */ |
1661 jabber_chat_buddy_real_name, /* get_cb_real_name */ | |
1662 jabber_chat_set_topic, /* set_chat_topic */ | |
1663 jabber_find_blist_chat, /* find_blist_chat */ | |
1664 jabber_roomlist_get_list, /* roomlist_get_list */ | |
1665 jabber_roomlist_cancel, /* roomlist_cancel */ | |
1666 NULL, /* roomlist_expand_category */ | |
1667 NULL, /* can_receive_file */ | |
1668 jabber_si_xfer_send /* send_file */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1669 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1670 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1671 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1672 { |
9943 | 1673 GAIM_PLUGIN_MAGIC, |
1674 GAIM_MAJOR_VERSION, | |
1675 GAIM_MINOR_VERSION, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1676 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1677 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1678 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1679 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1680 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1681 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1682 "prpl-jabber", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1683 "Jabber", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1684 VERSION, /**< version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1685 /** summary */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1686 N_("Jabber Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1687 /** description */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1688 N_("Jabber Protocol Plugin"), |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1689 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6357
diff
changeset
|
1690 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1691 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1692 NULL, /**< load */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1693 NULL, /**< unload */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1694 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1695 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1696 NULL, /**< ui_info */ |
8993 | 1697 &prpl_info, /**< extra_info */ |
10487 | 1698 NULL, /**< prefs_info */ |
9015 | 1699 jabber_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1700 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1701 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1702 static void |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5894
diff
changeset
|
1703 init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1704 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1705 GaimAccountUserSplit *split; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1706 GaimAccountOption *option; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1707 |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1708 split = gaim_account_user_split_new(_("Server"), "jabber.org", '@'); |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1709 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
|
1710 |
11939
85c25a32bb48
[gaim-migrate @ 14230]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11837
diff
changeset
|
1711 split = gaim_account_user_split_new(_("Resource"), "Home", '/'); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1712 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
|
1713 |
7630 | 1714 option = gaim_account_option_bool_new(_("Use TLS if available"), "use_tls", |
1715 TRUE); | |
1716 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
1717 option); | |
1718 | |
10941 | 1719 option = gaim_account_option_bool_new(_("Require TLS"), "require_tls", TRUE); |
1720 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
1721 | |
1722 option = gaim_account_option_bool_new(_("Force old (port 5223) SSL"), "old_ssl", FALSE); | |
7124 | 1723 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
1724 option); | |
6764 | 1725 |
8086 | 1726 option = gaim_account_option_bool_new( |
1727 _("Allow plaintext auth over unencrypted streams"), | |
1728 "auth_plain_in_clear", FALSE); | |
1729 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
1730 option); | |
1731 | |
11387 | 1732 option = gaim_account_option_int_new(_("Connect port"), "port", 5222); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1733 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
7014 | 1734 option); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1735 |
5685
43ea75092684
[gaim-migrate @ 6106]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
1736 option = gaim_account_option_string_new(_("Connect server"), |
7014 | 1737 "connect_server", NULL); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5613
diff
changeset
|
1738 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
7014 | 1739 option); |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1740 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5174
diff
changeset
|
1741 my_protocol = plugin; |
7014 | 1742 |
10487 | 1743 gaim_prefs_remove("/plugins/prpl/jabber"); |
9130 | 1744 |
1745 jabber_register_commands(); | |
2086 | 1746 } |
1747 | |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5894
diff
changeset
|
1748 GAIM_INIT_PLUGIN(jabber, init_plugin, info); |