comparison libpurple/protocols/jabber/si.c @ 31988:b6defcebfe4b

Steps toward hiding PurpleXfer. To convert prpls as they are now, lot of new accessors are needed (for stuff that maybe shouldn't be exposed directly). To convert prpls so that they don't keep re-implementing the same type of stuff, a lot of error-prone changes are needed.
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 29 Aug 2011 22:55:51 +0000
parents ac88c8fc3f47
children 3caef255ad47
comparison
equal deleted inserted replaced
31987:011abe09b264 31988:b6defcebfe4b
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 = purple_xfer_get_protocol_data(xfer); 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 }
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 }
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 }
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;
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);
473 purple_input_remove(xfer->watcher); 465 purple_input_remove(xfer->watcher);
474 xfer->watcher = 0; 466 xfer->watcher = 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) ||
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) {
542 purple_input_remove(xfer->watcher);
555 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ, 543 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ,
556 jabber_si_xfer_bytestreams_send_read_again_cb, xfer); 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;
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;
622 purple_input_remove(xfer->watcher);
644 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, 623 xfer->watcher = 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);
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;
640 purple_input_remove(xfer->watcher);
661 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, 641 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE,
662 jabber_si_xfer_bytestreams_send_read_response_cb, xfer); 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 }
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 */
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 xfer->local_port = 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) {
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_GSIZE_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 */
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 && xfer->fd >= 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(xfer->fd);
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);
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");
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 = purple_xfer_get_protocol_data(xfer); 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);
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 jsx->js->gc->account, 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