comparison libpurple/protocols/bonjour/bonjour_ft.c @ 21465:e489c81e1f6f

Cleanup and fix the socks5 proxy connect address to be correct.
author Daniel Atallah <daniel.atallah@gmail.com>
date Tue, 13 Nov 2007 02:20:58 +0000
parents da75dd6c41fb
children 7a05b6f84545
comparison
equal deleted inserted replaced
21464:577d90f8794e 21465:e489c81e1f6f
28 #include "buddy.h" 28 #include "buddy.h"
29 #include "bonjour.h" 29 #include "bonjour.h"
30 #include "bonjour_ft.h" 30 #include "bonjour_ft.h"
31 #include "cipher.h" 31 #include "cipher.h"
32 32
33 static PurpleXfer*
34 bonjour_si_xfer_find(BonjourData *bd, const char *sid, const char *from);
35 static void
36 xep_ft_si_offer(PurpleXfer *xfer, const gchar *to);
37 static void
38 xep_ft_si_result(PurpleXfer *xfer, char *to);
39 static void
40 xep_ft_si_reject(PurpleXfer *xfer, char *to);
41 static void
42 xep_ft_si_reject2(BonjourData *bd, const char *to, const char *sid);
43 static void 33 static void
44 bonjour_bytestreams_init(PurpleXfer *xfer); 34 bonjour_bytestreams_init(PurpleXfer *xfer);
45 static void 35 static void
46 bonjour_bytestreams_listen(int sock, gpointer data);
47 static void
48 bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond);
49 static void
50 bonjour_bytestreams_connect(PurpleXfer *xfer); 36 bonjour_bytestreams_connect(PurpleXfer *xfer);
51 static void
52 bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message);
53 static void 37 static void
54 bonjour_xfer_init(PurpleXfer *xfer); 38 bonjour_xfer_init(PurpleXfer *xfer);
55 static void 39 static void
56 bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *from, 40 bonjour_xfer_receive(PurpleConnection *pc, const char *id, const char *from,
57 const int filesize, const char *filename, int option); 41 const int filesize, const char *filename, int option);
58 static void bonjour_xfer_cancel_send(PurpleXfer *xfer);
59 static void bonjour_xfer_request_denied(PurpleXfer *xfer);
60 static void bonjour_xfer_cancel_recv(PurpleXfer *xfer);
61 static void bonjour_xfer_end(PurpleXfer *xfer);
62 static void bonjour_free_xfer(PurpleXfer *xfer); 42 static void bonjour_free_xfer(PurpleXfer *xfer);
63 43
64 /* Look for specific xfer handle */ 44 /* Look for specific xfer handle */
65 static unsigned int next_id = 0; 45 static unsigned int next_id = 0;
46
47 static void
48 xep_ft_si_reject(PurpleXfer *xfer, char *to)
49 {
50 xmlnode *error_node = NULL;
51 xmlnode *tmp_node = NULL;
52 XepIq *iq = NULL;
53 XepXfer *xf = NULL;
54
55 if(!to || !xfer)
56 return;
57 xf = xfer->data;
58 if(!xf)
59 return;
60
61 purple_debug_info("Bonjour", "xep file transfer stream initialization error.\n");
62 iq = xep_iq_new(xf->data, XEP_IQ_ERROR, to, xf->sid);
63 if(iq == NULL)
64 return;
65
66 error_node = xmlnode_new_child(iq->node, "error");
67 xmlnode_set_attrib(error_node, "code", "403");
68 xmlnode_set_attrib(error_node, "type", "cancel");
69
70 tmp_node = xmlnode_new_child(error_node, "forbidden");
71 xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
72
73 tmp_node = xmlnode_new_child(error_node, "text");
74 xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
75 xmlnode_insert_data(tmp_node, "Offer Declined", -1);
76
77 xep_iq_send_and_free(iq);
78 }
66 79
67 static void bonjour_xfer_cancel_send(PurpleXfer *xfer) 80 static void bonjour_xfer_cancel_send(PurpleXfer *xfer)
68 { 81 {
69 purple_debug_info("Bonjour", "Bonjour-xfer-cancel-send.\n"); 82 purple_debug_info("Bonjour", "Bonjour-xfer-cancel-send.\n");
70 bonjour_free_xfer(xfer); 83 bonjour_free_xfer(xfer);
74 { 87 {
75 purple_debug_info("Bonjour", "Bonjour-xfer-request-denied.\n"); 88 purple_debug_info("Bonjour", "Bonjour-xfer-request-denied.\n");
76 xep_ft_si_reject(xfer, xfer->who); 89 xep_ft_si_reject(xfer, xfer->who);
77 bonjour_free_xfer(xfer); 90 bonjour_free_xfer(xfer);
78 } 91 }
79
80 92
81 static void bonjour_xfer_cancel_recv(PurpleXfer *xfer) 93 static void bonjour_xfer_cancel_recv(PurpleXfer *xfer)
82 { 94 {
83 purple_debug_info("Bonjour", "Bonjour-xfer-cancel-recv.\n"); 95 purple_debug_info("Bonjour", "Bonjour-xfer-cancel-recv.\n");
84 bonjour_free_xfer(xfer); 96 bonjour_free_xfer(xfer);
134 XepIq *iq = NULL; 146 XepIq *iq = NULL;
135 XepXfer *xf = NULL; 147 XepXfer *xf = NULL;
136 BonjourData *bd = NULL; 148 BonjourData *bd = NULL;
137 char buf[32]; 149 char buf[32];
138 150
139 if(!xfer || !to)
140 return;
141 xf = xfer->data; 151 xf = xfer->data;
142 if(!xf) 152 if(!xf)
143 return; 153 return;
154
144 bd = xf->data; 155 bd = xf->data;
145 if(!bd) 156 if(!bd)
146 return; 157 return;
147 158
148 purple_debug_info("Bonjour", "xep file transfer stream initialization offer-id=%d.\n", next_id); 159 purple_debug_info("Bonjour", "xep file transfer stream initialization offer-id=%d.\n", next_id);
186 if (xf->mode & XEP_IBB) { 197 if (xf->mode & XEP_IBB) {
187 option = xmlnode_new_child(field, "option"); 198 option = xmlnode_new_child(field, "option");
188 value = xmlnode_new_child(option, "value"); 199 value = xmlnode_new_child(option, "value");
189 xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1); 200 xmlnode_insert_data(value, "http://jabber.org/protocol/ibb", -1);
190 } 201 }
191 xep_iq_send(iq); 202
192 } 203 xep_iq_send_and_free(iq);
193 204 }
194 static void 205
195 xep_ft_si_reject(PurpleXfer *xfer, char *to) 206 static void
207 xep_ft_si_reject2(BonjourData *bd, const char *to, const char *sid)
196 { 208 {
197 xmlnode *error_node = NULL; 209 xmlnode *error_node = NULL;
198 xmlnode *forbidden = NULL; 210 xmlnode *tmp_node = NULL;
199 xmlnode *text = NULL;
200 XepIq *iq = NULL; 211 XepIq *iq = NULL;
201 XepXfer *xf = NULL; 212
202 213 g_return_if_fail(bd != NULL);
203 if(!to || !xfer) 214
204 return; 215 if(!to || !sid)
205 xf = xfer->data;
206 if(!xf)
207 return; 216 return;
208 217
209 purple_debug_info("Bonjour", "xep file transfer stream initialization error.\n"); 218 purple_debug_info("Bonjour", "xep file transfer stream initialization error.\n");
210 iq = xep_iq_new(xf->data, XEP_IQ_ERROR, to, xf->sid); 219 iq = xep_iq_new(bd, XEP_IQ_ERROR, to, sid);
211 if(iq == NULL) 220 if(iq == NULL)
212 return; 221 return;
213 222
214 error_node = xmlnode_new_child(iq->node, "error"); 223 error_node = xmlnode_new_child(iq->node, "error");
215 xmlnode_set_attrib(error_node, "code", "403"); 224 xmlnode_set_attrib(error_node, "code", "403");
216 xmlnode_set_attrib(error_node, "type", "cancel"); 225 xmlnode_set_attrib(error_node, "type", "cancel");
217 226
218 forbidden = xmlnode_new_child(error_node, "forbidden"); 227 tmp_node = xmlnode_new_child(error_node, "forbidden");
219 xmlnode_set_namespace(forbidden, "urn:ietf:params:xml:ns:xmpp-stanzas"); 228 xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
220 229
221 text = xmlnode_new_child(error_node, "text"); 230 tmp_node = xmlnode_new_child(error_node, "text");
222 xmlnode_set_namespace(text, "urn:ietf:params:xml:ns:xmpp-stanzas"); 231 xmlnode_set_namespace(tmp_node, "urn:ietf:params:xml:ns:xmpp-stanzas");
223 xmlnode_insert_data(text, "Offer Declined", -1); 232 xmlnode_insert_data(tmp_node, "Offer Declined", -1);
224 233
225 xep_iq_send(iq); 234 xep_iq_send_and_free(iq);
226 }
227 static void
228 xep_ft_si_reject2(BonjourData *bd, const char *to, const char *sid)
229 {
230 xmlnode *error_node = NULL;
231 xmlnode *forbidden = NULL;
232 xmlnode *text = NULL;
233 XepIq *iq = NULL;
234 if(bd == NULL)
235 return;
236 if(!to || !sid)
237 return;
238 purple_debug_info("Bonjour", "xep file transfer stream initialization error.\n");
239 iq = xep_iq_new(bd, XEP_IQ_ERROR, to, sid);
240 if(iq == NULL)
241 return;
242 error_node = xmlnode_new_child(iq->node, "error");
243 xmlnode_set_attrib(error_node, "code", "403");
244 xmlnode_set_attrib(error_node, "type", "cancel");
245
246 forbidden = xmlnode_new_child(error_node, "forbidden");
247 xmlnode_set_namespace(forbidden, "urn:ietf:params:xml:ns:xmpp-stanzas");
248
249 text = xmlnode_new_child(error_node, "text");
250 xmlnode_set_namespace(text, "urn:ietf:params:xml:ns:xmpp-stanzas");
251 xmlnode_insert_data(text, "Offer Declined", -1);
252
253 xep_iq_send(iq);
254 } 235 }
255 236
256 static void 237 static void
257 xep_ft_si_result(PurpleXfer *xfer, char *to) 238 xep_ft_si_result(PurpleXfer *xfer, char *to)
258 { 239 {
289 xmlnode_set_attrib(field, "var", "stream-method"); 270 xmlnode_set_attrib(field, "var", "stream-method");
290 271
291 value = xmlnode_new_child(field, "value"); 272 value = xmlnode_new_child(field, "value");
292 xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1); 273 xmlnode_insert_data(value, "http://jabber.org/protocol/bytestreams", -1);
293 274
294 xep_iq_send(iq); 275 xep_iq_send_and_free(iq);
295 } 276 }
296 277
297 static void 278 static void
298 bonjour_free_xfer(PurpleXfer *xfer) 279 bonjour_free_xfer(PurpleXfer *xfer)
299 { 280 {
300 XepXfer *xf = NULL; 281 XepXfer *xf = NULL;
301 BonjourData *bd = NULL; 282 BonjourData *bd = NULL;
283
302 if(xfer == NULL) { 284 if(xfer == NULL) {
303 purple_debug_info("Bonjour", "bonjour-free-xfer-null.\n"); 285 purple_debug_info("Bonjour", "bonjour-free-xfer-null.\n");
304 return; 286 return;
305 } 287 }
288
306 purple_debug_info("Bonjour", "bonjour-free-xfer-%p.\n", xfer); 289 purple_debug_info("Bonjour", "bonjour-free-xfer-%p.\n", xfer);
290
307 xf = (XepXfer*)xfer->data; 291 xf = (XepXfer*)xfer->data;
308 if(xf != NULL){ 292 if(xf != NULL) {
309 bd = (BonjourData*)xf->data; 293 bd = (BonjourData*)xf->data;
310 if(bd != NULL){ 294 if(bd != NULL) {
311 bd->xfer_lists = g_list_remove(bd->xfer_lists, xfer); 295 bd->xfer_lists = g_list_remove(bd->xfer_lists, xfer);
312 purple_debug_info("Bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists); 296 purple_debug_info("Bonjour", "B free xfer from lists(%p).\n", bd->xfer_lists);
313 } 297 }
314 if (xf->proxy_connection != NULL) 298 if (xf->proxy_connection != NULL)
315 purple_proxy_connect_cancel(xf->proxy_connection); 299 purple_proxy_connect_cancel(xf->proxy_connection);
320 g_free(xf->buddy_ip); 304 g_free(xf->buddy_ip);
321 g_free(xf->sid); 305 g_free(xf->sid);
322 g_free(xf); 306 g_free(xf);
323 xfer->data = NULL; 307 xfer->data = NULL;
324 } 308 }
309
325 purple_debug_info("Bonjour", "Need close socket=%d.\n", xfer->fd); 310 purple_debug_info("Bonjour", "Need close socket=%d.\n", xfer->fd);
326 } 311 }
327 312
328 PurpleXfer * 313 PurpleXfer *
329 bonjour_new_xfer(PurpleConnection *gc, const char *who) 314 bonjour_new_xfer(PurpleConnection *gc, const char *who)
330 { 315 {
331 PurpleXfer *xfer = NULL; 316 PurpleXfer *xfer;
332 XepXfer *xep_xfer = NULL; 317 XepXfer *xep_xfer = NULL;
333 BonjourData *bd = NULL; 318 BonjourData *bd = NULL;
319
334 if(who == NULL || gc == NULL) 320 if(who == NULL || gc == NULL)
335 return xfer; 321 return NULL;
336 322
337 purple_debug_info("Bonjour", "Bonjour-new-xfer to %s.\n", who); 323 purple_debug_info("Bonjour", "Bonjour-new-xfer to %s.\n", who);
338 bd = (BonjourData*) gc->proto_data; 324 bd = (BonjourData*) gc->proto_data;
339 if(bd == NULL) 325 if(bd == NULL)
340 return xfer; 326 return NULL;
327
341 /* Build the file transfer handle */ 328 /* Build the file transfer handle */
342 xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who); 329 xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
343 330 xfer->data = xep_xfer = g_new0(XepXfer, 1);
344 if (xfer) { 331 xep_xfer->data = bd;
345 xep_xfer = g_new0(XepXfer, 1); 332
346 if(xep_xfer == NULL){ 333 purple_debug_info("Bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data);
347 bonjour_free_xfer(xfer); 334
348 return NULL; 335 xep_xfer->mode = XEP_BYTESTREAMS | XEP_IBB;
349 } 336 xep_xfer->sid = NULL;
350 xep_xfer->data = bd; 337
351 purple_debug_info("Bonjour", "Bonjour-new-xfer bd=%p data=%p.\n", bd, xep_xfer->data); 338 purple_xfer_set_init_fnc(xfer, bonjour_xfer_init);
352 xep_xfer->mode = XEP_BYTESTREAMS | XEP_IBB; 339 purple_xfer_set_cancel_send_fnc(xfer, bonjour_xfer_cancel_send);
353 xfer->data = xep_xfer; 340 purple_xfer_set_end_fnc(xfer, bonjour_xfer_end);
354 xep_xfer->sid = NULL; 341
355 purple_xfer_set_init_fnc(xfer, bonjour_xfer_init); 342 bd->xfer_lists = g_list_append(bd->xfer_lists, xfer);
356 purple_xfer_set_cancel_send_fnc(xfer, bonjour_xfer_cancel_send); 343
357 purple_xfer_set_end_fnc(xfer, bonjour_xfer_end);
358 bd->xfer_lists = g_list_append(bd->xfer_lists, xfer);
359 }
360 return xfer; 344 return xfer;
361 } 345 }
362 346
363 void 347 void
364 bonjour_send_file(PurpleConnection *gc, const char *who, const char *file) 348 bonjour_send_file(PurpleConnection *gc, const char *who, const char *file)
382 bonjour_xfer_init(PurpleXfer *xfer) 366 bonjour_xfer_init(PurpleXfer *xfer)
383 { 367 {
384 PurpleBuddy *buddy = NULL; 368 PurpleBuddy *buddy = NULL;
385 BonjourBuddy *bd = NULL; 369 BonjourBuddy *bd = NULL;
386 XepXfer *xf = NULL; 370 XepXfer *xf = NULL;
387 char buffer[100]; 371
388 if(xfer == NULL) 372 if(xfer == NULL)
389 return; 373 return;
390 xf = (XepXfer*)xfer->data; 374 xf = (XepXfer*)xfer->data;
391 if(xf == NULL) 375 if(xf == NULL)
392 return; 376 return;
396 /* this buddy is offline. */ 380 /* this buddy is offline. */
397 if (buddy == NULL) 381 if (buddy == NULL)
398 return; 382 return;
399 383
400 bd = (BonjourBuddy *)buddy->proto_data; 384 bd = (BonjourBuddy *)buddy->proto_data;
401 memcpy(buffer, bd->ip, 20);
402 xf->buddy_ip = g_strdup(bd->ip); 385 xf->buddy_ip = g_strdup(bd->ip);
403 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) { 386 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
404 /* initiate file transfer, send SI offer. */ 387 /* initiate file transfer, send SI offer. */
405 purple_debug_info("Bonjour", "Bonjour xfer type is PURPLE_XFER_SEND.\n"); 388 purple_debug_info("Bonjour", "Bonjour xfer type is PURPLE_XFER_SEND.\n");
406 xep_ft_si_offer(xfer, xfer->who); 389 xep_ft_si_offer(xfer, xfer->who);
427 if(pc == NULL || packet == NULL || pb == NULL) 410 if(pc == NULL || packet == NULL || pb == NULL)
428 return; 411 return;
429 bd = (BonjourData*) pc->proto_data; 412 bd = (BonjourData*) pc->proto_data;
430 if(bd == NULL) 413 if(bd == NULL)
431 return; 414 return;
415
432 purple_debug_info("Bonjour", "xep-si-parse.\n"); 416 purple_debug_info("Bonjour", "xep-si-parse.\n");
417
433 type = xmlnode_get_attrib(packet, "type"); 418 type = xmlnode_get_attrib(packet, "type");
434 from = pb->name; 419 from = pb->name;
435 id = xmlnode_get_attrib(packet, "id"); 420 id = xmlnode_get_attrib(packet, "id");
436 if(type) { 421 if(type) {
437 if(!strcmp(type, "set")){ 422 if(!strcmp(type, "set")){
438 si = xmlnode_get_child(packet,"si"); 423 si = xmlnode_get_child(packet,"si");
439 purple_debug_info("Bonjour", "si offer Message type - SET.\n"); 424 purple_debug_info("Bonjour", "si offer Message type - SET.\n");
440 file = xmlnode_get_child(si, "file"); 425 file = xmlnode_get_child(si, "file");
441 /**/ 426 /**/
442 filename = xmlnode_get_attrib(file, "name"); 427 filename = xmlnode_get_attrib(file, "name");
443 if( (filesize_str = xmlnode_get_attrib(file, "size")) != NULL ) 428 if((filesize_str = xmlnode_get_attrib(file, "size")))
444 filesize = atoi(filesize_str); 429 filesize = atoi(filesize_str);
445 bonjour_xfer_receive(pc, id, from, filesize, filename, option); 430 bonjour_xfer_receive(pc, id, from, filesize, filename, option);
446 } else if(!strcmp(type, "result")){ 431 } else if(!strcmp(type, "result")){
447 si = xmlnode_get_child(packet,"si"); 432 si = xmlnode_get_child(packet,"si");
448 purple_debug_info("Bonjour", "si offer Message type - RESULT.\n"); 433 purple_debug_info("Bonjour", "si offer Message type - RESULT.\n");
475 BonjourData *bd = NULL; 460 BonjourData *bd = NULL;
476 PurpleXfer *xfer = NULL; 461 PurpleXfer *xfer = NULL;
477 XepXfer *xf = NULL; 462 XepXfer *xf = NULL;
478 const char *jid=NULL, *host=NULL, *port=NULL; 463 const char *jid=NULL, *host=NULL, *port=NULL;
479 int portnum; 464 int portnum;
465
480 if(pc == NULL || packet == NULL || pb == NULL) 466 if(pc == NULL || packet == NULL || pb == NULL)
481 return; 467 return;
468
482 bd = (BonjourData*) pc->proto_data; 469 bd = (BonjourData*) pc->proto_data;
483 if(bd == NULL) 470 if(bd == NULL)
484 return; 471 return;
472
485 purple_debug_info("Bonjour", "xep-bytestreams-parse.\n"); 473 purple_debug_info("Bonjour", "xep-bytestreams-parse.\n");
474
486 type = xmlnode_get_attrib(packet, "type"); 475 type = xmlnode_get_attrib(packet, "type");
487 from = pb->name; 476 from = pb->name;
488 query = xmlnode_get_child(packet,"query"); 477 query = xmlnode_get_child(packet,"query");
489 if(type) { 478 if(type) {
490 if(!strcmp(type, "set")){ 479 if(!strcmp(type, "set")){
491 purple_debug_info("Bonjour", "bytestream offer Message type - SET.\n"); 480 purple_debug_info("Bonjour", "bytestream offer Message type - SET.\n");
481
492 id = xmlnode_get_attrib(query, "sid"); 482 id = xmlnode_get_attrib(query, "sid");
493 xfer = bonjour_si_xfer_find(bd, id, from); 483 xfer = bonjour_si_xfer_find(bd, id, from);
484
494 if(xfer){ 485 if(xfer){
495 xf = (XepXfer*)xfer->data; 486 xf = (XepXfer*)xfer->data;
496 for(streamhost = xmlnode_get_child(query, "streamhost"); 487 for(streamhost = xmlnode_get_child(query, "streamhost");
497 streamhost; 488 streamhost;
498 streamhost = xmlnode_get_next_twin(streamhost)) { 489 streamhost = xmlnode_get_next_twin(streamhost)) {
490
499 if((jid = xmlnode_get_attrib(streamhost, "jid")) && 491 if((jid = xmlnode_get_attrib(streamhost, "jid")) &&
500 (host = xmlnode_get_attrib(streamhost, "host")) && 492 (host = xmlnode_get_attrib(streamhost, "host")) &&
501 (port = xmlnode_get_attrib(streamhost, "port")) && 493 (port = xmlnode_get_attrib(streamhost, "port")) &&
502 (portnum = atoi(port))) { 494 (portnum = atoi(port))) {
495
503 if(!strcmp(host, xf->buddy_ip)) { 496 if(!strcmp(host, xf->buddy_ip)) {
504 xf->jid = g_strdup(jid); 497 xf->jid = g_strdup(jid);
505 xf->proxy_host = g_strdup(host); 498 xf->proxy_host = g_strdup(host);
506 xf->proxy_port = portnum; 499 xf->proxy_port = portnum;
507 purple_debug_info("Bonjour", "bytestream offer parse" 500 purple_debug_info("Bonjour", "bytestream offer parse"
508 "jid=%s host=%s port=%d.\n", jid, host, portnum); 501 "jid=%s host=%s port=%d.\n", jid, host, portnum);
509 bonjour_bytestreams_connect(xfer); 502 bonjour_bytestreams_connect(xfer);
503 break;
510 } 504 }
505
511 } else { 506 } else {
512 purple_debug_info("Bonjour", "bytestream offer Message parse error.\n"); 507 purple_debug_info("Bonjour", "bytestream offer Message parse error.\n");
513 } 508 }
514 } 509 }
515 } else { 510 } else {
527 const int filesize, const char *filename, int option) 522 const int filesize, const char *filename, int option)
528 { 523 {
529 PurpleXfer *xfer = NULL; 524 PurpleXfer *xfer = NULL;
530 XepXfer *xf = NULL; 525 XepXfer *xf = NULL;
531 BonjourData *bd = NULL; 526 BonjourData *bd = NULL;
527
532 if(pc == NULL || id == NULL || from == NULL || filename == NULL) 528 if(pc == NULL || id == NULL || from == NULL || filename == NULL)
533 return; 529 return;
530
534 bd = (BonjourData*) pc->proto_data; 531 bd = (BonjourData*) pc->proto_data;
535 if(bd == NULL) 532 if(bd == NULL)
536 return; 533 return;
534
537 purple_debug_info("Bonjour", "bonjour-xfer-receive.\n"); 535 purple_debug_info("Bonjour", "bonjour-xfer-receive.\n");
536
538 /* Build the file transfer handle */ 537 /* Build the file transfer handle */
539 xfer = purple_xfer_new(pc->account, PURPLE_XFER_RECEIVE, from); 538 xfer = purple_xfer_new(pc->account, PURPLE_XFER_RECEIVE, from);
540 if (xfer) { 539 xfer->data = xf = g_new0(XepXfer, 1);
541 xf = g_new0(XepXfer, 1); 540 xf->data = bd;
542 xf->data = bd; 541 purple_xfer_set_filename(xfer, filename);
543 xfer->data = xf; 542 xf->sid = g_strdup(id);
544 purple_xfer_set_filename(xfer, filename); 543
545 xf->sid = g_strdup(id); 544 if(filesize > 0)
546 if(filesize > 0) 545 purple_xfer_set_size(xfer, filesize);
547 purple_xfer_set_size(xfer, filesize); 546 purple_xfer_set_init_fnc(xfer, bonjour_xfer_init);
548 purple_xfer_set_init_fnc(xfer, bonjour_xfer_init); 547 purple_xfer_set_request_denied_fnc(xfer, bonjour_xfer_request_denied);
549 purple_xfer_set_request_denied_fnc(xfer, bonjour_xfer_request_denied); 548 purple_xfer_set_cancel_recv_fnc(xfer, bonjour_xfer_cancel_recv);
550 purple_xfer_set_cancel_recv_fnc(xfer, bonjour_xfer_cancel_recv); 549 purple_xfer_set_end_fnc(xfer, bonjour_xfer_end);
551 purple_xfer_set_end_fnc(xfer, bonjour_xfer_end); 550
552 bd->xfer_lists = g_list_append(bd->xfer_lists, xfer); 551 bd->xfer_lists = g_list_append(bd->xfer_lists, xfer);
553 purple_xfer_request(xfer); 552
554 } 553 purple_xfer_request(xfer);
555 }
556
557 static void
558 bonjour_bytestreams_init(PurpleXfer *xfer)
559 {
560 XepXfer *xf = NULL;
561 if(xfer == NULL)
562 return;
563 purple_debug_info("Bonjour", "Bonjour-bytestreams-init.\n");
564 xf = xfer->data;
565 xf->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
566 bonjour_bytestreams_listen, xfer);
567 if (xf->listen_data == NULL) {
568 purple_xfer_cancel_local(xfer);
569 }
570 return;
571 }
572
573 static void
574 bonjour_bytestreams_listen(int sock, gpointer data)
575 {
576 PurpleXfer *xfer = NULL;
577 XepXfer *xf;
578 XepIq *iq;
579 xmlnode *query, *streamhost;
580 char *port;
581 char *next_ip = NULL;
582 char *local_ip = NULL;
583 char token [] = ";";
584 purple_debug_info("Bonjour", "Bonjour-bytestreams-listen. sock=%d.\n", sock);
585 if (sock < 0 || data == NULL) {
586 /*purple_xfer_cancel_local(xfer);*/
587 return;
588 }
589 xfer = data;
590 xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
591 bonjour_sock5_request_cb, xfer);
592 xf = (XepXfer*)xfer->data;
593 xf->listen_data = NULL;
594 /*xf->listen_data = NULL;*/
595 iq = xep_iq_new(xf->data, XEP_IQ_SET, xfer->who, xf->sid);
596 query = xmlnode_new_child(iq->node, "query");
597 xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
598 xmlnode_set_attrib(query, "sid", xf->sid);
599 xmlnode_set_attrib(query, "mode", "tcp");
600 local_ip = purple_network_get_my_ip_ext2(sock);
601 next_ip = strtok(local_ip, token);
602 xfer->local_port = purple_network_get_port_from_fd(sock);
603 while(next_ip != NULL) {
604 streamhost = xmlnode_new_child(query, "streamhost");
605 xmlnode_set_attrib(streamhost, "jid", xf->sid);
606 xmlnode_set_attrib(streamhost, "host", next_ip);
607 port = g_strdup_printf("%hu", xfer->local_port);
608 xmlnode_set_attrib(streamhost, "port", port);
609 g_free(port);
610 next_ip = strtok(NULL, token);
611 }
612 xep_iq_send(iq);
613 } 554 }
614 555
615 static void 556 static void
616 bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond) 557 bonjour_sock5_request_cb(gpointer data, gint source, PurpleInputCondition cond)
617 { 558 {
618 PurpleXfer *xfer = data; 559 PurpleXfer *xfer = data;
619 XepXfer *xf = NULL; 560 XepXfer *xf = NULL;
620 int acceptfd; 561 int acceptfd;
621 int len = 0; 562 int len = 0;
622 if(xfer == NULL ) 563
623 return; 564 if(xfer == NULL)
565 return;
566
624 xf = xfer->data; 567 xf = xfer->data;
625 if(xf == NULL) 568 if(xf == NULL)
626 return; 569 return;
570
627 switch(xf->sock5_req_state){ 571 switch(xf->sock5_req_state){
628 case 0x00: 572 case 0x00:
629 acceptfd = accept (source, NULL, 0); 573 acceptfd = accept(source, NULL, 0);
630 if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK )) { 574 if(acceptfd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
631 575
632 } else if(acceptfd == -1) { 576 } else if(acceptfd == -1) {
633 577
634 } else { 578 } else {
635 purple_debug_info("Bonjour", "Conjour-sock5-request-cb. state= %d, accept=%d\n", xf->sock5_req_state, acceptfd); 579 purple_debug_info("Bonjour", "Conjour-sock5-request-cb. state= %d, accept=%d\n", xf->sock5_req_state, acceptfd);
722 default: 666 default:
723 break; 667 break;
724 } 668 }
725 return; 669 return;
726 } 670 }
671
672 static void
673 bonjour_bytestreams_listen(int sock, gpointer data)
674 {
675 PurpleXfer *xfer = data;
676 XepXfer *xf;
677 XepIq *iq;
678 xmlnode *query, *streamhost;
679 char *port;
680 const char *next_ip;
681 const char *local_ip = NULL;
682 char token [] = ";";
683
684 purple_debug_info("Bonjour", "Bonjour-bytestreams-listen. sock=%d.\n", sock);
685 if (sock < 0 || xfer == NULL) {
686 /*purple_xfer_cancel_local(xfer);*/
687 return;
688 }
689
690 xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ,
691 bonjour_sock5_request_cb, xfer);
692 xf = (XepXfer*)xfer->data;
693 xf->listen_data = NULL;
694
695 iq = xep_iq_new(xf->data, XEP_IQ_SET, xfer->who, xf->sid);
696
697 query = xmlnode_new_child(iq->node, "query");
698 xmlnode_set_namespace(query, "http://jabber.org/protocol/bytestreams");
699 xmlnode_set_attrib(query, "sid", xf->sid);
700 xmlnode_set_attrib(query, "mode", "tcp");
701
702 xfer->local_port = purple_network_get_port_from_fd(sock);
703
704 local_ip = purple_network_get_my_ip_ext2(sock);
705 /* cheat a little here - the intent of the "const" attribute is to make it clear that the string doesn't need to be freed */
706 next_ip = strtok((char *)local_ip, token);
707
708 while(next_ip != NULL) {
709 streamhost = xmlnode_new_child(query, "streamhost");
710 xmlnode_set_attrib(streamhost, "jid", xf->sid);
711 xmlnode_set_attrib(streamhost, "host", next_ip);
712 port = g_strdup_printf("%hu", xfer->local_port);
713 xmlnode_set_attrib(streamhost, "port", port);
714 g_free(port);
715 next_ip = strtok(NULL, token);
716 }
717
718 xep_iq_send_and_free(iq);
719 }
720
721 static void
722 bonjour_bytestreams_init(PurpleXfer *xfer)
723 {
724 XepXfer *xf = NULL;
725 if(xfer == NULL)
726 return;
727 purple_debug_info("Bonjour", "Bonjour-bytestreams-init.\n");
728 xf = xfer->data;
729 xf->listen_data = purple_network_listen_range(0, 0, SOCK_STREAM,
730 bonjour_bytestreams_listen, xfer);
731 if (xf->listen_data == NULL) {
732 purple_xfer_cancel_local(xfer);
733 }
734 return;
735 }
736
737 static void
738 bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
739 {
740 PurpleXfer *xfer = data;
741 XepXfer *xf = xfer->data;
742
743 if(data == NULL || source < 0)
744 return;
745
746 purple_proxy_info_destroy(xf->proxy_info);
747 xf->proxy_connection = NULL;
748 xf->proxy_info = NULL;
749 /* Here, start the file transfer.*/
750 purple_xfer_start(xfer, source, NULL, -1);
751 }
752
727 static void 753 static void
728 bonjour_bytestreams_connect(PurpleXfer *xfer) 754 bonjour_bytestreams_connect(PurpleXfer *xfer)
729 { 755 {
730 XepXfer *xf = NULL; 756 XepXfer *xf = NULL;
731 char dstaddr[41]; 757 char dstaddr[41];
732 unsigned char hashval[20]; 758 unsigned char hashval[20];
733 char *p = NULL; 759 char *p = NULL;
734 int i; 760 int i;
761
735 if(xfer == NULL) 762 if(xfer == NULL)
736 return; 763 return;
764
737 purple_debug_info("Bonjour", "bonjour-bytestreams-connect.\n"); 765 purple_debug_info("Bonjour", "bonjour-bytestreams-connect.\n");
766
738 xf = (XepXfer*)xfer->data; 767 xf = (XepXfer*)xfer->data;
739 if(!xf) 768 if(!xf)
740 return; 769 return;
741 xf->proxy_info = purple_proxy_info_new(); 770
742 if(xf->proxy_info == NULL)
743 return;
744 p = g_strdup_printf("%s@%s", xf->sid, xfer->who); 771 p = g_strdup_printf("%s@%s", xf->sid, xfer->who);
745 purple_cipher_digest_region("sha1", (guchar *)dstaddr, strlen(dstaddr), 772 purple_cipher_digest_region("sha1", (guchar *)p, strlen(p),
746 sizeof(hashval), hashval, NULL); 773 sizeof(hashval), hashval, NULL);
747 g_free(p); 774 g_free(p);
775
748 memset(dstaddr, 0, 41); 776 memset(dstaddr, 0, 41);
749 p = dstaddr; 777 p = dstaddr;
750 for(i=0; i<20; i++) { 778 for(i = 0; i < 20; i++, p += 2)
751 snprintf(p, 3, "%02x", hashval[i]); 779 snprintf(p, 3, "%02x", hashval[i]);
752 } 780
781 xf->proxy_info = purple_proxy_info_new();
753 purple_proxy_info_set_type(xf->proxy_info, PURPLE_PROXY_SOCKS5); 782 purple_proxy_info_set_type(xf->proxy_info, PURPLE_PROXY_SOCKS5);
754 purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host); 783 purple_proxy_info_set_host(xf->proxy_info, xf->proxy_host);
755 purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port); 784 purple_proxy_info_set_port(xf->proxy_info, xf->proxy_port);
756 xf->proxy_connection = purple_proxy_connect_socks5(NULL, xf->proxy_info, 785 xf->proxy_connection = purple_proxy_connect_socks5(NULL, xf->proxy_info,
757 dstaddr, 0, 786 dstaddr, 0,
758 bonjour_bytestreams_connect_cb, xfer); 787 bonjour_bytestreams_connect_cb, xfer);
788
759 if(xf->proxy_connection == NULL) { 789 if(xf->proxy_connection == NULL) {
760 purple_proxy_info_destroy(xf->proxy_info); 790 purple_proxy_info_destroy(xf->proxy_info);
761 xf->proxy_info = NULL; 791 xf->proxy_info = NULL;
762 } 792 }
763 } 793 }
764 794
765 static void
766 bonjour_bytestreams_connect_cb(gpointer data, gint source, const gchar *error_message)
767 {
768 PurpleXfer *xfer = data;
769 XepXfer *xf = xfer->data;
770 if(data == NULL || source < 0)
771 return;
772 purple_proxy_info_destroy(xf->proxy_info);
773 xf->proxy_connection = NULL;
774 xf->proxy_info = NULL;
775 /* Here, start the file transfer.*/
776 purple_xfer_start(xfer, source, NULL, -1);
777 }