| 1505 static void oscar_cancel_direct_im(struct ask_do_dir_im *data) { |
1505 static void oscar_cancel_direct_im(struct ask_do_dir_im *data) { |
| 1506 g_free(data->who); |
1506 g_free(data->who); |
| 1507 g_free(data); |
1507 g_free(data); |
| 1508 } |
1508 } |
| 1509 |
1509 |
| |
1510 struct dir_im_listen { |
| |
1511 struct oscar_direct_im *dim; |
| |
1512 const guchar *cookie; |
| |
1513 }; |
| |
1514 |
| |
1515 static void |
| |
1516 oscar_direct_im_listen_cb(int listenfd, gpointer data) { |
| |
1517 struct dir_im_listen *dim_l = data; |
| |
1518 const char *ip; |
| |
1519 OscarData *od; |
| |
1520 struct oscar_direct_im *dim = dim_l->dim; |
| |
1521 |
| |
1522 od = (OscarData *)dim->gc->proto_data; |
| |
1523 |
| |
1524 /* XXX: shouldn't this be your public IP or something? */ |
| |
1525 ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); |
| |
1526 |
| |
1527 if (listenfd >= 0) |
| |
1528 dim->conn = aim_odc_initiate(od->sess, dim->name, listenfd, |
| |
1529 gaim_network_ip_atoi(ip), |
| |
1530 gaim_network_get_port_from_fd(listenfd), dim_l->cookie); |
| |
1531 |
| |
1532 if (dim->conn != NULL) { |
| |
1533 char *tmp; |
| |
1534 GaimConversation *conv; |
| |
1535 |
| |
1536 od->direct_ims = g_slist_append(od->direct_ims, dim); |
| |
1537 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
| |
1538 oscar_callback, dim->conn); |
| |
1539 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, |
| |
1540 gaim_odc_initiate, 0); |
| |
1541 |
| |
1542 conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, dim->name); |
| |
1543 tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), dim->name, ip, |
| |
1544 gaim_network_get_port_from_fd(listenfd)); |
| |
1545 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); |
| |
1546 g_free(tmp); |
| |
1547 } else { |
| |
1548 gaim_notify_error(dim->gc, NULL, _("Unable to open Direct IM"), NULL); |
| |
1549 oscar_direct_im_destroy(od, dim); |
| |
1550 } |
| |
1551 |
| |
1552 g_free(dim_l); |
| |
1553 } |
| |
1554 |
| 1510 /* this function is used to initiate a direct im session with someone. |
1555 /* this function is used to initiate a direct im session with someone. |
| 1511 * we start listening on a port and send a request. they either connect |
1556 * we start listening on a port and send a request. they either connect |
| 1512 * or send some kind of reply. If they can't connect, they ask us to |
1557 * or send some kind of reply. If they can't connect, they ask us to |
| 1513 * connect to them, and so we do that. |
1558 * connect to them, and so we do that. |
| 1514 * |
1559 * |
| 1518 * note that cookie is an 8 byte string that isn't NULL terminated |
1563 * note that cookie is an 8 byte string that isn't NULL terminated |
| 1519 */ |
1564 */ |
| 1520 static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const guchar *cookie) { |
1565 static void oscar_direct_im_initiate(GaimConnection *gc, const char *who, const guchar *cookie) { |
| 1521 OscarData *od; |
1566 OscarData *od; |
| 1522 struct oscar_direct_im *dim; |
1567 struct oscar_direct_im *dim; |
| 1523 int listenfd; |
1568 struct dir_im_listen *dim_l; |
| 1524 const char *ip; |
|
| 1525 |
1569 |
| 1526 od = (OscarData *)gc->proto_data; |
1570 od = (OscarData *)gc->proto_data; |
| 1527 |
1571 |
| 1528 dim = oscar_direct_im_find(od, who); |
1572 dim = oscar_direct_im_find(od, who); |
| 1529 if (dim) { |
1573 if (dim) { |
| 1538 } |
1582 } |
| 1539 dim = g_new0(struct oscar_direct_im, 1); |
1583 dim = g_new0(struct oscar_direct_im, 1); |
| 1540 dim->gc = gc; |
1584 dim->gc = gc; |
| 1541 g_snprintf(dim->name, sizeof dim->name, "%s", who); |
1585 g_snprintf(dim->name, sizeof dim->name, "%s", who); |
| 1542 |
1586 |
| 1543 listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM); |
1587 dim_l = g_new0(struct dir_im_listen, 1); |
| 1544 ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); |
1588 dim_l->dim = dim; |
| 1545 if (listenfd >= 0) |
1589 dim_l->cookie = cookie; |
| 1546 dim->conn = aim_odc_initiate(od->sess, who, listenfd, gaim_network_ip_atoi(ip), gaim_network_get_port_from_fd(listenfd), cookie); |
1590 |
| 1547 if (dim->conn != NULL) { |
1591 if(!gaim_network_listen_range(5190, 5199, SOCK_STREAM, oscar_direct_im_listen_cb, dim)) { |
| 1548 char *tmp; |
|
| 1549 GaimConversation *conv; |
|
| 1550 |
|
| 1551 od->direct_ims = g_slist_append(od->direct_ims, dim); |
|
| 1552 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, |
|
| 1553 oscar_callback, dim->conn); |
|
| 1554 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED, |
|
| 1555 gaim_odc_initiate, 0); |
|
| 1556 |
|
| 1557 conv = gaim_conversation_new(GAIM_CONV_TYPE_IM, dim->gc->account, who); |
|
| 1558 tmp = g_strdup_printf(_("Asking %s to connect to us at %s:%hu for Direct IM."), who, ip, |
|
| 1559 gaim_network_get_port_from_fd(listenfd)); |
|
| 1560 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); |
|
| 1561 g_free(tmp); |
|
| 1562 } else { |
|
| 1563 gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL); |
1592 gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL); |
| 1564 oscar_direct_im_destroy(od, dim); |
1593 oscar_direct_im_destroy(od, dim); |
| |
1594 g_free(dim_l); |
| 1565 } |
1595 } |
| 1566 } |
1596 } |
| 1567 |
1597 |
| 1568 static void oscar_direct_im(struct ask_do_dir_im *data) { |
1598 static void oscar_direct_im(struct ask_do_dir_im *data) { |
| 1569 GaimConnection *gc = data->gc; |
1599 GaimConnection *gc = data->gc; |
| 2543 _("Unable to establish listener socket or no AOL proxy connection present.")); |
2573 _("Unable to establish listener socket or no AOL proxy connection present.")); |
| 2544 gaim_xfer_cancel_local(xfer); |
2574 gaim_xfer_cancel_local(xfer); |
| 2545 } |
2575 } |
| 2546 } |
2576 } |
| 2547 |
2577 |
| |
2578 static void |
| |
2579 oscar_xfer_init_listen_cb(int listenfd, gpointer data) { |
| |
2580 GaimXfer *xfer = data; |
| |
2581 struct aim_oft_info *oft_info; |
| |
2582 GaimConnection *gc; |
| |
2583 OscarData *od; |
| |
2584 |
| |
2585 /* If the ft was canceled before we get here, don't continue */ |
| |
2586 if(gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) { |
| |
2587 gaim_xfer_unref(xfer); |
| |
2588 return; |
| |
2589 } |
| |
2590 |
| |
2591 oft_info = xfer->data; |
| |
2592 gc = oft_info->sess->aux_data; |
| |
2593 od = gc->proto_data; |
| |
2594 |
| |
2595 if (listenfd < 0) { |
| |
2596 gaim_xfer_cancel_local(xfer); |
| |
2597 return; |
| |
2598 } |
| |
2599 |
| |
2600 xfer->local_port = gaim_network_get_port_from_fd(listenfd); |
| |
2601 oft_info->port = xfer->local_port; |
| |
2602 if (aim_sendfile_listen(od->sess, oft_info, listenfd) != 0) { |
| |
2603 gaim_xfer_cancel_local(xfer); |
| |
2604 return; |
| |
2605 } |
| |
2606 gaim_debug_misc("oscar", |
| |
2607 "port is %hu, ip is %s\n", |
| |
2608 xfer->local_port, oft_info->clientip); |
| |
2609 |
| |
2610 if(oft_info->conn) |
| |
2611 xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, |
| |
2612 oft_info->conn); |
| |
2613 else |
| |
2614 gaim_debug_info("oscar","NULL oft_info->conn; not adding watcher\n"); |
| |
2615 |
| |
2616 oscar_send_file_request(xfer); |
| |
2617 } |
| |
2618 |
| 2548 |
2619 |
| 2549 /* |
2620 /* |
| 2550 * Opens a listener socket in preparation for sending a file |
2621 * Opens a listener socket in preparation for sending a file |
| 2551 * This is not called if we are using a rendezvous proxy server |
2622 * This is not called if we are using a rendezvous proxy server |
| 2552 */ |
2623 */ |
| 2553 static void oscar_xfer_init_send(GaimXfer *xfer) |
2624 static void oscar_xfer_init_send(GaimXfer *xfer) |
| 2554 { |
2625 { |
| 2555 struct aim_oft_info *oft_info = xfer->data; |
|
| 2556 GaimConnection *gc = oft_info->sess->aux_data; |
|
| 2557 OscarData *od = gc->proto_data; |
|
| 2558 int listenfd; |
|
| 2559 |
|
| 2560 gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); |
2626 gaim_debug_info("oscar", "AAA - in oscar_xfer_init_send\n"); |
| 2561 |
2627 |
| |
2628 gaim_xfer_ref(xfer); |
| |
2629 |
| 2562 /* Create a listening socket and an associated libfaim conn */ |
2630 /* Create a listening socket and an associated libfaim conn */ |
| 2563 if ((listenfd = gaim_network_listen_range(5190, 5199, SOCK_STREAM)) < 0) { |
2631 if (!gaim_network_listen_range(5190, 5199, SOCK_STREAM, |
| |
2632 oscar_xfer_init_listen_cb, xfer)) { |
| |
2633 gaim_xfer_unref(xfer); |
| 2564 gaim_xfer_cancel_local(xfer); |
2634 gaim_xfer_cancel_local(xfer); |
| 2565 return; |
2635 return; |
| 2566 } |
2636 } |
| 2567 xfer->local_port = gaim_network_get_port_from_fd(listenfd); |
|
| 2568 oft_info->port = xfer->local_port; |
|
| 2569 if (aim_sendfile_listen(od->sess, oft_info, listenfd) != 0) { |
|
| 2570 gaim_xfer_cancel_local(xfer); |
|
| 2571 return; |
|
| 2572 } |
|
| 2573 gaim_debug_misc("oscar", |
|
| 2574 "port is %hu, ip is %s\n", |
|
| 2575 xfer->local_port, oft_info->clientip); |
|
| 2576 |
|
| 2577 if(oft_info->conn) |
|
| 2578 xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, |
|
| 2579 oft_info->conn); |
|
| 2580 else |
|
| 2581 gaim_debug_info("oscar","NULL oft_info->conn; not adding watcher\n"); |
|
| 2582 |
|
| 2583 oscar_send_file_request(xfer); |
|
| 2584 } |
2637 } |
| 2585 |
2638 |
| 2586 /* |
2639 /* |
| 2587 * "On second thought, you don't deserve this file." |
2640 * "On second thought, you don't deserve this file." |
| 2588 */ |
2641 */ |