/** * Someone else wants to establish a peer connection with us. */ void peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args) { PurpleConnection *gc; PurpleAccount *account; PeerConnection *conn; gchar *buf; gc = od->gc; account = purple_connection_get_account(gc); /* * If we have a connection with this same cookie then they are * probably just telling us they weren't able to connect to us * and we should try connecting to them, instead. Or they want * to go through a proxy. */ conn = peer_connection_find_by_cookie(od, bn, args->cookie); if ((conn != NULL) && (conn->type == args->type)) { purple_debug_info("oscar", "Remote user wants to try a " "different connection method\n"); g_free(conn->proxyip); g_free(conn->clientip); g_free(conn->verifiedip); if (args->use_proxy) conn->proxyip = g_strdup(args->proxyip); else conn->proxyip = NULL; conn->verifiedip = g_strdup(args->verifiedip); conn->clientip = g_strdup(args->clientip); conn->port = args->port; conn->use_proxy |= args->use_proxy; conn->lastrequestnumber++; peer_connection_trynext(conn); return; } /* If this is a direct IM, then close any existing session */ if (args->type == OSCAR_CAPABILITY_DIRECTIM) { conn = peer_connection_find_by_type(od, bn, args->type); if (conn != NULL) { /* Close the old direct IM and start a new one */ purple_debug_info("oscar", "Received new direct IM request " "from %s. Destroying old connection.\n", bn); peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL); } } /* Check for proper arguments */ if (args->type == OSCAR_CAPABILITY_SENDFILE) { if ((args->info.sendfile.filename == NULL) || (args->info.sendfile.totsize == 0) || (args->info.sendfile.totfiles == 0)) { purple_debug_warning("oscar", "%s tried to send you a file with incomplete " "information.\n", bn); return; } } conn = peer_connection_new(od, args->type, bn); memcpy(conn->cookie, args->cookie, 8); if (args->use_proxy) conn->proxyip = g_strdup(args->proxyip); conn->clientip = g_strdup(args->clientip); conn->verifiedip = g_strdup(args->verifiedip); conn->port = args->port; conn->use_proxy |= args->use_proxy; conn->lastrequestnumber++; if (args->type == OSCAR_CAPABILITY_DIRECTIM) { buf = g_strdup_printf(_("%s has just asked to directly connect to %s"), bn, purple_account_get_username(account)); purple_request_action(conn, NULL, buf, _("This requires a direct connection between " "the two computers and is necessary for IM " "Images. Because your IP address will be " "revealed, this may be considered a privacy " "risk."), PURPLE_DEFAULT_ACTION_NONE, account, bn, NULL, conn, 2, _("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb), _("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb)); } else if (args->type == OSCAR_CAPABILITY_SENDFILE) { gchar *filename; conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn); if (conn->xfer) { conn->xfer->data = conn; purple_xfer_ref(conn->xfer); purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize); /* Set the file name */ if (g_utf8_validate(args->info.sendfile.filename, -1, NULL)) filename = g_strdup(args->info.sendfile.filename); else filename = purple_utf8_salvage(args->info.sendfile.filename); if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR) { /* * If they are sending us a directory then the last character * of the file name will be an asterisk. We don't want to * save stuff to a directory named "*" so we remove the * asterisk from the file name. */ char *tmp = strrchr(filename, '\\'); if ((tmp != NULL) && (tmp[1] == '*')) tmp[0] = '\0'; } purple_xfer_set_filename(conn->xfer, filename); g_free(filename); /* * Set the message, unless this is the dummy message from an * ICQ client or an empty message from an AIM client. * TODO: Maybe we should strip HTML and then see if strlen>0? */ if ((message != NULL) && (g_ascii_strncasecmp(message, "<ICQ_COOL_FT>", 13) != 0) && (g_ascii_strcasecmp(message, "<HTML>") != 0)) { purple_xfer_set_message(conn->xfer, message); } /* Setup our I/O op functions */ purple_xfer_set_init_fnc(conn->xfer, peer_oft_recvcb_init); purple_xfer_set_end_fnc(conn->xfer, peer_oft_recvcb_end); purple_xfer_set_request_denied_fnc(conn->xfer, peer_oft_cb_generic_cancel); purple_xfer_set_cancel_recv_fnc(conn->xfer, peer_oft_cb_generic_cancel); purple_xfer_set_ack_fnc(conn->xfer, peer_oft_recvcb_ack_recv); /* Now perform the request */ purple_xfer_request(conn->xfer); } } }
/* This function makes the necessary arrangements for receiving files */ void irc_dccsend_recv(struct irc_conn *irc, const char *from, const char *msg) { PurpleXfer *xfer; struct irc_xfer_rx_data *xd; gchar **token; struct in_addr addr; GString *filename; int i = 0; guint32 nip; token = g_strsplit(msg, " ", 0); if (!token[0] || !token[1] || !token[2]) { g_strfreev(token); return; } filename = g_string_new(""); if (token[0][0] == '"') { if (!strchr(&(token[0][1]), '"')) { g_string_append(filename, &(token[0][1])); for (i = 1; token[i]; i++) if (!strchr(token[i], '"')) { g_string_append_printf(filename, " %s", token[i]); } else { g_string_append_len(filename, token[i], strlen(token[i]) - 1); break; } } else { g_string_append_len(filename, &(token[0][1]), strlen(&(token[0][1])) - 1); } } else { g_string_append(filename, token[0]); } if (!token[i] || !token[i+1] || !token[i+2]) { g_strfreev(token); g_string_free(filename, TRUE); return; } i++; xfer = purple_xfer_new(irc->account, PURPLE_XFER_RECEIVE, from); if (xfer) { xd = g_new0(struct irc_xfer_rx_data, 1); xfer->data = xd; purple_xfer_set_filename(xfer, filename->str); xfer->remote_port = atoi(token[i+1]); nip = strtoul(token[i], NULL, 10); if (nip) { addr.s_addr = htonl(nip); xd->ip = g_strdup(inet_ntoa(addr)); } else { xd->ip = g_strdup(token[i]); } purple_debug(PURPLE_DEBUG_INFO, "irc", "Receiving file from %s\n", xd->ip); purple_xfer_set_size(xfer, token[i+2] ? atoi(token[i+2]) : 0); purple_xfer_set_init_fnc(xfer, irc_dccsend_recv_init); purple_xfer_set_ack_fnc(xfer, irc_dccsend_recv_ack); purple_xfer_set_end_fnc(xfer, irc_dccsend_recv_destroy); purple_xfer_set_request_denied_fnc(xfer, irc_dccsend_recv_destroy); purple_xfer_set_cancel_send_fnc(xfer, irc_dccsend_recv_destroy); purple_xfer_request(xfer); } g_strfreev(token); g_string_free(filename, TRUE); }