| 93 "xmlns:stream='" NS_XMPP_STREAMS "' " |
93 "xmlns:stream='" NS_XMPP_STREAMS "' " |
| 94 "version='1.0'>", |
94 "version='1.0'>", |
| 95 js->user->domain); |
95 js->user->domain); |
| 96 /* setup the parser fresh for each stream */ |
96 /* setup the parser fresh for each stream */ |
| 97 jabber_parser_setup(js); |
97 jabber_parser_setup(js); |
| 98 jabber_send_raw(js, open_stream, -1); |
98 jabber_send_raw(NULL, js, open_stream, -1); |
| 99 js->reinit = FALSE; |
99 js->reinit = FALSE; |
| 100 g_free(open_stream); |
100 g_free(open_stream); |
| 101 } |
101 } |
| 102 |
102 |
| 103 static void |
103 static void |
| 223 |
223 |
| 224 /* Otherwise, it's a standard XMPP connection, or a HTTP (insecure) BOSH connection. |
224 /* Otherwise, it's a standard XMPP connection, or a HTTP (insecure) BOSH connection. |
| 225 * We request STARTTLS for standard XMPP connections, but we do nothing for insecure |
225 * We request STARTTLS for standard XMPP connections, but we do nothing for insecure |
| 226 * BOSH connections, per XEP-0206. */ |
226 * BOSH connections, per XEP-0206. */ |
| 227 if(!js->bosh) { |
227 if(!js->bosh) { |
| 228 jabber_send_raw(js, |
228 jabber_send_raw(NULL, js, |
| 229 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); |
229 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); |
| 230 return TRUE; |
230 return TRUE; |
| 231 } |
231 } |
| 232 |
232 |
| 233 /* It's an insecure standard XMPP connection, or an insecure BOSH connection, let's |
233 /* It's an insecure standard XMPP connection, or an insecure BOSH connection, let's |
| 406 g_bytes_unref(output); |
406 g_bytes_unref(output); |
| 407 |
407 |
| 408 return success; |
408 return success; |
| 409 } |
409 } |
| 410 |
410 |
| 411 void jabber_send_raw(JabberStream *js, const char *data, int len) |
411 void |
| |
412 jabber_send_raw(PurpleProtocolServer *protocol_server, JabberStream *js, |
| |
413 const gchar *data, gint len) |
| 412 { |
414 { |
| 413 PurpleConnection *gc; |
415 PurpleConnection *gc; |
| 414 PurpleAccount *account; |
416 PurpleAccount *account; |
| 415 |
417 |
| 416 gc = js->gc; |
418 gc = js->gc; |
| 512 jabber_bosh_connection_send(js->bosh, data); |
514 jabber_bosh_connection_send(js->bosh, data); |
| 513 else |
515 else |
| 514 do_jabber_send_raw(js, data, len); |
516 do_jabber_send_raw(js, data, len); |
| 515 } |
517 } |
| 516 |
518 |
| 517 int jabber_protocol_send_raw(PurpleConnection *gc, const char *buf, int len) |
519 gint |
| |
520 jabber_protocol_send_raw(PurpleProtocolServer *protocol_server, |
| |
521 PurpleConnection *gc, const gchar *buf, gint len) |
| 518 { |
522 { |
| 519 JabberStream *js = purple_connection_get_protocol_data(gc); |
523 JabberStream *js = purple_connection_get_protocol_data(gc); |
| 520 |
524 |
| 521 g_return_val_if_fail(js != NULL, -1); |
525 g_return_val_if_fail(js != NULL, -1); |
| 522 /* TODO: It's probably worthwhile to restrict this to when the account |
526 /* TODO: It's probably worthwhile to restrict this to when the account |
| 523 * state is CONNECTED, but I can /almost/ envision reasons for wanting |
527 * state is CONNECTED, but I can /almost/ envision reasons for wanting |
| 524 * to do things during the connection process. |
528 * to do things during the connection process. |
| 525 */ |
529 */ |
| 526 |
530 |
| 527 jabber_send_raw(js, buf, len); |
531 jabber_send_raw(NULL, js, buf, len); |
| 528 return (len < 0 ? (int)strlen(buf) : len); |
532 return (len < 0 ? (int)strlen(buf) : len); |
| 529 } |
533 } |
| 530 |
534 |
| 531 void jabber_send_signal_cb(PurpleConnection *pc, PurpleXmlNode **packet, |
535 void jabber_send_signal_cb(PurpleConnection *pc, PurpleXmlNode **packet, |
| 532 gpointer unused) |
536 gpointer unused) |
| 549 if (purple_strequal((*packet)->name, "message") || |
553 if (purple_strequal((*packet)->name, "message") || |
| 550 purple_strequal((*packet)->name, "iq") || |
554 purple_strequal((*packet)->name, "iq") || |
| 551 purple_strequal((*packet)->name, "presence")) |
555 purple_strequal((*packet)->name, "presence")) |
| 552 purple_xmlnode_set_namespace(*packet, NS_XMPP_CLIENT); |
556 purple_xmlnode_set_namespace(*packet, NS_XMPP_CLIENT); |
| 553 txt = purple_xmlnode_to_str(*packet, &len); |
557 txt = purple_xmlnode_to_str(*packet, &len); |
| 554 jabber_send_raw(js, txt, len); |
558 jabber_send_raw(NULL, js, txt, len); |
| 555 g_free(txt); |
559 g_free(txt); |
| 556 } |
560 } |
| 557 |
561 |
| 558 void jabber_send(JabberStream *js, PurpleXmlNode *packet) |
562 void jabber_send(JabberStream *js, PurpleXmlNode *packet) |
| 559 { |
563 { |
| 567 _("Ping timed out")); |
571 _("Ping timed out")); |
| 568 js->keepalive_timeout = 0; |
572 js->keepalive_timeout = 0; |
| 569 return FALSE; |
573 return FALSE; |
| 570 } |
574 } |
| 571 |
575 |
| 572 void jabber_keepalive(PurpleConnection *gc) |
576 void |
| 573 { |
577 jabber_keepalive(PurpleProtocolServer *protocol_server, PurpleConnection *gc) { |
| 574 JabberStream *js = purple_connection_get_protocol_data(gc); |
578 JabberStream *js = purple_connection_get_protocol_data(gc); |
| 575 |
579 |
| 576 if (js->keepalive_timeout == 0) { |
580 if (js->keepalive_timeout == 0) { |
| 577 jabber_keepalive_ping(js); |
581 jabber_keepalive_ping(js); |
| 578 js->keepalive_timeout = g_timeout_add_seconds(120, |
582 js->keepalive_timeout = g_timeout_add_seconds(120, |
| 579 (GSourceFunc)(jabber_keepalive_timeout), gc); |
583 (GSourceFunc)(jabber_keepalive_timeout), gc); |
| 580 } |
584 } |
| 581 } |
585 } |
| 582 |
586 |
| 583 static int jabber_get_keepalive_interval(void) |
587 static int |
| 584 { |
588 jabber_get_keepalive_interval(PurpleProtocolServer *protocol_server) { |
| 585 return PING_TIMEOUT; |
589 return PING_TIMEOUT; |
| 586 } |
590 } |
| 587 |
591 |
| 588 static gboolean |
592 static gboolean |
| 589 jabber_recv_cb(GObject *stream, gpointer data) |
593 jabber_recv_cb(GObject *stream, gpointer data) |
| 729 js->input = g_io_stream_get_input_stream(js->stream); |
733 js->input = g_io_stream_get_input_stream(js->stream); |
| 730 js->output = purple_queued_output_stream_new( |
734 js->output = purple_queued_output_stream_new( |
| 731 g_io_stream_get_output_stream(js->stream)); |
735 g_io_stream_get_output_stream(js->stream)); |
| 732 |
736 |
| 733 if (js->state == JABBER_STREAM_CONNECTING) { |
737 if (js->state == JABBER_STREAM_CONNECTING) { |
| 734 jabber_send_raw(js, "<?xml version='1.0' ?>", -1); |
738 jabber_send_raw(NULL, js, "<?xml version='1.0' ?>", -1); |
| 735 } |
739 } |
| 736 |
740 |
| 737 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
741 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING); |
| 738 source = g_pollable_input_stream_create_source( |
742 source = g_pollable_input_stream_create_source( |
| 739 G_POLLABLE_INPUT_STREAM(js->input), js->cancellable); |
743 G_POLLABLE_INPUT_STREAM(js->input), js->cancellable); |
| 1510 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:register"); |
1514 iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:register"); |
| 1511 purple_xmlnode_set_attrib(iq->node, "to", gateway); |
1515 purple_xmlnode_set_attrib(iq->node, "to", gateway); |
| 1512 jabber_iq_send(iq); |
1516 jabber_iq_send(iq); |
| 1513 } |
1517 } |
| 1514 |
1518 |
| 1515 void jabber_register_account(PurpleAccount *account) |
1519 void |
| |
1520 jabber_register_account(PurpleProtocolServer *protocol_server, |
| |
1521 PurpleAccount *account) |
| 1516 { |
1522 { |
| 1517 JabberStream *js; |
1523 JabberStream *js; |
| 1518 |
1524 |
| 1519 js = jabber_stream_new(account); |
1525 js = jabber_stream_new(account); |
| 1520 if (js == NULL) |
1526 if (js == NULL) |
| 1564 |
1570 |
| 1565 jabber_iq_set_callback(iq, jabber_unregister_account_iq_cb, NULL); |
1571 jabber_iq_set_callback(iq, jabber_unregister_account_iq_cb, NULL); |
| 1566 jabber_iq_send(iq); |
1572 jabber_iq_send(iq); |
| 1567 } |
1573 } |
| 1568 |
1574 |
| 1569 void jabber_unregister_account(PurpleAccount *account, PurpleAccountUnregistrationCb cb, void *user_data) { |
1575 void |
| |
1576 jabber_unregister_account(PurpleProtocolServer *protocol_server, |
| |
1577 PurpleAccount *account, |
| |
1578 PurpleAccountUnregistrationCb cb, gpointer user_data) |
| |
1579 { |
| 1570 PurpleConnection *gc = purple_account_get_connection(account); |
1580 PurpleConnection *gc = purple_account_get_connection(account); |
| 1571 JabberStream *js; |
1581 JabberStream *js; |
| 1572 |
1582 |
| 1573 if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTED) { |
1583 if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTED) { |
| 1574 if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTING) |
1584 if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTING) |
| 1769 { |
1779 { |
| 1770 return g_strdup_printf("purple%x", js->next_id++); |
1780 return g_strdup_printf("purple%x", js->next_id++); |
| 1771 } |
1781 } |
| 1772 |
1782 |
| 1773 |
1783 |
| 1774 void jabber_idle_set(PurpleConnection *gc, int idle) |
1784 void |
| |
1785 jabber_idle_set(PurpleProtocolServer *protocol_server, PurpleConnection *gc, |
| |
1786 gint idle) |
| 1775 { |
1787 { |
| 1776 JabberStream *js = purple_connection_get_protocol_data(gc); |
1788 JabberStream *js = purple_connection_get_protocol_data(gc); |
| 1777 |
1789 |
| 1778 js->idle = idle ? time(NULL) - idle : idle; |
1790 js->idle = idle ? time(NULL) - idle : idle; |
| 1779 |
1791 |
| 2096 /* We want whatever is sent to set this. It's okay because |
2108 /* We want whatever is sent to set this. It's okay because |
| 2097 * the eventloop unsets it via the return FALSE. |
2109 * the eventloop unsets it via the return FALSE. |
| 2098 */ |
2110 */ |
| 2099 js->inactivity_timer = 0; |
2111 js->inactivity_timer = 0; |
| 2100 |
2112 |
| 2101 if (js->bosh) |
2113 if (js->bosh) { |
| 2102 jabber_bosh_connection_send_keepalive(js->bosh); |
2114 jabber_bosh_connection_send_keepalive(js->bosh); |
| 2103 else |
2115 } else { |
| 2104 jabber_send_raw(js, "\t", 1); |
2116 jabber_send_raw(NULL, js, "\t", 1); |
| |
2117 } |
| 2105 |
2118 |
| 2106 return FALSE; |
2119 return FALSE; |
| 2107 } |
2120 } |
| 2108 |
2121 |
| 2109 void jabber_stream_restart_inactivity_timer(JabberStream *js) |
2122 void jabber_stream_restart_inactivity_timer(JabberStream *js) |