Wed, 13 May 2009 20:29:03 +0000
Support custom smileys in MUCs (when all participants support BoB and a maximum
of 10 participants are in the chat).
Always announce support for BoB, since disable custom smileys will still turn
off fetching them, and BoB can be used for other purposes further on.
| 7170 | 1 | /* |
| 15884 | 2 | * purple - Jabber Protocol Plugin |
| 7170 | 3 | * |
| 4 | * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
| 5 | * | |
| 6 | * This program is free software; you can redistribute it and/or modify | |
| 7 | * it under the terms of the GNU General Public License as published by | |
| 8 | * the Free Software Foundation; either version 2 of the License, or | |
| 9 | * (at your option) any later version. | |
| 10 | * | |
| 11 | * This program is distributed in the hope that it will be useful, | |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 | * GNU General Public License for more details. | |
| 15 | * | |
| 16 | * You should have received a copy of the GNU General Public License | |
| 17 | * along with this program; if not, write to the Free Software | |
|
19859
71d37b57eff2
The FSF changed its address a while ago; our files were out of date.
John Bailey <rekkanoryo@rekkanoryo.org>
parents:
15884
diff
changeset
|
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 7170 | 19 | * |
| 20 | */ | |
| 21 | #include "internal.h" | |
| 7234 | 22 | #include "debug.h" |
| 7170 | 23 | #include "ft.h" |
| 24 | #include "util.h" | |
| 25 | ||
| 26 | #include "jabber.h" | |
| 27 | #include "iq.h" | |
|
12324
caf9784f2405
[gaim-migrate @ 14628]
Richard Laager <rlaager@pidgin.im>
parents:
12323
diff
changeset
|
28 | #include "oob.h" |
| 7170 | 29 | |
| 30 | typedef struct _JabberOOBXfer { | |
| 31 | char *address; | |
| 32 | int port; | |
| 33 | char *page; | |
| 34 | ||
| 35 | GString *headers; | |
| 36 | ||
| 37 | char *iq_id; | |
| 38 | ||
| 39 | JabberStream *js; | |
| 40 | ||
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
41 | gchar *write_buffer; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
42 | gsize written_len; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
43 | guint writeh; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
44 | |
| 7170 | 45 | } JabberOOBXfer; |
| 46 | ||
| 15884 | 47 | static void jabber_oob_xfer_init(PurpleXfer *xfer) |
| 7170 | 48 | { |
| 49 | JabberOOBXfer *jox = xfer->data; | |
| 15884 | 50 | purple_xfer_start(xfer, -1, jox->address, jox->port); |
| 7170 | 51 | } |
| 52 | ||
| 15884 | 53 | static void jabber_oob_xfer_free(PurpleXfer *xfer) |
| 7170 | 54 | { |
| 55 | JabberOOBXfer *jox = xfer->data; | |
| 7395 | 56 | jox->js->oob_file_transfers = g_list_remove(jox->js->oob_file_transfers, |
| 57 | xfer); | |
| 7170 | 58 | |
| 59 | g_string_free(jox->headers, TRUE); | |
| 60 | g_free(jox->address); | |
| 61 | g_free(jox->page); | |
| 62 | g_free(jox->iq_id); | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
63 | g_free(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
64 | if(jox->writeh) |
| 15884 | 65 | purple_input_remove(jox->writeh); |
| 7170 | 66 | g_free(jox); |
| 67 | ||
| 68 | xfer->data = NULL; | |
| 69 | } | |
| 70 | ||
| 15884 | 71 | static void jabber_oob_xfer_end(PurpleXfer *xfer) |
| 7170 | 72 | { |
| 73 | JabberOOBXfer *jox = xfer->data; | |
| 74 | JabberIq *iq; | |
| 75 | ||
| 76 | iq = jabber_iq_new(jox->js, JABBER_IQ_RESULT); | |
| 77 | xmlnode_set_attrib(iq->node, "to", xfer->who); | |
| 78 | jabber_iq_set_id(iq, jox->iq_id); | |
| 79 | ||
| 80 | jabber_iq_send(iq); | |
| 81 | ||
| 82 | jabber_oob_xfer_free(xfer); | |
| 83 | } | |
| 84 | ||
| 15884 | 85 | static void jabber_oob_xfer_request_send(gpointer data, gint source, PurpleInputCondition cond) { |
| 86 | PurpleXfer *xfer = data; | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
87 | JabberOOBXfer *jox = xfer->data; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
88 | int len, total_len = strlen(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
89 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
90 | len = write(xfer->fd, jox->write_buffer + jox->written_len, |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
91 | total_len - jox->written_len); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
92 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
93 | if(len < 0 && errno == EAGAIN) |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
94 | return; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
95 | else if(len < 0) { |
| 15884 | 96 | purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Write error on oob xfer!\n"); |
| 97 | purple_input_remove(jox->writeh); | |
| 98 | purple_xfer_cancel_local(xfer); | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
99 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
100 | jox->written_len += len; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
101 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
102 | if(jox->written_len == total_len) { |
| 15884 | 103 | purple_input_remove(jox->writeh); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
104 | g_free(jox->write_buffer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
105 | jox->write_buffer = NULL; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
106 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
107 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
108 | |
| 15884 | 109 | static void jabber_oob_xfer_start(PurpleXfer *xfer) |
| 7170 | 110 | { |
| 111 | JabberOOBXfer *jox = xfer->data; | |
| 112 | ||
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
113 | if(jox->write_buffer == NULL) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
114 | jox->write_buffer = g_strdup_printf( |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
115 | "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", |
| 7170 | 116 | jox->page, jox->address); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
117 | jox->written_len = 0; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
118 | } |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
119 | |
| 15884 | 120 | jox->writeh = purple_input_add(xfer->fd, PURPLE_INPUT_WRITE, |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
121 | jabber_oob_xfer_request_send, xfer); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
122 | |
| 15884 | 123 | jabber_oob_xfer_request_send(xfer, xfer->fd, PURPLE_INPUT_WRITE); |
| 7170 | 124 | } |
| 125 | ||
| 15884 | 126 | static gssize jabber_oob_xfer_read(guchar **buffer, PurpleXfer *xfer) { |
| 7170 | 127 | JabberOOBXfer *jox = xfer->data; |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
128 | char test[2048]; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
129 | char *tmp, *lenstr; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
130 | int len; |
| 7170 | 131 | |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
132 | if((len = read(xfer->fd, test, sizeof(test))) > 0) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
133 | jox->headers = g_string_append_len(jox->headers, test, len); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
134 | if((tmp = strstr(jox->headers->str, "\r\n\r\n"))) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
135 | *tmp = '\0'; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
136 | lenstr = strstr(jox->headers->str, "Content-Length: "); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
137 | if(lenstr) { |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
138 | int size; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
139 | sscanf(lenstr, "Content-Length: %d", &size); |
| 15884 | 140 | purple_xfer_set_size(xfer, size); |
| 7170 | 141 | } |
| 15884 | 142 | purple_xfer_set_read_fnc(xfer, NULL); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
143 | |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
144 | tmp += 4; |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
145 | |
|
14697
518c0fae208e
[gaim-migrate @ 17381]
Daniel Atallah <datallah@pidgin.im>
parents:
14356
diff
changeset
|
146 | *buffer = (unsigned char*) g_strdup(tmp); |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
147 | return strlen(tmp); |
|
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
148 | } |
| 7170 | 149 | return 0; |
|
13201
8c224ef70efa
[gaim-migrate @ 15563]
Daniel Atallah <datallah@pidgin.im>
parents:
12324
diff
changeset
|
150 | } else if (errno != EAGAIN) { |
| 15884 | 151 | purple_debug(PURPLE_DEBUG_ERROR, "jabber", "Read error on oob xfer!\n"); |
| 152 | purple_xfer_cancel_local(xfer); | |
| 7170 | 153 | } |
| 7234 | 154 | |
| 7170 | 155 | return 0; |
| 156 | } | |
| 157 | ||
| 15884 | 158 | static void jabber_oob_xfer_recv_error(PurpleXfer *xfer, const char *code) { |
| 7170 | 159 | JabberOOBXfer *jox = xfer->data; |
| 160 | JabberIq *iq; | |
| 8399 | 161 | xmlnode *y, *z; |
| 7170 | 162 | |
| 163 | iq = jabber_iq_new(jox->js, JABBER_IQ_ERROR); | |
| 164 | xmlnode_set_attrib(iq->node, "to", xfer->who); | |
| 165 | jabber_iq_set_id(iq, jox->iq_id); | |
| 166 | y = xmlnode_new_child(iq->node, "error"); | |
| 8399 | 167 | xmlnode_set_attrib(y, "code", code); |
| 168 | if(!strcmp(code, "406")) { | |
| 169 | z = xmlnode_new_child(y, "not-acceptable"); | |
| 170 | xmlnode_set_attrib(y, "type", "modify"); | |
| 13808 | 171 | xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
| 8399 | 172 | } else if(!strcmp(code, "404")) { |
| 173 | z = xmlnode_new_child(y, "not-found"); | |
| 174 | xmlnode_set_attrib(y, "type", "cancel"); | |
| 13808 | 175 | xmlnode_set_namespace(z, "urn:ietf:params:xml:ns:xmpp-stanzas"); |
| 8399 | 176 | } |
| 7170 | 177 | jabber_iq_send(iq); |
| 178 | ||
| 179 | jabber_oob_xfer_free(xfer); | |
| 180 | } | |
| 181 | ||
| 15884 | 182 | static void jabber_oob_xfer_recv_denied(PurpleXfer *xfer) { |
| 8399 | 183 | jabber_oob_xfer_recv_error(xfer, "406"); |
| 184 | } | |
| 185 | ||
| 15884 | 186 | static void jabber_oob_xfer_recv_canceled(PurpleXfer *xfer) { |
| 8399 | 187 | jabber_oob_xfer_recv_error(xfer, "404"); |
| 188 | } | |
| 189 | ||
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
190 | void jabber_oob_parse(JabberStream *js, const char *from, JabberIqType type, |
|
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
191 | const char *id, xmlnode *querynode) { |
| 7170 | 192 | JabberOOBXfer *jox; |
| 15884 | 193 | PurpleXfer *xfer; |
| 7170 | 194 | char *filename; |
| 195 | char *url; | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
196 | xmlnode *urlnode; |
| 7170 | 197 | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
198 | if(type != JABBER_IQ_SET) |
| 14356 | 199 | return; |
| 200 | ||
|
25818
d087a2754595
Avoid assertion failures on NULL 'from' attributes
Paul Aurich <darkrain42@pidgin.im>
parents:
25817
diff
changeset
|
201 | if(!from) |
| 7170 | 202 | return; |
| 203 | ||
| 204 | if(!(urlnode = xmlnode_get_child(querynode, "url"))) | |
| 205 | return; | |
| 206 | ||
| 207 | url = xmlnode_get_data(urlnode); | |
| 208 | ||
| 209 | jox = g_new0(JabberOOBXfer, 1); | |
| 15884 | 210 | purple_url_parse(url, &jox->address, &jox->port, &jox->page, NULL, NULL); |
| 7170 | 211 | g_free(url); |
| 212 | jox->js = js; | |
| 213 | jox->headers = g_string_new(""); | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
214 | jox->iq_id = g_strdup(id); |
| 7170 | 215 | |
|
25817
09d6a40a341d
Pass IQ handlers type, from, id, and the child node
Paul Aurich <darkrain42@pidgin.im>
parents:
19859
diff
changeset
|
216 | xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from); |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
217 | if (xfer) |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
218 | { |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
219 | xfer->data = jox; |
| 7170 | 220 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
221 | if(!(filename = g_strdup(g_strrstr(jox->page, "/")))) |
|
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
222 | filename = g_strdup(jox->page); |
| 7170 | 223 | |
| 15884 | 224 | purple_xfer_set_filename(xfer, filename); |
| 7170 | 225 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
226 | g_free(filename); |
| 7170 | 227 | |
| 15884 | 228 | purple_xfer_set_init_fnc(xfer, jabber_oob_xfer_init); |
| 229 | purple_xfer_set_end_fnc(xfer, jabber_oob_xfer_end); | |
| 230 | purple_xfer_set_request_denied_fnc(xfer, jabber_oob_xfer_recv_denied); | |
| 231 | purple_xfer_set_cancel_recv_fnc(xfer, jabber_oob_xfer_recv_canceled); | |
| 232 | purple_xfer_set_read_fnc(xfer, jabber_oob_xfer_read); | |
| 233 | purple_xfer_set_start_fnc(xfer, jabber_oob_xfer_start); | |
| 7170 | 234 | |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
235 | js->oob_file_transfers = g_list_append(js->oob_file_transfers, xfer); |
| 7170 | 236 | |
| 15884 | 237 | purple_xfer_request(xfer); |
|
15345
797936e968ff
[gaim-migrate @ 18073]
Evan Schoenberg <evands@pidgin.im>
parents:
14697
diff
changeset
|
238 | } |
| 7170 | 239 | } |
| 240 | ||
| 241 |