Mercurial > pidgin
comparison libpurple/protocols/jabber/si.c @ 32819:2c6510167895 default tip
propagate from branch 'im.pidgin.pidgin.2.x.y' (head 3315c5dfbd0ad16511bdcf865e5b07c02d07df24)
to branch 'im.pidgin.pidgin' (head cbd1eda6bcbf0565ae7766396bb8f6f419cb6a9a)
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sat, 02 Jun 2012 02:30:49 +0000 |
parents | fb5b5f6cf111 |
children |
comparison
equal
deleted
inserted
replaced
32818:01ff09d4a463 | 32819:2c6510167895 |
---|---|
85 if(!sid || !from) | 85 if(!sid || !from) |
86 return NULL; | 86 return NULL; |
87 | 87 |
88 for(xfers = js->file_transfers; xfers; xfers = xfers->next) { | 88 for(xfers = js->file_transfers; xfers; xfers = xfers->next) { |
89 PurpleXfer *xfer = xfers->data; | 89 PurpleXfer *xfer = xfers->data; |
90 JabberSIXfer *jsx = xfer->data; | 90 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
91 if(jsx->stream_id && xfer->who && | 91 if(jsx->stream_id && purple_xfer_get_remote_user(xfer) && |
92 !strcmp(jsx->stream_id, sid) && !strcmp(xfer->who, from)) | 92 !strcmp(jsx->stream_id, sid) && !strcmp(purple_xfer_get_remote_user(xfer), from)) |
93 return xfer; | 93 return xfer; |
94 } | 94 } |
95 | 95 |
96 return NULL; | 96 return NULL; |
97 } | 97 } |
116 | 116 |
117 static void | 117 static void |
118 jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) | 118 jabber_si_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message) |
119 { | 119 { |
120 PurpleXfer *xfer = data; | 120 PurpleXfer *xfer = data; |
121 JabberSIXfer *jsx = xfer->data; | 121 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
122 JabberIq *iq; | 122 JabberIq *iq; |
123 xmlnode *query, *su; | 123 xmlnode *query, *su; |
124 JabberBytestreamsStreamhost *streamhost = jsx->streamhosts->data; | 124 JabberBytestreamsStreamhost *streamhost = jsx->streamhosts->data; |
125 | 125 |
126 purple_proxy_info_destroy(jsx->gpi); | 126 purple_proxy_info_destroy(jsx->gpi); |
141 jabber_si_bytestreams_attempt_connect(xfer); | 141 jabber_si_bytestreams_attempt_connect(xfer); |
142 return; | 142 return; |
143 } | 143 } |
144 | 144 |
145 /* unknown file transfer type is assumed to be RECEIVE */ | 145 /* unknown file transfer type is assumed to be RECEIVE */ |
146 if(xfer->type == PURPLE_XFER_SEND) | 146 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) |
147 { | 147 { |
148 xmlnode *activate; | 148 xmlnode *activate; |
149 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS); | 149 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS); |
150 xmlnode_set_attrib(iq->node, "to", streamhost->jid); | 150 xmlnode_set_attrib(iq->node, "to", streamhost->jid); |
151 query = xmlnode_get_child(iq->node, "query"); | 151 query = xmlnode_get_child(iq->node, "query"); |
152 xmlnode_set_attrib(query, "sid", jsx->stream_id); | 152 xmlnode_set_attrib(query, "sid", jsx->stream_id); |
153 activate = xmlnode_new_child(query, "activate"); | 153 activate = xmlnode_new_child(query, "activate"); |
154 xmlnode_insert_data(activate, xfer->who, -1); | 154 xmlnode_insert_data(activate, purple_xfer_get_remote_user(xfer), -1); |
155 | 155 |
156 /* TODO: We need to wait for an activation result before starting */ | 156 /* TODO: We need to wait for an activation result before starting */ |
157 } | 157 } |
158 else | 158 else |
159 { | 159 { |
160 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, NS_BYTESTREAMS); | 160 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_RESULT, NS_BYTESTREAMS); |
161 xmlnode_set_attrib(iq->node, "to", xfer->who); | 161 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
162 jabber_iq_set_id(iq, jsx->iq_id); | 162 jabber_iq_set_id(iq, jsx->iq_id); |
163 query = xmlnode_get_child(iq->node, "query"); | 163 query = xmlnode_get_child(iq->node, "query"); |
164 su = xmlnode_new_child(query, "streamhost-used"); | 164 su = xmlnode_new_child(query, "streamhost-used"); |
165 xmlnode_set_attrib(su, "jid", streamhost->jid); | 165 xmlnode_set_attrib(su, "jid", streamhost->jid); |
166 } | 166 } |
172 | 172 |
173 static gboolean | 173 static gboolean |
174 connect_timeout_cb(gpointer data) | 174 connect_timeout_cb(gpointer data) |
175 { | 175 { |
176 PurpleXfer *xfer = data; | 176 PurpleXfer *xfer = data; |
177 JabberSIXfer *jsx = xfer->data; | 177 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
178 | 178 |
179 purple_debug_info("jabber", "Streamhost connection timeout of %d seconds exceeded.\n", STREAMHOST_CONNECT_TIMEOUT); | 179 purple_debug_info("jabber", "Streamhost connection timeout of %d seconds exceeded.\n", STREAMHOST_CONNECT_TIMEOUT); |
180 | 180 |
181 jsx->connect_timeout = 0; | 181 jsx->connect_timeout = 0; |
182 | 182 |
201 | 201 |
202 static gboolean | 202 static gboolean |
203 jabber_si_bytestreams_ibb_timeout_cb(gpointer data) | 203 jabber_si_bytestreams_ibb_timeout_cb(gpointer data) |
204 { | 204 { |
205 PurpleXfer *xfer = (PurpleXfer *) data; | 205 PurpleXfer *xfer = (PurpleXfer *) data; |
206 JabberSIXfer *jsx = xfer->data; | 206 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
207 | 207 |
208 if (jsx && !jsx->ibb_session) { | 208 if (jsx && !jsx->ibb_session) { |
209 purple_debug_info("jabber", | 209 purple_debug_info("jabber", |
210 "jabber_si_bytestreams_ibb_timeout called and IBB session not set " | 210 "jabber_si_bytestreams_ibb_timeout called and IBB session not set " |
211 " up yet, cancel transfer"); | 211 " up yet, cancel transfer"); |
216 return FALSE; | 216 return FALSE; |
217 } | 217 } |
218 | 218 |
219 static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer) | 219 static void jabber_si_bytestreams_attempt_connect(PurpleXfer *xfer) |
220 { | 220 { |
221 JabberSIXfer *jsx = xfer->data; | 221 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
222 JabberBytestreamsStreamhost *streamhost; | 222 JabberBytestreamsStreamhost *streamhost; |
223 JabberID *dstjid; | 223 JabberID *dstjid; |
224 | 224 |
225 if(!jsx->streamhosts) { | 225 if(!jsx->streamhosts) { |
226 JabberIq *iq = jabber_iq_new(jsx->js, JABBER_IQ_ERROR); | 226 JabberIq *iq = jabber_iq_new(jsx->js, JABBER_IQ_ERROR); |
227 xmlnode *error, *inf; | 227 xmlnode *error, *inf; |
228 | 228 |
229 if(jsx->iq_id) | 229 if(jsx->iq_id) |
230 jabber_iq_set_id(iq, jsx->iq_id); | 230 jabber_iq_set_id(iq, jsx->iq_id); |
231 | 231 |
232 xmlnode_set_attrib(iq->node, "to", xfer->who); | 232 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
233 error = xmlnode_new_child(iq->node, "error"); | 233 error = xmlnode_new_child(iq->node, "error"); |
234 xmlnode_set_attrib(error, "code", "404"); | 234 xmlnode_set_attrib(error, "code", "404"); |
235 xmlnode_set_attrib(error, "type", "cancel"); | 235 xmlnode_set_attrib(error, "type", "cancel"); |
236 inf = xmlnode_new_child(error, "item-not-found"); | 236 inf = xmlnode_new_child(error, "item-not-found"); |
237 xmlnode_set_namespace(inf, NS_XMPP_STANZAS); | 237 xmlnode_set_namespace(inf, NS_XMPP_STANZAS); |
269 jsx->connect_data = NULL; | 269 jsx->connect_data = NULL; |
270 if (jsx->gpi != NULL) | 270 if (jsx->gpi != NULL) |
271 purple_proxy_info_destroy(jsx->gpi); | 271 purple_proxy_info_destroy(jsx->gpi); |
272 jsx->gpi = NULL; | 272 jsx->gpi = NULL; |
273 | 273 |
274 dstjid = jabber_id_new(xfer->who); | 274 dstjid = jabber_id_new(purple_xfer_get_remote_user(xfer)); |
275 | 275 |
276 /* TODO: Deal with zeroconf */ | 276 /* TODO: Deal with zeroconf */ |
277 | 277 |
278 if(dstjid != NULL && streamhost->host && streamhost->port > 0) { | 278 if(dstjid != NULL && streamhost->host && streamhost->port > 0) { |
279 char *dstaddr, *hash; | 279 char *dstaddr, *hash; |
282 purple_proxy_info_set_type(jsx->gpi, PURPLE_PROXY_SOCKS5); | 282 purple_proxy_info_set_type(jsx->gpi, PURPLE_PROXY_SOCKS5); |
283 purple_proxy_info_set_host(jsx->gpi, streamhost->host); | 283 purple_proxy_info_set_host(jsx->gpi, streamhost->host); |
284 purple_proxy_info_set_port(jsx->gpi, streamhost->port); | 284 purple_proxy_info_set_port(jsx->gpi, streamhost->port); |
285 | 285 |
286 /* unknown file transfer type is assumed to be RECEIVE */ | 286 /* unknown file transfer type is assumed to be RECEIVE */ |
287 if(xfer->type == PURPLE_XFER_SEND) | 287 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) |
288 dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, jsx->js->user->node, jsx->js->user->domain, | 288 dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, jsx->js->user->node, jsx->js->user->domain, |
289 jsx->js->user->resource, dstjid->node, dstjid->domain, dstjid->resource); | 289 jsx->js->user->resource, dstjid->node, dstjid->domain, dstjid->resource); |
290 else | 290 else |
291 dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, dstjid->node, dstjid->domain, dstjid->resource, | 291 dstaddr = g_strdup_printf("%s%s@%s/%s%s@%s/%s", jsx->stream_id, dstjid->node, dstjid->domain, dstjid->resource, |
292 jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource); | 292 jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource); |
300 jabber_si_bytestreams_connect_cb, xfer); | 300 jabber_si_bytestreams_connect_cb, xfer); |
301 g_free(hash); | 301 g_free(hash); |
302 g_free(dstaddr); | 302 g_free(dstaddr); |
303 | 303 |
304 /* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */ | 304 /* When selecting a streamhost, timeout after STREAMHOST_CONNECT_TIMEOUT seconds, otherwise it takes forever */ |
305 if (xfer->type != PURPLE_XFER_SEND && jsx->connect_data != NULL) | 305 if (purple_xfer_get_type(xfer) != PURPLE_XFER_SEND && jsx->connect_data != NULL) |
306 jsx->connect_timeout = purple_timeout_add_seconds( | 306 jsx->connect_timeout = purple_timeout_add_seconds( |
307 STREAMHOST_CONNECT_TIMEOUT, connect_timeout_cb, xfer); | 307 STREAMHOST_CONNECT_TIMEOUT, connect_timeout_cb, xfer); |
308 | 308 |
309 jabber_id_free(dstjid); | 309 jabber_id_free(dstjid); |
310 } | 310 } |
335 return; | 335 return; |
336 | 336 |
337 if(!(xfer = jabber_si_xfer_find(js, sid, from))) | 337 if(!(xfer = jabber_si_xfer_find(js, sid, from))) |
338 return; | 338 return; |
339 | 339 |
340 jsx = xfer->data; | 340 jsx = purple_xfer_get_protocol_data(xfer); |
341 | 341 |
342 if(!jsx->accepted) | 342 if(!jsx->accepted) |
343 return; | 343 return; |
344 | 344 |
345 if(jsx->iq_id) | 345 if(jsx->iq_id) |
373 static void | 373 static void |
374 jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source, | 374 jabber_si_xfer_bytestreams_send_read_again_resp_cb(gpointer data, gint source, |
375 PurpleInputCondition cond) | 375 PurpleInputCondition cond) |
376 { | 376 { |
377 PurpleXfer *xfer = data; | 377 PurpleXfer *xfer = data; |
378 JabberSIXfer *jsx = xfer->data; | 378 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
379 int len; | 379 int len; |
380 | 380 |
381 len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen); | 381 len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen); |
382 if (len < 0 && errno == EAGAIN) | 382 if (len < 0 && errno == EAGAIN) |
383 return; | 383 return; |
384 else if (len < 0) { | 384 else if (len < 0) { |
385 purple_input_remove(xfer->watcher); | |
386 xfer->watcher = 0; | |
387 g_free(jsx->rxqueue); | 385 g_free(jsx->rxqueue); |
388 jsx->rxqueue = NULL; | 386 jsx->rxqueue = NULL; |
389 close(source); | 387 close(source); |
390 purple_xfer_cancel_remote(xfer); | 388 purple_xfer_cancel_remote(xfer); |
391 return; | 389 return; |
393 jsx->rxlen += len; | 391 jsx->rxlen += len; |
394 | 392 |
395 if (jsx->rxlen < jsx->rxmaxlen) | 393 if (jsx->rxlen < jsx->rxmaxlen) |
396 return; | 394 return; |
397 | 395 |
398 purple_input_remove(xfer->watcher); | 396 purple_input_remove(purple_xfer_get_watcher(xfer)); |
399 xfer->watcher = 0; | 397 purple_xfer_set_watcher(xfer, 0); |
400 g_free(jsx->rxqueue); | 398 g_free(jsx->rxqueue); |
401 jsx->rxqueue = NULL; | 399 jsx->rxqueue = NULL; |
402 | 400 |
403 /* Before actually starting sending the file, we need to wait until the | 401 /* Before actually starting sending the file, we need to wait until the |
404 * recipient sends the IQ result with <streamhost-used/> | 402 * recipient sends the IQ result with <streamhost-used/> |
410 static void | 408 static void |
411 jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source, | 409 jabber_si_xfer_bytestreams_send_read_again_cb(gpointer data, gint source, |
412 PurpleInputCondition cond) | 410 PurpleInputCondition cond) |
413 { | 411 { |
414 PurpleXfer *xfer = data; | 412 PurpleXfer *xfer = data; |
415 JabberSIXfer *jsx = xfer->data; | 413 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
416 char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/ | 414 char buffer[42]; /* 40 for DST.ADDR + 2 bytes for port number*/ |
417 int len; | 415 int len; |
418 char *dstaddr, *hash; | 416 char *dstaddr, *hash; |
419 const char *host; | 417 const char *host; |
420 | 418 |
424 purple_debug_info("jabber", "reading the first 5 bytes\n"); | 422 purple_debug_info("jabber", "reading the first 5 bytes\n"); |
425 len = read(source, buffer, 5 - jsx->rxlen); | 423 len = read(source, buffer, 5 - jsx->rxlen); |
426 if(len < 0 && errno == EAGAIN) | 424 if(len < 0 && errno == EAGAIN) |
427 return; | 425 return; |
428 else if(len <= 0) { | 426 else if(len <= 0) { |
429 purple_input_remove(xfer->watcher); | |
430 xfer->watcher = 0; | |
431 close(source); | 427 close(source); |
432 purple_xfer_cancel_remote(xfer); | 428 purple_xfer_cancel_remote(xfer); |
433 return; | 429 return; |
434 } | 430 } |
435 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 431 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
439 } else if(jsx->rxqueue[0] != 0x05 || jsx->rxqueue[1] != 0x01 || | 435 } else if(jsx->rxqueue[0] != 0x05 || jsx->rxqueue[1] != 0x01 || |
440 jsx->rxqueue[3] != 0x03 || jsx->rxqueue[4] != 40) { | 436 jsx->rxqueue[3] != 0x03 || jsx->rxqueue[4] != 40) { |
441 purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n", | 437 purple_debug_info("jabber", "Invalid socks5 conn req. header[0x%x,0x%x,0x%x,0x%x,0x%x]\n", |
442 jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2], | 438 jsx->rxqueue[0], jsx->rxqueue[1], jsx->rxqueue[2], |
443 jsx->rxqueue[3], jsx->rxqueue[4]); | 439 jsx->rxqueue[3], jsx->rxqueue[4]); |
444 purple_input_remove(xfer->watcher); | |
445 xfer->watcher = 0; | |
446 close(source); | 440 close(source); |
447 purple_xfer_cancel_remote(xfer); | 441 purple_xfer_cancel_remote(xfer); |
448 return; | 442 return; |
449 } else if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) { | 443 } else if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) { |
450 /* Upper-bound of 257 (jsx->rxlen = 5, jsx->rxqueue[4] = 0xFF) */ | 444 /* Upper-bound of 257 (jsx->rxlen = 5, jsx->rxqueue[4] = 0xFF) */ |
453 jsx->rxqueue[4] + 2, to_read); | 447 jsx->rxqueue[4] + 2, to_read); |
454 len = read(source, buffer, to_read); | 448 len = read(source, buffer, to_read); |
455 if(len < 0 && errno == EAGAIN) | 449 if(len < 0 && errno == EAGAIN) |
456 return; | 450 return; |
457 else if(len <= 0) { | 451 else if(len <= 0) { |
458 purple_input_remove(xfer->watcher); | |
459 xfer->watcher = 0; | |
460 close(source); | 452 close(source); |
461 purple_xfer_cancel_remote(xfer); | 453 purple_xfer_cancel_remote(xfer); |
462 return; | 454 return; |
463 } | 455 } |
464 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 456 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
468 | 460 |
469 /* Have we not read all of DST.ADDR and the following 2-byte port number? */ | 461 /* Have we not read all of DST.ADDR and the following 2-byte port number? */ |
470 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) | 462 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) |
471 return; | 463 return; |
472 | 464 |
473 purple_input_remove(xfer->watcher); | 465 purple_input_remove(purple_xfer_get_watcher(xfer)); |
474 xfer->watcher = 0; | 466 purple_xfer_set_watcher(xfer, 0); |
475 | 467 |
476 dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id, | 468 dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id, |
477 jsx->js->user->node, jsx->js->user->domain, | 469 jsx->js->user->node, jsx->js->user->domain, |
478 jsx->js->user->resource, xfer->who); | 470 jsx->js->user->resource, purple_xfer_get_remote_user(xfer)); |
479 | 471 |
480 /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */ | 472 /* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */ |
481 hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1"); | 473 hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1"); |
482 | 474 |
483 if(strncmp(hash, jsx->rxqueue + 5, 40) || | 475 if(strncmp(hash, jsx->rxqueue + 5, 40) || |
514 jsx->rxqueue[4] = strlen(host); | 506 jsx->rxqueue[4] = strlen(host); |
515 memcpy(jsx->rxqueue + 5, host, strlen(host)); | 507 memcpy(jsx->rxqueue + 5, host, strlen(host)); |
516 jsx->rxqueue[5+strlen(host)] = 0x00; | 508 jsx->rxqueue[5+strlen(host)] = 0x00; |
517 jsx->rxqueue[6+strlen(host)] = 0x00; | 509 jsx->rxqueue[6+strlen(host)] = 0x00; |
518 | 510 |
519 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, | 511 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, |
520 jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer); | 512 jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer)); |
521 jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source, | 513 jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source, |
522 PURPLE_INPUT_WRITE); | 514 PURPLE_INPUT_WRITE); |
523 } | 515 } |
524 | 516 |
525 static void | 517 static void |
526 jabber_si_xfer_bytestreams_send_read_response_cb(gpointer data, gint source, | 518 jabber_si_xfer_bytestreams_send_read_response_cb(gpointer data, gint source, |
527 PurpleInputCondition cond) | 519 PurpleInputCondition cond) |
528 { | 520 { |
529 PurpleXfer *xfer = data; | 521 PurpleXfer *xfer = data; |
530 JabberSIXfer *jsx = xfer->data; | 522 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
531 int len; | 523 int len; |
532 | 524 |
533 len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen); | 525 len = write(source, jsx->rxqueue + jsx->rxlen, jsx->rxmaxlen - jsx->rxlen); |
534 if (len < 0 && errno == EAGAIN) | 526 if (len < 0 && errno == EAGAIN) |
535 return; | 527 return; |
536 else if (len < 0) { | 528 else if (len < 0) { |
537 purple_input_remove(xfer->watcher); | |
538 xfer->watcher = 0; | |
539 g_free(jsx->rxqueue); | 529 g_free(jsx->rxqueue); |
540 jsx->rxqueue = NULL; | 530 jsx->rxqueue = NULL; |
541 close(source); | 531 close(source); |
542 purple_xfer_cancel_remote(xfer); | 532 purple_xfer_cancel_remote(xfer); |
543 return; | 533 return; |
545 jsx->rxlen += len; | 535 jsx->rxlen += len; |
546 | 536 |
547 if (jsx->rxlen < jsx->rxmaxlen) | 537 if (jsx->rxlen < jsx->rxmaxlen) |
548 return; | 538 return; |
549 | 539 |
550 purple_input_remove(xfer->watcher); | |
551 xfer->watcher = 0; | |
552 | |
553 /* If we sent a "Success", wait for a response, otherwise give up and cancel */ | 540 /* If we sent a "Success", wait for a response, otherwise give up and cancel */ |
554 if (jsx->rxqueue[1] == 0x00) { | 541 if (jsx->rxqueue[1] == 0x00) { |
555 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ, | 542 purple_input_remove(purple_xfer_get_watcher(xfer)); |
556 jabber_si_xfer_bytestreams_send_read_again_cb, xfer); | 543 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_READ, |
544 jabber_si_xfer_bytestreams_send_read_again_cb, xfer)); | |
557 g_free(jsx->rxqueue); | 545 g_free(jsx->rxqueue); |
558 jsx->rxqueue = NULL; | 546 jsx->rxqueue = NULL; |
559 jsx->rxlen = 0; | 547 jsx->rxlen = 0; |
560 } else { | 548 } else { |
561 close(source); | 549 close(source); |
566 static void | 554 static void |
567 jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source, | 555 jabber_si_xfer_bytestreams_send_read_cb(gpointer data, gint source, |
568 PurpleInputCondition cond) | 556 PurpleInputCondition cond) |
569 { | 557 { |
570 PurpleXfer *xfer = data; | 558 PurpleXfer *xfer = data; |
571 JabberSIXfer *jsx = xfer->data; | 559 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
572 int i; | 560 int i; |
573 int len; | 561 int len; |
574 char buffer[256]; | 562 char buffer[256]; |
575 | 563 |
576 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n"); | 564 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n"); |
577 | 565 |
578 xfer->fd = source; | 566 purple_xfer_set_fd(xfer, source); |
579 | 567 |
580 /** Try to read the SOCKS5 header */ | 568 /** Try to read the SOCKS5 header */ |
581 if(jsx->rxlen < 2) { | 569 if(jsx->rxlen < 2) { |
582 purple_debug_info("jabber", "reading those first two bytes\n"); | 570 purple_debug_info("jabber", "reading those first two bytes\n"); |
583 len = read(source, buffer, 2 - jsx->rxlen); | 571 len = read(source, buffer, 2 - jsx->rxlen); |
584 if(len < 0 && errno == EAGAIN) | 572 if(len < 0 && errno == EAGAIN) |
585 return; | 573 return; |
586 else if(len <= 0) { | 574 else if(len <= 0) { |
587 purple_input_remove(xfer->watcher); | |
588 xfer->watcher = 0; | |
589 close(source); | |
590 purple_xfer_cancel_remote(xfer); | 575 purple_xfer_cancel_remote(xfer); |
591 return; | 576 return; |
592 } | 577 } |
593 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 578 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
594 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 579 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
601 jsx->rxqueue[1], to_read); | 586 jsx->rxqueue[1], to_read); |
602 len = read(source, buffer, to_read); | 587 len = read(source, buffer, to_read); |
603 if(len < 0 && errno == EAGAIN) | 588 if(len < 0 && errno == EAGAIN) |
604 return; | 589 return; |
605 else if(len <= 0) { | 590 else if(len <= 0) { |
606 purple_input_remove(xfer->watcher); | |
607 xfer->watcher = 0; | |
608 close(source); | |
609 purple_xfer_cancel_remote(xfer); | 591 purple_xfer_cancel_remote(xfer); |
610 return; | 592 return; |
611 } | 593 } |
612 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); | 594 jsx->rxqueue = g_realloc(jsx->rxqueue, len + jsx->rxlen); |
613 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); | 595 memcpy(jsx->rxqueue + jsx->rxlen, buffer, len); |
616 | 598 |
617 /* Have we not read all the auth. method bytes? */ | 599 /* Have we not read all the auth. method bytes? */ |
618 if(jsx->rxlen -2 < jsx->rxqueue[1]) | 600 if(jsx->rxlen -2 < jsx->rxqueue[1]) |
619 return; | 601 return; |
620 | 602 |
621 purple_input_remove(xfer->watcher); | |
622 xfer->watcher = 0; | |
623 | |
624 purple_debug_info("jabber", "checking to make sure we're socks FIVE\n"); | 603 purple_debug_info("jabber", "checking to make sure we're socks FIVE\n"); |
625 | 604 |
626 if(jsx->rxqueue[0] != 0x05) { | 605 if(jsx->rxqueue[0] != 0x05) { |
627 close(source); | |
628 purple_xfer_cancel_remote(xfer); | 606 purple_xfer_cancel_remote(xfer); |
629 return; | 607 return; |
630 } | 608 } |
631 | 609 |
632 purple_debug_info("jabber", "going to test %hhu different methods\n", jsx->rxqueue[1]); | 610 purple_debug_info("jabber", "going to test %hhu different methods\n", jsx->rxqueue[1]); |
639 jsx->rxlen = 0; | 617 jsx->rxlen = 0; |
640 jsx->rxmaxlen = 2; | 618 jsx->rxmaxlen = 2; |
641 jsx->rxqueue = g_malloc(jsx->rxmaxlen); | 619 jsx->rxqueue = g_malloc(jsx->rxmaxlen); |
642 jsx->rxqueue[0] = 0x05; | 620 jsx->rxqueue[0] = 0x05; |
643 jsx->rxqueue[1] = 0x00; | 621 jsx->rxqueue[1] = 0x00; |
644 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, | 622 purple_input_remove(purple_xfer_get_watcher(xfer)); |
623 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, | |
645 jabber_si_xfer_bytestreams_send_read_response_cb, | 624 jabber_si_xfer_bytestreams_send_read_response_cb, |
646 xfer); | 625 xfer)); |
647 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, | 626 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, |
648 source, PURPLE_INPUT_WRITE); | 627 source, PURPLE_INPUT_WRITE); |
649 jsx->rxqueue = NULL; | 628 jsx->rxqueue = NULL; |
650 jsx->rxlen = 0; | 629 jsx->rxlen = 0; |
651 return; | 630 return; |
656 jsx->rxlen = 0; | 635 jsx->rxlen = 0; |
657 jsx->rxmaxlen = 2; | 636 jsx->rxmaxlen = 2; |
658 jsx->rxqueue = g_malloc(jsx->rxmaxlen); | 637 jsx->rxqueue = g_malloc(jsx->rxmaxlen); |
659 jsx->rxqueue[0] = 0x05; | 638 jsx->rxqueue[0] = 0x05; |
660 jsx->rxqueue[1] = 0xFF; | 639 jsx->rxqueue[1] = 0xFF; |
661 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, | 640 purple_input_remove(purple_xfer_get_watcher(xfer)); |
662 jabber_si_xfer_bytestreams_send_read_response_cb, xfer); | 641 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE, |
642 jabber_si_xfer_bytestreams_send_read_response_cb, xfer)); | |
663 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, | 643 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, |
664 source, PURPLE_INPUT_WRITE); | 644 source, PURPLE_INPUT_WRITE); |
665 } | 645 } |
666 | 646 |
667 static gint | 647 static gint |
678 static void | 658 static void |
679 jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source, | 659 jabber_si_xfer_bytestreams_send_connected_cb(gpointer data, gint source, |
680 PurpleInputCondition cond) | 660 PurpleInputCondition cond) |
681 { | 661 { |
682 PurpleXfer *xfer = data; | 662 PurpleXfer *xfer = data; |
683 JabberSIXfer *jsx = xfer->data; | 663 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
684 int acceptfd, flags; | 664 int acceptfd, flags; |
685 | 665 |
686 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n"); | 666 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_connected_cb\n"); |
687 | 667 |
688 acceptfd = accept(source, NULL, 0); | 668 acceptfd = accept(source, NULL, 0); |
692 purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno)); | 672 purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno)); |
693 /* Don't cancel the ft - allow it to fall to the next streamhost.*/ | 673 /* Don't cancel the ft - allow it to fall to the next streamhost.*/ |
694 return; | 674 return; |
695 } | 675 } |
696 | 676 |
697 purple_input_remove(xfer->watcher); | 677 purple_input_remove(purple_xfer_get_watcher(xfer)); |
698 close(source); | 678 close(source); |
699 jsx->local_streamhost_fd = -1; | 679 jsx->local_streamhost_fd = -1; |
700 | 680 |
701 flags = fcntl(acceptfd, F_GETFL); | 681 flags = fcntl(acceptfd, F_GETFL); |
702 fcntl(acceptfd, F_SETFL, flags | O_NONBLOCK); | 682 fcntl(acceptfd, F_SETFL, flags | O_NONBLOCK); |
703 #ifndef _WIN32 | 683 #ifndef _WIN32 |
704 fcntl(acceptfd, F_SETFD, FD_CLOEXEC); | 684 fcntl(acceptfd, F_SETFD, FD_CLOEXEC); |
705 #endif | 685 #endif |
706 | 686 |
707 xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ, | 687 purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ, |
708 jabber_si_xfer_bytestreams_send_read_cb, xfer); | 688 jabber_si_xfer_bytestreams_send_read_cb, xfer)); |
709 } | 689 } |
710 | 690 |
711 static void | 691 static void |
712 jabber_si_connect_proxy_cb(JabberStream *js, const char *from, | 692 jabber_si_connect_proxy_cb(JabberStream *js, const char *from, |
713 JabberIqType type, const char *id, | 693 JabberIqType type, const char *id, |
725 if (!g_list_find(js->file_transfers, xfer)) { | 705 if (!g_list_find(js->file_transfers, xfer)) { |
726 purple_debug_error("jabber", "Got bytestreams response for no longer existing xfer (%p)\n", xfer); | 706 purple_debug_error("jabber", "Got bytestreams response for no longer existing xfer (%p)\n", xfer); |
727 return; | 707 return; |
728 } | 708 } |
729 | 709 |
710 jsx = purple_xfer_get_protocol_data(xfer); | |
711 | |
730 /* In the case of a direct file transfer, this is expected to return */ | 712 /* In the case of a direct file transfer, this is expected to return */ |
731 if(!xfer->data) | 713 if(!jsx) |
732 return; | 714 return; |
733 | |
734 jsx = xfer->data; | |
735 | 715 |
736 if(type != JABBER_IQ_RESULT) { | 716 if(type != JABBER_IQ_RESULT) { |
737 purple_debug_info("jabber", | 717 purple_debug_info("jabber", |
738 "jabber_si_xfer_connect_proxy_cb: type = error\n"); | 718 "jabber_si_xfer_connect_proxy_cb: type = error\n"); |
739 /* if IBB is available, open IBB session */ | 719 /* if IBB is available, open IBB session */ |
779 { | 759 { |
780 gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, | 760 gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, |
781 jsx->js->user->domain, jsx->js->user->resource); | 761 jsx->js->user->domain, jsx->js->user->resource); |
782 if (!strcmp(jid, my_jid)) { | 762 if (!strcmp(jid, my_jid)) { |
783 purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n"); | 763 purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n"); |
784 purple_xfer_start(xfer, xfer->fd, NULL, -1); | 764 purple_xfer_start(xfer, purple_xfer_get_fd(xfer), NULL, -1); |
785 } else { | 765 } else { |
786 /* if available, try to revert to IBB... */ | 766 /* if available, try to revert to IBB... */ |
787 if (jsx->stream_method & STREAM_METHOD_IBB) { | 767 if (jsx->stream_method & STREAM_METHOD_IBB) { |
788 purple_debug_info("jabber", | 768 purple_debug_info("jabber", |
789 "jabber_si_connect_proxy_cb: trying to revert to IBB\n"); | 769 "jabber_si_connect_proxy_cb: trying to revert to IBB\n"); |
803 g_free(my_jid); | 783 g_free(my_jid); |
804 return; | 784 return; |
805 } | 785 } |
806 | 786 |
807 /* Clean up the local streamhost - it isn't going to be used.*/ | 787 /* Clean up the local streamhost - it isn't going to be used.*/ |
808 if (xfer->watcher > 0) { | 788 if (purple_xfer_get_watcher(xfer) > 0) { |
809 purple_input_remove(xfer->watcher); | 789 purple_input_remove(purple_xfer_get_watcher(xfer)); |
810 xfer->watcher = 0; | 790 purple_xfer_set_watcher(xfer, 0); |
811 } | 791 } |
812 if (jsx->local_streamhost_fd >= 0) { | 792 if (jsx->local_streamhost_fd >= 0) { |
813 close(jsx->local_streamhost_fd); | 793 close(jsx->local_streamhost_fd); |
814 jsx->local_streamhost_fd = -1; | 794 jsx->local_streamhost_fd = -1; |
815 } | 795 } |
833 char port[6]; | 813 char port[6]; |
834 GList *tmp; | 814 GList *tmp; |
835 JabberBytestreamsStreamhost *sh, *sh2; | 815 JabberBytestreamsStreamhost *sh, *sh2; |
836 int streamhost_count = 0; | 816 int streamhost_count = 0; |
837 | 817 |
838 jsx = xfer->data; | 818 jsx = purple_xfer_get_protocol_data(xfer); |
839 jsx->listen_data = NULL; | 819 jsx->listen_data = NULL; |
840 | 820 |
841 /* I'm not sure under which conditions this can happen | 821 /* I'm not sure under which conditions this can happen |
842 * (it seems like it shouldn't be possible */ | 822 * (it seems like it shouldn't be possible */ |
843 if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) { | 823 if (purple_xfer_get_status(xfer) == PURPLE_XFER_STATUS_CANCEL_LOCAL) { |
846 } | 826 } |
847 | 827 |
848 purple_xfer_unref(xfer); | 828 purple_xfer_unref(xfer); |
849 | 829 |
850 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS); | 830 iq = jabber_iq_new_query(jsx->js, JABBER_IQ_SET, NS_BYTESTREAMS); |
851 xmlnode_set_attrib(iq->node, "to", xfer->who); | 831 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
852 query = xmlnode_get_child(iq->node, "query"); | 832 query = xmlnode_get_child(iq->node, "query"); |
853 | 833 |
854 xmlnode_set_attrib(query, "sid", jsx->stream_id); | 834 xmlnode_set_attrib(query, "sid", jsx->stream_id); |
855 | 835 |
856 /* If we successfully started listening locally */ | 836 /* If we successfully started listening locally */ |
863 | 843 |
864 jsx->local_streamhost_fd = sock; | 844 jsx->local_streamhost_fd = sock; |
865 | 845 |
866 jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, | 846 jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, |
867 jsx->js->user->domain, jsx->js->user->resource); | 847 jsx->js->user->domain, jsx->js->user->resource); |
868 xfer->local_port = purple_network_get_port_from_fd(sock); | 848 purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock)); |
869 g_snprintf(port, sizeof(port), "%hu", xfer->local_port); | 849 g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer)); |
870 | 850 |
871 public_ip = purple_network_get_my_ip(jsx->js->fd); | 851 public_ip = purple_network_get_my_ip(jsx->js->fd); |
872 | 852 |
873 /* Include the localhost's IPs (for in-network transfers) */ | 853 /* Include the localhost's IPs (for in-network transfers) */ |
874 while (local_ips) { | 854 while (local_ips) { |
894 } | 874 } |
895 | 875 |
896 g_free(jid); | 876 g_free(jid); |
897 | 877 |
898 /* The listener for the local proxy */ | 878 /* The listener for the local proxy */ |
899 xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ, | 879 purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ, |
900 jabber_si_xfer_bytestreams_send_connected_cb, xfer); | 880 jabber_si_xfer_bytestreams_send_connected_cb, xfer)); |
901 } | 881 } |
902 | 882 |
903 for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) { | 883 for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) { |
904 sh = tmp->data; | 884 sh = tmp->data; |
905 | 885 |
967 JabberSIXfer *jsx; | 947 JabberSIXfer *jsx; |
968 PurpleProxyType proxy_type; | 948 PurpleProxyType proxy_type; |
969 | 949 |
970 purple_xfer_ref(xfer); | 950 purple_xfer_ref(xfer); |
971 | 951 |
972 jsx = xfer->data; | 952 jsx = purple_xfer_get_protocol_data(xfer); |
973 | 953 |
974 /* TODO: This should probably be done with an account option instead of | 954 /* TODO: This should probably be done with an account option instead of |
975 * piggy-backing on the TOR proxy type. */ | 955 * piggy-backing on the TOR proxy type. */ |
976 proxy_type = purple_proxy_info_get_type( | 956 proxy_type = purple_proxy_info_get_type( |
977 purple_proxy_get_setup(purple_connection_get_account(jsx->js->gc))); | 957 purple_proxy_get_setup(purple_connection_get_account(jsx->js->gc))); |
978 if (proxy_type == PURPLE_PROXY_TOR) { | 958 if (proxy_type == PURPLE_PROXY_TOR) { |
979 purple_debug_info("jabber", "Skipping attempting local streamhost.\n"); | 959 purple_debug_info("jabber", "Skipping attempting local streamhost.\n"); |
980 jsx->listen_data = NULL; | 960 jsx->listen_data = NULL; |
981 } else | 961 } else |
982 jsx->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM, | 962 jsx->listen_data = purple_network_listen_range(0, 0, AF_UNSPEC, SOCK_STREAM, TRUE, |
983 jabber_si_xfer_bytestreams_listen_cb, xfer); | 963 jabber_si_xfer_bytestreams_listen_cb, xfer); |
984 | 964 |
985 if (jsx->listen_data == NULL) { | 965 if (jsx->listen_data == NULL) { |
986 /* We couldn't open a local port. Perhaps we can use a proxy. */ | 966 /* We couldn't open a local port. Perhaps we can use a proxy. */ |
987 jabber_si_xfer_bytestreams_listen_cb(-1, xfer); | 967 jabber_si_xfer_bytestreams_listen_cb(-1, xfer); |
1015 static void | 995 static void |
1016 jabber_si_xfer_ibb_recv_data_cb(JabberIBBSession *sess, gpointer data, | 996 jabber_si_xfer_ibb_recv_data_cb(JabberIBBSession *sess, gpointer data, |
1017 gsize size) | 997 gsize size) |
1018 { | 998 { |
1019 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); | 999 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); |
1020 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1000 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1021 | 1001 |
1022 if (size <= purple_xfer_get_bytes_remaining(xfer)) { | 1002 if (size <= purple_xfer_get_bytes_remaining(xfer)) { |
1023 purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n", | 1003 purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n", |
1024 size); | 1004 size); |
1025 purple_circ_buffer_append(jsx->ibb_buffer, data, size); | 1005 purple_circ_buffer_append(jsx->ibb_buffer, data, size); |
1035 } | 1015 } |
1036 | 1016 |
1037 static gssize | 1017 static gssize |
1038 jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer) | 1018 jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer) |
1039 { | 1019 { |
1040 JabberSIXfer *jsx = xfer->data; | 1020 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1041 guchar *buffer; | 1021 guchar *buffer; |
1042 gsize size; | 1022 gsize size; |
1043 gsize tmp; | 1023 gsize tmp; |
1044 | 1024 |
1045 size = jsx->ibb_buffer->bufused; | 1025 size = jsx->ibb_buffer->bufused; |
1058 xmlnode *open) | 1038 xmlnode *open) |
1059 { | 1039 { |
1060 const gchar *sid = xmlnode_get_attrib(open, "sid"); | 1040 const gchar *sid = xmlnode_get_attrib(open, "sid"); |
1061 PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who); | 1041 PurpleXfer *xfer = jabber_si_xfer_find(js, sid, who); |
1062 if (xfer) { | 1042 if (xfer) { |
1063 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1043 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1064 JabberIBBSession *sess = | 1044 JabberIBBSession *sess = |
1065 jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer); | 1045 jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer); |
1066 | 1046 |
1067 jabber_si_bytestreams_ibb_timeout_remove(jsx); | 1047 jabber_si_bytestreams_ibb_timeout_remove(jsx); |
1068 | 1048 |
1103 } | 1083 } |
1104 | 1084 |
1105 static gssize | 1085 static gssize |
1106 jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer) | 1086 jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer) |
1107 { | 1087 { |
1108 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1088 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1109 JabberIBBSession *sess = jsx->ibb_session; | 1089 JabberIBBSession *sess = jsx->ibb_session; |
1110 gsize packet_size = len < jabber_ibb_session_get_max_data_size(sess) ? | 1090 gsize packet_size = len < jabber_ibb_session_get_max_data_size(sess) ? |
1111 len : jabber_ibb_session_get_max_data_size(sess); | 1091 len : jabber_ibb_session_get_max_data_size(sess); |
1112 | 1092 |
1113 jabber_ibb_session_send_data(sess, buffer, packet_size); | 1093 jabber_ibb_session_send_data(sess, buffer, packet_size); |
1117 | 1097 |
1118 static void | 1098 static void |
1119 jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess) | 1099 jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess) |
1120 { | 1100 { |
1121 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); | 1101 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); |
1122 gsize remaining = purple_xfer_get_bytes_remaining(xfer); | 1102 goffset remaining = purple_xfer_get_bytes_remaining(xfer); |
1123 | 1103 |
1124 if (remaining == 0) { | 1104 if (remaining == 0) { |
1125 /* close the session */ | 1105 /* close the session */ |
1126 jabber_ibb_session_close(sess); | 1106 jabber_ibb_session_close(sess); |
1127 purple_xfer_set_completed(xfer, TRUE); | 1107 purple_xfer_set_completed(xfer, TRUE); |
1147 } | 1127 } |
1148 | 1128 |
1149 static void | 1129 static void |
1150 jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer) | 1130 jabber_si_xfer_ibb_send_init(JabberStream *js, PurpleXfer *xfer) |
1151 { | 1131 { |
1152 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1132 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1153 | 1133 |
1154 jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id, | 1134 jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id, |
1155 purple_xfer_get_remote_user(xfer), xfer); | 1135 purple_xfer_get_remote_user(xfer), xfer); |
1156 | 1136 |
1157 if (jsx->ibb_session) { | 1137 if (jsx->ibb_session) { |
1204 return; | 1184 return; |
1205 } | 1185 } |
1206 | 1186 |
1207 for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) { | 1187 for(field = xmlnode_get_child(x, "field"); field; field = xmlnode_get_next_twin(field)) { |
1208 const char *var = xmlnode_get_attrib(field, "var"); | 1188 const char *var = xmlnode_get_attrib(field, "var"); |
1209 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1189 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1210 | 1190 |
1211 if(var && !strcmp(var, "stream-method")) { | 1191 if(var && !strcmp(var, "stream-method")) { |
1212 if((value = xmlnode_get_child(field, "value"))) { | 1192 if((value = xmlnode_get_child(field, "value"))) { |
1213 char *val = xmlnode_get_data(value); | 1193 char *val = xmlnode_get_data(value); |
1214 if(val && !strcmp(val, NS_BYTESTREAMS)) { | 1194 if(val && !strcmp(val, NS_BYTESTREAMS)) { |
1235 | 1215 |
1236 } | 1216 } |
1237 | 1217 |
1238 static void jabber_si_xfer_send_request(PurpleXfer *xfer) | 1218 static void jabber_si_xfer_send_request(PurpleXfer *xfer) |
1239 { | 1219 { |
1240 JabberSIXfer *jsx = xfer->data; | 1220 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1241 JabberIq *iq; | 1221 JabberIq *iq; |
1242 xmlnode *si, *file, *feature, *x, *field, *option, *value; | 1222 xmlnode *si, *file, *feature, *x, *field, *option, *value; |
1243 char buf[32]; | 1223 char buf[32]; |
1244 #if ENABLE_FT_THUMBNAILS | 1224 #if ENABLE_FT_THUMBNAILS |
1245 gconstpointer thumb; | 1225 gconstpointer thumb; |
1246 gsize thumb_size; | 1226 gsize thumb_size; |
1247 | 1227 |
1248 purple_xfer_prepare_thumbnail(xfer, "jpeg,png"); | 1228 purple_xfer_prepare_thumbnail(xfer, "jpeg,png"); |
1249 #endif | 1229 #endif |
1250 xfer->filename = g_path_get_basename(xfer->local_filename); | 1230 purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer))); |
1251 | 1231 |
1252 iq = jabber_iq_new(jsx->js, JABBER_IQ_SET); | 1232 iq = jabber_iq_new(jsx->js, JABBER_IQ_SET); |
1253 xmlnode_set_attrib(iq->node, "to", xfer->who); | 1233 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
1254 si = xmlnode_new_child(iq->node, "si"); | 1234 si = xmlnode_new_child(iq->node, "si"); |
1255 xmlnode_set_namespace(si, "http://jabber.org/protocol/si"); | 1235 xmlnode_set_namespace(si, "http://jabber.org/protocol/si"); |
1256 jsx->stream_id = jabber_get_next_id(jsx->js); | 1236 jsx->stream_id = jabber_get_next_id(jsx->js); |
1257 xmlnode_set_attrib(si, "id", jsx->stream_id); | 1237 xmlnode_set_attrib(si, "id", jsx->stream_id); |
1258 xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER); | 1238 xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER); |
1259 | 1239 |
1260 file = xmlnode_new_child(si, "file"); | 1240 file = xmlnode_new_child(si, "file"); |
1261 xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER); | 1241 xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER); |
1262 xmlnode_set_attrib(file, "name", xfer->filename); | 1242 xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer)); |
1263 g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, xfer->size); | 1243 g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer)); |
1264 xmlnode_set_attrib(file, "size", buf); | 1244 xmlnode_set_attrib(file, "size", buf); |
1265 /* maybe later we'll do hash and date attribs */ | 1245 /* maybe later we'll do hash and date attribs */ |
1266 | 1246 |
1267 #if ENABLE_FT_THUMBNAILS | 1247 #if ENABLE_FT_THUMBNAILS |
1268 /* add thumbnail, if appropriate */ | 1248 /* add thumbnail, if appropriate */ |
1307 jabber_iq_send(iq); | 1287 jabber_iq_send(iq); |
1308 } | 1288 } |
1309 | 1289 |
1310 static void jabber_si_xfer_free(PurpleXfer *xfer) | 1290 static void jabber_si_xfer_free(PurpleXfer *xfer) |
1311 { | 1291 { |
1312 JabberSIXfer *jsx = xfer->data; | 1292 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1313 | 1293 |
1314 if (jsx) { | 1294 if (jsx) { |
1315 JabberStream *js = jsx->js; | 1295 JabberStream *js = jsx->js; |
1316 | 1296 |
1317 js->file_transfers = g_list_remove(js->file_transfers, xfer); | 1297 js->file_transfers = g_list_remove(js->file_transfers, xfer); |
1322 purple_network_listen_cancel(jsx->listen_data); | 1302 purple_network_listen_cancel(jsx->listen_data); |
1323 if (jsx->iq_id != NULL) | 1303 if (jsx->iq_id != NULL) |
1324 jabber_iq_remove_callback_by_id(js, jsx->iq_id); | 1304 jabber_iq_remove_callback_by_id(js, jsx->iq_id); |
1325 if (jsx->local_streamhost_fd >= 0) | 1305 if (jsx->local_streamhost_fd >= 0) |
1326 close(jsx->local_streamhost_fd); | 1306 close(jsx->local_streamhost_fd); |
1327 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && | 1307 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && purple_xfer_get_fd(xfer) >= 0) { |
1328 xfer->fd >= 0) { | |
1329 purple_debug_info("jabber", "remove port mapping\n"); | 1308 purple_debug_info("jabber", "remove port mapping\n"); |
1330 purple_network_remove_port_mapping(xfer->fd); | 1309 purple_network_remove_port_mapping(purple_xfer_get_fd(xfer)); |
1331 } | 1310 } |
1332 if (jsx->connect_timeout > 0) | 1311 if (jsx->connect_timeout > 0) |
1333 purple_timeout_remove(jsx->connect_timeout); | 1312 purple_timeout_remove(jsx->connect_timeout); |
1334 if (jsx->ibb_timeout_handle > 0) | 1313 if (jsx->ibb_timeout_handle > 0) |
1335 purple_timeout_remove(jsx->ibb_timeout_handle); | 1314 purple_timeout_remove(jsx->ibb_timeout_handle); |
1354 g_free(jsx->stream_id); | 1333 g_free(jsx->stream_id); |
1355 g_free(jsx->iq_id); | 1334 g_free(jsx->iq_id); |
1356 /* XXX: free other stuff */ | 1335 /* XXX: free other stuff */ |
1357 g_free(jsx->rxqueue); | 1336 g_free(jsx->rxqueue); |
1358 g_free(jsx); | 1337 g_free(jsx); |
1359 xfer->data = NULL; | 1338 purple_xfer_set_protocol_data(xfer, NULL); |
1360 } | 1339 } |
1361 } | 1340 } |
1362 | 1341 |
1363 /* | 1342 /* |
1364 * These four functions should only be called from the PurpleXfer functions | 1343 * These four functions should only be called from the PurpleXfer functions |
1365 * (typically purple_xfer_cancel_(remote|local), purple_xfer_end, or | 1344 * (typically purple_xfer_cancel_(remote|local), purple_xfer_end, or |
1366 * purple_xfer_request_denied. | 1345 * purple_xfer_request_denied. |
1367 */ | 1346 */ |
1368 static void jabber_si_xfer_cancel_send(PurpleXfer *xfer) | 1347 static void jabber_si_xfer_cancel_send(PurpleXfer *xfer) |
1369 { | 1348 { |
1370 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1349 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1371 | 1350 |
1372 /* if there is an IBB session active, send close on that */ | 1351 /* if there is an IBB session active, send close on that */ |
1373 if (jsx->ibb_session) { | 1352 if (jsx->ibb_session) { |
1374 jabber_ibb_session_close(jsx->ibb_session); | 1353 jabber_ibb_session_close(jsx->ibb_session); |
1375 } | 1354 } |
1378 } | 1357 } |
1379 | 1358 |
1380 | 1359 |
1381 static void jabber_si_xfer_request_denied(PurpleXfer *xfer) | 1360 static void jabber_si_xfer_request_denied(PurpleXfer *xfer) |
1382 { | 1361 { |
1383 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1362 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1384 JabberStream *js = jsx->js; | 1363 JabberStream *js = jsx->js; |
1385 | 1364 |
1386 /* | 1365 /* |
1387 * TODO: It's probably an error if jsx->iq_id == NULL. g_return_if_fail | 1366 * TODO: It's probably an error if jsx->iq_id == NULL. g_return_if_fail |
1388 * might be warranted. | 1367 * might be warranted. |
1389 */ | 1368 */ |
1390 if (jsx->iq_id && !jsx->accepted) { | 1369 if (jsx->iq_id && !jsx->accepted) { |
1391 JabberIq *iq; | 1370 JabberIq *iq; |
1392 xmlnode *error, *child; | 1371 xmlnode *error, *child; |
1393 iq = jabber_iq_new(js, JABBER_IQ_ERROR); | 1372 iq = jabber_iq_new(js, JABBER_IQ_ERROR); |
1394 xmlnode_set_attrib(iq->node, "to", xfer->who); | 1373 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
1395 jabber_iq_set_id(iq, jsx->iq_id); | 1374 jabber_iq_set_id(iq, jsx->iq_id); |
1396 | 1375 |
1397 error = xmlnode_new_child(iq->node, "error"); | 1376 error = xmlnode_new_child(iq->node, "error"); |
1398 xmlnode_set_attrib(error, "type", "cancel"); | 1377 xmlnode_set_attrib(error, "type", "cancel"); |
1399 child = xmlnode_new_child(error, "forbidden"); | 1378 child = xmlnode_new_child(error, "forbidden"); |
1410 } | 1389 } |
1411 | 1390 |
1412 | 1391 |
1413 static void jabber_si_xfer_cancel_recv(PurpleXfer *xfer) | 1392 static void jabber_si_xfer_cancel_recv(PurpleXfer *xfer) |
1414 { | 1393 { |
1415 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1394 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1416 /* if there is an IBB session active, send close */ | 1395 /* if there is an IBB session active, send close */ |
1417 if (jsx->ibb_session) { | 1396 if (jsx->ibb_session) { |
1418 jabber_ibb_session_close(jsx->ibb_session); | 1397 jabber_ibb_session_close(jsx->ibb_session); |
1419 } | 1398 } |
1420 jabber_si_xfer_free(xfer); | 1399 jabber_si_xfer_free(xfer); |
1430 | 1409 |
1431 static void jabber_si_xfer_send_disco_cb(JabberStream *js, const char *who, | 1410 static void jabber_si_xfer_send_disco_cb(JabberStream *js, const char *who, |
1432 JabberCapabilities capabilities, gpointer data) | 1411 JabberCapabilities capabilities, gpointer data) |
1433 { | 1412 { |
1434 PurpleXfer *xfer = (PurpleXfer *) data; | 1413 PurpleXfer *xfer = (PurpleXfer *) data; |
1435 JabberSIXfer *jsx = (JabberSIXfer *) xfer->data; | 1414 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1436 | 1415 |
1437 if (capabilities & JABBER_CAP_IBB) { | 1416 if (capabilities & JABBER_CAP_IBB) { |
1438 purple_debug_info("jabber", | 1417 purple_debug_info("jabber", |
1439 "jabber_si_xfer_send_disco_cb: remote JID supports IBB\n"); | 1418 "jabber_si_xfer_send_disco_cb: remote JID supports IBB\n"); |
1440 jsx->stream_method |= STREAM_METHOD_IBB; | 1419 jsx->stream_method |= STREAM_METHOD_IBB; |
1456 purple_xfer_cancel_local(xfer); | 1435 purple_xfer_cancel_local(xfer); |
1457 } | 1436 } |
1458 | 1437 |
1459 static void do_transfer_send(PurpleXfer *xfer, const char *resource) | 1438 static void do_transfer_send(PurpleXfer *xfer, const char *resource) |
1460 { | 1439 { |
1461 JabberSIXfer *jsx = xfer->data; | 1440 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1462 char **who_v = g_strsplit(xfer->who, "/", 2); | 1441 char **who_v = g_strsplit(purple_xfer_get_remote_user(xfer), "/", 2); |
1463 char *who; | 1442 char *who; |
1464 JabberBuddy *jb; | 1443 JabberBuddy *jb; |
1465 JabberBuddyResource *jbr = NULL; | 1444 JabberBuddyResource *jbr = NULL; |
1466 | 1445 |
1467 jb = jabber_buddy_find(jsx->js, who_v[0], FALSE); | 1446 jb = jabber_buddy_find(jsx->js, who_v[0], FALSE); |
1506 do_transfer_send(xfer, selected_label); | 1485 do_transfer_send(xfer, selected_label); |
1507 } | 1486 } |
1508 | 1487 |
1509 static void jabber_si_xfer_init(PurpleXfer *xfer) | 1488 static void jabber_si_xfer_init(PurpleXfer *xfer) |
1510 { | 1489 { |
1511 JabberSIXfer *jsx = xfer->data; | 1490 JabberSIXfer *jsx = purple_xfer_get_protocol_data(xfer); |
1512 JabberIq *iq; | 1491 JabberIq *iq; |
1513 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) { | 1492 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) { |
1514 JabberBuddy *jb; | 1493 JabberBuddy *jb; |
1515 JabberBuddyResource *jbr = NULL; | 1494 JabberBuddyResource *jbr = NULL; |
1516 char *resource; | 1495 char *resource; |
1517 GList *resources = NULL; | 1496 GList *resources = NULL; |
1518 | 1497 |
1519 if(NULL != (resource = jabber_get_resource(xfer->who))) { | 1498 if(NULL != (resource = jabber_get_resource(purple_xfer_get_remote_user(xfer)))) { |
1520 /* they've specified a resource, no need to ask or | 1499 /* they've specified a resource, no need to ask or |
1521 * default or anything, just do it */ | 1500 * default or anything, just do it */ |
1522 | 1501 |
1523 do_transfer_send(xfer, resource); | 1502 do_transfer_send(xfer, resource); |
1524 g_free(resource); | 1503 g_free(resource); |
1525 return; | 1504 return; |
1526 } | 1505 } |
1527 | 1506 |
1528 jb = jabber_buddy_find(jsx->js, xfer->who, TRUE); | 1507 jb = jabber_buddy_find(jsx->js, purple_xfer_get_remote_user(xfer), TRUE); |
1529 | 1508 |
1530 if (jb) { | 1509 if (jb) { |
1531 GList *l; | 1510 GList *l; |
1532 | 1511 |
1533 for (l = jb->resources ; l ; l = g_list_next(l)) { | 1512 for (l = jb->resources ; l ; l = g_list_next(l)) { |
1547 * whose presence we're not subscribed to, or | 1526 * whose presence we're not subscribed to, or |
1548 * someone who is offline. Let's inform the user */ | 1527 * someone who is offline. Let's inform the user */ |
1549 char *msg; | 1528 char *msg; |
1550 | 1529 |
1551 if(!jb) { | 1530 if(!jb) { |
1552 msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), xfer->who); | 1531 msg = g_strdup_printf(_("Unable to send file to %s, invalid JID"), purple_xfer_get_remote_user(xfer)); |
1553 } else if(jb->subscription & JABBER_SUB_TO) { | 1532 } else if(jb->subscription & JABBER_SUB_TO) { |
1554 msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), xfer->who); | 1533 msg = g_strdup_printf(_("Unable to send file to %s, user is not online"), purple_xfer_get_remote_user(xfer)); |
1555 } else { | 1534 } else { |
1556 msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), xfer->who); | 1535 msg = g_strdup_printf(_("Unable to send file to %s, not subscribed to user presence"), purple_xfer_get_remote_user(xfer)); |
1557 } | 1536 } |
1558 | 1537 |
1559 purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg); | 1538 purple_notify_error(jsx->js->gc, _("File Send Failed"), _("File Send Failed"), msg); |
1560 g_free(msg); | 1539 g_free(msg); |
1561 } else if (g_list_length(resources) == 1) { | 1540 } else if (g_list_length(resources) == 1) { |
1564 jbr = resources->data; | 1543 jbr = resources->data; |
1565 do_transfer_send(xfer, jbr->name); | 1544 do_transfer_send(xfer, jbr->name); |
1566 } else { | 1545 } else { |
1567 /* we've got multiple resources, we need to pick one to send to */ | 1546 /* we've got multiple resources, we need to pick one to send to */ |
1568 GList *l; | 1547 GList *l; |
1569 char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), xfer->who); | 1548 char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), purple_xfer_get_remote_user(xfer)); |
1570 PurpleRequestFields *fields = purple_request_fields_new(); | 1549 PurpleRequestFields *fields = purple_request_fields_new(); |
1571 PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0); | 1550 PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0); |
1572 PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL); | 1551 PurpleRequestFieldGroup *group = purple_request_field_group_new(NULL); |
1573 | 1552 |
1574 for(l = resources; l; l = l->next) { | 1553 for(l = resources; l; l = l->next) { |
1580 | 1559 |
1581 purple_request_fields_add_group(fields, group); | 1560 purple_request_fields_add_group(fields, group); |
1582 | 1561 |
1583 purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields, | 1562 purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields, |
1584 _("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb), | 1563 _("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb), |
1585 jsx->js->gc->account, xfer->who, NULL, xfer); | 1564 purple_connection_get_account(jsx->js->gc), purple_xfer_get_remote_user(xfer), NULL, xfer); |
1586 | 1565 |
1587 g_free(msg); | 1566 g_free(msg); |
1588 } | 1567 } |
1589 | 1568 |
1590 g_list_free(resources); | 1569 g_list_free(resources); |
1591 } else { | 1570 } else { |
1592 xmlnode *si, *feature, *x, *field, *value; | 1571 xmlnode *si, *feature, *x, *field, *value; |
1593 | 1572 |
1594 iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT); | 1573 iq = jabber_iq_new(jsx->js, JABBER_IQ_RESULT); |
1595 xmlnode_set_attrib(iq->node, "to", xfer->who); | 1574 xmlnode_set_attrib(iq->node, "to", purple_xfer_get_remote_user(xfer)); |
1596 if(jsx->iq_id) | 1575 if(jsx->iq_id) |
1597 jabber_iq_set_id(iq, jsx->iq_id); | 1576 jabber_iq_set_id(iq, jsx->iq_id); |
1598 else | 1577 else |
1599 purple_debug_error("jabber", "Sending SI result with new IQ id.\n"); | 1578 purple_debug_error("jabber", "Sending SI result with new IQ id.\n"); |
1600 | 1579 |
1634 JabberStream *js; | 1613 JabberStream *js; |
1635 | 1614 |
1636 PurpleXfer *xfer; | 1615 PurpleXfer *xfer; |
1637 JabberSIXfer *jsx; | 1616 JabberSIXfer *jsx; |
1638 | 1617 |
1639 js = gc->proto_data; | 1618 js = purple_connection_get_protocol_data(gc); |
1640 | 1619 |
1641 xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who); | 1620 xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who); |
1642 if (xfer) | 1621 if (xfer) |
1643 { | 1622 { |
1644 xfer->data = jsx = g_new0(JabberSIXfer, 1); | 1623 jsx = g_new0(JabberSIXfer, 1); |
1624 purple_xfer_set_protocol_data(xfer, jsx); | |
1645 jsx->js = js; | 1625 jsx->js = js; |
1646 jsx->local_streamhost_fd = -1; | 1626 jsx->local_streamhost_fd = -1; |
1647 | 1627 |
1648 jsx->ibb_session = NULL; | 1628 jsx->ibb_session = NULL; |
1649 | 1629 |
1694 xmlnode *file, *feature, *x, *field, *option, *value; | 1674 xmlnode *file, *feature, *x, *field, *option, *value; |
1695 #if ENABLE_FT_THUMBNAILS | 1675 #if ENABLE_FT_THUMBNAILS |
1696 xmlnode *thumbnail; | 1676 xmlnode *thumbnail; |
1697 #endif | 1677 #endif |
1698 const char *stream_id, *filename, *filesize_c, *profile; | 1678 const char *stream_id, *filename, *filesize_c, *profile; |
1699 guint64 filesize_64 = 0; | 1679 goffset filesize = 0; |
1700 size_t filesize = 0; | |
1701 | 1680 |
1702 if(!(profile = xmlnode_get_attrib(si, "profile")) || | 1681 if(!(profile = xmlnode_get_attrib(si, "profile")) || |
1703 strcmp(profile, NS_SI_FILE_TRANSFER)) | 1682 strcmp(profile, NS_SI_FILE_TRANSFER)) |
1704 return; | 1683 return; |
1705 | 1684 |
1711 | 1690 |
1712 if(!(filename = xmlnode_get_attrib(file, "name"))) | 1691 if(!(filename = xmlnode_get_attrib(file, "name"))) |
1713 return; | 1692 return; |
1714 | 1693 |
1715 if((filesize_c = xmlnode_get_attrib(file, "size"))) | 1694 if((filesize_c = xmlnode_get_attrib(file, "size"))) |
1716 filesize_64 = g_ascii_strtoull(filesize_c, NULL, 10); | 1695 filesize = g_ascii_strtoull(filesize_c, NULL, 10); |
1717 /* TODO 3.0.0: When the core uses a guint64, this is redundant. | |
1718 * See #8477. | |
1719 */ | |
1720 if (filesize_64 > G_MAXSIZE) { | |
1721 /* Should this pop up a warning? */ | |
1722 purple_debug_warning("jabber", "Unable to transfer file (too large)" | |
1723 " -- see #8477 for more details."); | |
1724 return; | |
1725 } | |
1726 filesize = filesize_64; | |
1727 | 1696 |
1728 if(!(feature = xmlnode_get_child(si, "feature"))) | 1697 if(!(feature = xmlnode_get_child(si, "feature"))) |
1729 return; | 1698 return; |
1730 | 1699 |
1731 if(!(x = xmlnode_get_child_with_namespace(feature, "x", "jabber:x:data"))) | 1700 if(!(x = xmlnode_get_child_with_namespace(feature, "x", "jabber:x:data"))) |
1772 | 1741 |
1773 jsx->js = js; | 1742 jsx->js = js; |
1774 jsx->stream_id = g_strdup(stream_id); | 1743 jsx->stream_id = g_strdup(stream_id); |
1775 jsx->iq_id = g_strdup(id); | 1744 jsx->iq_id = g_strdup(id); |
1776 | 1745 |
1777 xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from); | 1746 xfer = purple_xfer_new(purple_connection_get_account(js->gc), PURPLE_XFER_RECEIVE, from); |
1778 g_return_if_fail(xfer != NULL); | 1747 g_return_if_fail(xfer != NULL); |
1779 | 1748 |
1780 xfer->data = jsx; | 1749 purple_xfer_set_protocol_data(xfer, jsx); |
1781 | 1750 |
1782 purple_xfer_set_filename(xfer, filename); | 1751 purple_xfer_set_filename(xfer, filename); |
1783 if(filesize > 0) | 1752 if(filesize > 0) |
1784 purple_xfer_set_size(xfer, filesize); | 1753 purple_xfer_set_size(xfer, filesize); |
1785 | 1754 |