📄 send_file.c
字号:
if (packet_len == bytes) qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data); else purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_request", "%d bytes expected but got %d bytes\n", packet_len, bytes); g_free (filelen_str);}/* tell the buddy we want to accept the file */static void _qq_send_packet_file_accept(PurpleConnection *gc, guint32 to_uid){ qq_data *qd; guint8 *cursor, *raw_data; guint16 minor_port; guint32 real_ip; gint packet_len, bytes; ft_info *info; qd = (qq_data *) gc->proto_data; info = (ft_info *) qd->xfer->data; purple_debug(PURPLE_DEBUG_INFO, "QQ", "I've accepted the file transfer request from %d\n", to_uid); _qq_xfer_init_socket(qd->xfer); packet_len = 79; raw_data = g_newa (guint8, packet_len); cursor = raw_data; minor_port = info->local_minor_port; real_ip = info->local_real_ip; info->local_minor_port = 0; info->local_real_ip = 0; bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, QQ_FILE_TRANS_ACC_UDP, qd, TRUE); bytes += qq_fill_conn_info(raw_data, &cursor, info); info->local_minor_port = minor_port; info->local_real_ip = real_ip; if (packet_len == bytes) qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data); else purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_accept", "%d bytes expected but got %d bytes\n", packet_len, bytes);}static void _qq_send_packet_file_notifyip(PurpleConnection *gc, guint32 to_uid){ PurpleXfer *xfer; ft_info *info; qq_data *qd; guint8 *cursor, *raw_data; gint packet_len, bytes; qd = (qq_data *) gc->proto_data; xfer = qd->xfer; info = xfer->data; packet_len = 79; raw_data = g_newa (guint8, packet_len); cursor = raw_data; purple_debug(PURPLE_DEBUG_INFO, "QQ", "<== sending qq file notify ip packet\n"); bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, QQ_FILE_TRANS_NOTIFY, qd, TRUE); bytes += qq_fill_conn_info(raw_data, &cursor, info); if (packet_len == bytes) qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data); else purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_notify", "%d bytes expected but got %d bytes\n", packet_len, bytes); if (xfer->watcher) purple_input_remove(xfer->watcher); xfer->watcher = purple_input_add(info->recv_fd, PURPLE_INPUT_READ, _qq_xfer_recv_packet, xfer); purple_input_add(info->major_fd, PURPLE_INPUT_READ, _qq_xfer_recv_packet, xfer);}/* tell the buddy we don't want the file */static void _qq_send_packet_file_reject (PurpleConnection *gc, guint32 to_uid){ qq_data *qd; guint8 *cursor, *raw_data; gint packet_len, bytes; purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_reject", "start"); qd = (qq_data *) gc->proto_data; packet_len = 64; raw_data = g_newa (guint8, packet_len); cursor = raw_data; bytes = 0; bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, QQ_FILE_TRANS_DENY_UDP, qd, TRUE); if (packet_len == bytes) qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data); else purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file", "%d bytes expected but got %d bytes\n", packet_len, bytes);}/* tell the buddy to cancel transfer */static void _qq_send_packet_file_cancel (PurpleConnection *gc, guint32 to_uid){ qq_data *qd; guint8 *cursor, *raw_data; gint packet_len, bytes; purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "start\n"); qd = (qq_data *) gc->proto_data; packet_len = 64; raw_data = g_newa (guint8, packet_len); cursor = raw_data; bytes = 0; purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "before create header\n"); bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, QQ_FILE_TRANS_CANCEL, qd, TRUE); purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "end create header\n"); if (packet_len == bytes) { purple_debug(PURPLE_DEBUG_INFO, "_qq_send_packet_file_cancel", "before send cmd\n"); qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, cursor - raw_data); } else purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file", "%d bytes expected but got %d bytes\n", packet_len, bytes); purple_debug (PURPLE_DEBUG_INFO, "qq_send_packet_file_cancel", "end\n");}/* request to send a file */static void_qq_xfer_init (PurpleXfer * xfer){ PurpleConnection *gc; PurpleAccount *account; guint32 to_uid; gchar *filename, *filename_without_path; g_return_if_fail (xfer != NULL); account = purple_xfer_get_account(xfer); gc = purple_account_get_connection(account); to_uid = purple_name_to_uid (xfer->who); g_return_if_fail (to_uid != 0); filename = (gchar *) purple_xfer_get_local_filename (xfer); g_return_if_fail (filename != NULL); filename_without_path = strrchr (filename, '/') + 1; _qq_send_packet_file_request (gc, to_uid, filename_without_path, purple_xfer_get_size(xfer));}/* cancel the transfer of receiving files */static void _qq_xfer_cancel(PurpleXfer *xfer){ PurpleConnection *gc; PurpleAccount *account; guint16 *seq; g_return_if_fail (xfer != NULL); seq = (guint16 *) xfer->data; account = purple_xfer_get_account(xfer); gc = purple_account_get_connection(account); switch (purple_xfer_get_status(xfer)) { case PURPLE_XFER_STATUS_CANCEL_LOCAL: _qq_send_packet_file_cancel(gc, purple_name_to_uid(xfer->who)); break; case PURPLE_XFER_STATUS_CANCEL_REMOTE: _qq_send_packet_file_cancel(gc, purple_name_to_uid(xfer->who)); break; case PURPLE_XFER_STATUS_NOT_STARTED: break; case PURPLE_XFER_STATUS_UNKNOWN: _qq_send_packet_file_reject(gc, purple_name_to_uid(xfer->who)); break; case PURPLE_XFER_STATUS_DONE: break; case PURPLE_XFER_STATUS_ACCEPTED: break; case PURPLE_XFER_STATUS_STARTED: break; }}/* init the transfer of receiving files */static void _qq_xfer_recv_init(PurpleXfer *xfer){ PurpleConnection *gc; PurpleAccount *account; ft_info *info; g_return_if_fail (xfer != NULL && xfer->data != NULL); info = (ft_info *) xfer->data; account = purple_xfer_get_account(xfer); gc = purple_account_get_connection(account); _qq_send_packet_file_accept(gc, purple_name_to_uid(xfer->who));}/* process reject im for file transfer request */void qq_process_recv_file_reject (guint8 *data, guint8 **cursor, gint data_len, guint32 sender_uid, PurpleConnection *gc){ gchar *msg, *filename; qq_data *qd; g_return_if_fail (data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; g_return_if_fail (qd->xfer != NULL); if (*cursor >= (data + data_len - 1)) { purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received file reject message is empty\n"); return; } filename = strrchr(purple_xfer_get_local_filename(qd->xfer), '/') + 1; msg = g_strdup_printf(_("%d has declined the file %s"), sender_uid, filename); purple_notify_warning (gc, _("File Send"), msg, NULL); purple_xfer_request_denied(qd->xfer); qd->xfer = NULL; g_free (msg);}/* process cancel im for file transfer request */void qq_process_recv_file_cancel (guint8 *data, guint8 **cursor, gint data_len, guint32 sender_uid, PurpleConnection *gc){ gchar *msg, *filename; qq_data *qd; g_return_if_fail (data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; g_return_if_fail (qd->xfer != NULL && purple_xfer_get_filename(qd->xfer) != NULL); if (*cursor >= (data + data_len - 1)) { purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received file reject message is empty\n"); return; } filename = strrchr(purple_xfer_get_local_filename(qd->xfer), '/') + 1; msg = g_strdup_printf (_("%d canceled the transfer of %s"), sender_uid, filename); purple_notify_warning (gc, _("File Send"), msg, NULL); purple_xfer_cancel_remote(qd->xfer); qd->xfer = NULL; g_free (msg);}/* process accept im for file transfer request */void qq_process_recv_file_accept(guint8 *data, guint8 **cursor, gint data_len, guint32 sender_uid, PurpleConnection *gc){ qq_data *qd; ft_info *info; PurpleXfer *xfer; g_return_if_fail (data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; xfer = qd->xfer; if (*cursor >= (data + data_len - 1)) { purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received file reject message is empty\n"); return; } info = (ft_info *) qd->xfer->data; *cursor = data + 18 + 12; qq_get_conn_info(data, cursor, data_len, info); _qq_xfer_init_socket(qd->xfer); _qq_xfer_init_udp_channel(info); _qq_send_packet_file_notifyip(gc, sender_uid);}/* process request from buddy's im for file transfer request */void qq_process_recv_file_request(guint8 *data, guint8 **cursor, gint data_len, guint32 sender_uid, PurpleConnection * gc){ qq_data *qd; PurpleXfer *xfer; gchar *sender_name, **fileinfo; ft_info *info; PurpleBuddy *b; qq_buddy *q_bud; g_return_if_fail (data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; if (*cursor >= (data + data_len - 1)) { purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received file reject message is empty\n"); return; } info = g_new0(ft_info, 1); info->local_internet_ip = g_ntohl(inet_addr(qd->my_ip)); info->local_internet_port = qd->my_port; info->local_real_ip = 0x00000000; info->to_uid = sender_uid; read_packet_w(data, cursor, data_len, &(info->send_seq)); *cursor = data + 18 + 12; qq_get_conn_info(data, cursor, data_len, info); fileinfo = g_strsplit((gchar *) (data + 81 + 12), "\x1f", 2); g_return_if_fail (fileinfo != NULL && fileinfo[0] != NULL && fileinfo[1] != NULL); sender_name = uid_to_purple_name(sender_uid); /* FACE from IP detector, ignored by gfhuang */ if(g_ascii_strcasecmp(fileinfo[0], "FACE") == 0) { purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Received a FACE ip detect from qq-%d, so he/she must be online :)\n", sender_uid); b = purple_find_buddy(gc->account, sender_name); q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data; if (q_bud) { if(0 != info->remote_real_ip) { g_memmove(q_bud->ip, &info->remote_real_ip, 4); q_bud->port = info->remote_minor_port; } else if (0 != info->remote_internet_ip) { g_memmove(q_bud->ip, &info->remote_internet_ip, 4); q_bud->port = info->remote_major_port; } if(!is_online(q_bud->status)) { q_bud->status = QQ_BUDDY_ONLINE_INVISIBLE; qq_update_buddy_contact(gc, q_bud); } else purple_debug(PURPLE_DEBUG_INFO, "QQ", "buddy %d is already online\n", sender_uid); } else purple_debug(PURPLE_DEBUG_WARNING, "QQ", "buddy %d is not in my friendlist\n", sender_uid); g_free(sender_name); g_strfreev(fileinfo); return; } xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_RECEIVE, sender_name); if (xfer) { purple_xfer_set_filename(xfer, fileinfo[0]); purple_xfer_set_size(xfer, atoi(fileinfo[1])); purple_xfer_set_init_fnc(xfer, _qq_xfer_recv_init); purple_xfer_set_request_denied_fnc(xfer, _qq_xfer_cancel); purple_xfer_set_cancel_recv_fnc(xfer, _qq_xfer_cancel); purple_xfer_set_end_fnc(xfer, _qq_xfer_end); purple_xfer_set_write_fnc(xfer, _qq_xfer_write); xfer->data = info; qd->xfer = xfer; purple_xfer_request(xfer); } g_free(sender_name); g_strfreev(fileinfo);}static void _qq_xfer_send_notify_ip_ack(gpointer data, gint source, PurpleInputCondition cond){ PurpleXfer *xfer = (PurpleXfer *) data; PurpleAccount *account = purple_xfer_get_account(xfer); PurpleConnection *gc = purple_account_get_connection(account); ft_info *info = (ft_info *) xfer->data; purple_input_remove(xfer->watcher); xfer->watcher = purple_input_add(info->recv_fd, PURPLE_INPUT_READ, _qq_xfer_recv_packet, xfer); qq_send_file_ctl_packet(gc, QQ_FILE_CMD_NOTIFY_IP_ACK, info->to_uid, 0); /* info->use_major = TRUE; qq_send_file_ctl_packet(gc, QQ_FILE_CMD_NOTIFY_IP_ACK, info->to_uid, 0); info->use_major = FALSE; */}void qq_process_recv_file_notify(guint8 *data, guint8 **cursor, gint data_len, guint32 sender_uid, PurpleConnection *gc){ qq_data *qd; ft_info *info; PurpleXfer *xfer; g_return_if_fail (data != NULL && data_len != 0); qd = (qq_data *) gc->proto_data; if (*cursor >= (data + data_len - 1)) { purple_debug (PURPLE_DEBUG_WARNING, "QQ", "Received file notify message is empty\n"); return; } xfer = qd->xfer; info = (ft_info *) qd->xfer->data; /* FIXME */ read_packet_w(data, cursor, data_len, &(info->send_seq)); *cursor = data + 18 + 12; qq_get_conn_info(data, cursor, data_len, info); _qq_xfer_init_udp_channel(info); xfer->watcher = purple_input_add(info->sender_fd, PURPLE_INPUT_WRITE, _qq_xfer_send_notify_ip_ack, xfer);}/* temp placeholder until a working function can be implemented */gboolean qq_can_receive_file(PurpleConnection *gc, const char *who){ return TRUE;}void qq_send_file(PurpleConnection *gc, const char *who, const char *file){ qq_data *qd; PurpleXfer *xfer; qd = (qq_data *) gc->proto_data; xfer = purple_xfer_new (gc->account, PURPLE_XFER_SEND, who); if (xfer) { purple_xfer_set_init_fnc (xfer, _qq_xfer_init); purple_xfer_set_cancel_send_fnc (xfer, _qq_xfer_cancel); purple_xfer_set_write_fnc(xfer, _qq_xfer_write); qd->xfer = xfer; purple_xfer_request(xfer); }}/*static void qq_send_packet_request_key(PurpleConnection *gc, guint8 key){ qq_send_cmd(gc, QQ_CMD_REQUEST_KEY, TRUE, 0, TRUE, &key, 1);}static void qq_process_recv_request_key(PurpleConnection *gc){}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -