void mrim_xfer_send_rq(PurpleXfer *xfer) { gchar *file_name = purple_xfer_get_local_filename(xfer); purple_debug_info("mrim-prpl", "[%s] Sending file '%s'\n", __func__, file_name); MrimFT *mrim_ft = xfer->data; mrim_ft->xfer = xfer; mrim_ft->count = 1; mrim_ft->files = g_new0(MrimFT, 1); mrim_ft->files[0].name = basename(file_name); // TODO: strdup??? { GRand *rnd = g_rand_new(); mrim_ft->id = g_rand_int(rnd); g_rand_free(rnd); } { struct stat st; stat(file_name, &st); mrim_ft->files[0].size = st.st_size; } MrimData *mrim = mrim_ft->mrim; MrimPackage *pack = mrim_package_new(mrim->seq++, MRIM_CS_FILE_TRANSFER); mrim_package_add_LPSA(pack, mrim_ft->user_name); mrim_package_add_UL(pack, mrim_ft->id); mrim_package_add_UL(pack, mrim_ft->files[0].size); gchar *file_list = g_strdup_printf("%s;%u;", mrim_ft->files[0].name, mrim_ft->files[0].size); gchar *my_ip = "1.2.3.4:1234;"; // Заведомо некорректное значение, чтобы клиент обломался и пошёл использовать зеркальный прокси TODO mrim_package_add_UL(pack, 4 + strlen(file_list) + 4 + 4 + strlen(my_ip)); mrim_package_add_LPSA(pack, file_list); mrim_package_add_UL(pack, 0); mrim_package_add_LPSA(pack, my_ip); //mrim_add_ack_cb(mrim, pack->header->seq, mrim_xfer_ack, xfer); g_hash_table_insert(mrim->transfers, GUINT_TO_POINTER(mrim_ft->id), xfer); mrim_package_send(pack, mrim); }
void mrim_send_xfer_connect_cb(gpointer data, gint source, const gchar *error_message) { purple_debug_info("mrim-prpl", "[%s]\n", __func__); MrimFT *ft = data; ft->proxy_conn = NULL; if (source >= 0) { purple_debug_info("mrim-prpl", "[%s] Connected!\n", __func__); ft->conn = source; ft->state = WAITING_FOR_HELLO_ACK; MrimData *mrim = ft->mrim; MrimData *fake_mrim = g_new0(MrimData, 1); fake_mrim->fd = source; ft->fake_mrim = fake_mrim; MrimPackage *pack = mrim_package_new(0, MRIM_CS_PROXY_HELLO); pack->header->proto = 0x00010009; mrim_package_add_UL(pack, ft->proxy_id[0]); mrim_package_add_UL(pack, ft->proxy_id[1]); mrim_package_add_UL(pack, ft->proxy_id[2]); mrim_package_add_UL(pack, ft->proxy_id[3]); if (mrim_package_send(pack, fake_mrim)) { ft->inpa = purple_input_add(ft->conn, PURPLE_INPUT_READ, mrim_ft_send_input_cb, ft); purple_debug_info("mrim-prpl", "[%s] MRIM_CS_PROXY_HELLO sent!\n", __func__); } else { purple_debug_info("mrim-prpl", "[%s] Failed to send MRIM_CS_PROXY_HELLO!\n", __func__); purple_xfer_unref(ft->xfer); } } else { purple_debug_info("mrim-prpl", "[%s] Fail!\n", __func__); purple_xfer_unref(ft->xfer); } }
void mrim_xfer_ack(MrimPackage *pack, MrimData *mrim) { purple_debug_info("mrim-prpl", "[%s] MRIM_CS_FILE_TRANSFER_ACK\n", __func__); guint32 status = mrim_package_read_UL(pack); gchar *user_name = mrim_package_read_LPSA(pack); guint32 id = mrim_package_read_UL(pack); gchar *remote_addr = mrim_package_read_LPSA(pack); purple_debug_info("mrim-prpl", "[%s] MRIM_CS_FILE_TRANSFER_ACK: status = %u, user_name = '%s', remote_addr = '%s'\n", __func__, status, user_name, remote_addr); PurpleXfer *xfer = g_hash_table_lookup(mrim->transfers, GUINT_TO_POINTER(id)); if (xfer) { if (status == FILE_TRANSFER_MIRROR) { MrimFT *ft = xfer->data; purple_debug_info("mrim-prpl", "[%s] User='******' accepted files! id='%xu'\n", __func__, user_name, id); //Допустим белого IP у нас нет и запросим зеркальный прокси TODO MrimPackage *ack = mrim_package_new(mrim->seq++, MRIM_CS_PROXY); mrim_package_add_LPSA(ack, user_name); mrim_package_add_UL(ack, id); mrim_package_add_UL(ack, MRIM_PROXY_TYPE_FILES); gchar *file_list = g_strdup_printf("%s;%u;", ft->files[0].name, ft->files[0].size); mrim_package_add_LPSA(ack, file_list); mrim_package_add_UL(ack, 0); // Много- mrim_package_add_UL(ack, 0); // много mrim_package_add_UL(ack, 0); // не mrim_package_add_UL(ack, 0); // нужных mrim_package_add_UL(ack, 0); // полей mrim_package_add_UL(ack, 4 + 4 + strlen(file_list) * 2); //Длина последующихъ данных // Судя по всему далее идёт повтор пакета, но в UTF16 mrim_package_add_UL(ack, MRIM_PROXY_TYPE_FILES); mrim_package_add_LPSW(ack, file_list); mrim_package_add_UL(ack, 4); // Неизвестное поле mrim_package_add_UL(ack, 1); // Ещё одно неизвестно поле... Имеет смысл узнать, что это... mrim_package_send(ack, mrim); } else { purple_debug_info("mrim-prpl", "[%s] Transfer cancelled!\n", __func__); purple_xfer_unref(xfer); } } g_free(user_name); g_free(remote_addr); }