| 75 } |
75 } |
| 76 return 0; |
76 return 0; |
| 77 } |
77 } |
| 78 |
78 |
| 79 /* these 2 functions send and recv buffer from/to UDP channel */ |
79 /* these 2 functions send and recv buffer from/to UDP channel */ |
| 80 static ssize_t _qq_xfer_udp_recv(char *buf, size_t len, GaimXfer *xfer) |
80 static ssize_t _qq_xfer_udp_recv(guint8 *buf, size_t len, GaimXfer *xfer) |
| 81 { |
81 { |
| 82 struct sockaddr_in sin; |
82 struct sockaddr_in sin; |
| 83 int sinlen; |
83 socklen_t sinlen; |
| 84 ft_info *info; |
84 ft_info *info; |
| 85 int r; |
85 gint r; |
| 86 |
86 |
| 87 info = (ft_info *) xfer->data; |
87 info = (ft_info *) xfer->data; |
| 88 sinlen = sizeof(sin); |
88 sinlen = sizeof(sin); |
| 89 r = recvfrom(info->recv_fd, buf, len, 0, (struct sockaddr *) &sin, &sinlen); |
89 r = recvfrom(info->recv_fd, buf, len, 0, (struct sockaddr *) &sin, &sinlen); |
| 90 gaim_debug(GAIM_DEBUG_INFO, "QQ", |
90 gaim_debug(GAIM_DEBUG_INFO, "QQ", |
| 100 |
100 |
| 101 info = (ft_info *) xfer->data; |
101 info = (ft_info *) xfer->data; |
| 102 return send(info->sender_fd, buf, len, 0); |
102 return send(info->sender_fd, buf, len, 0); |
| 103 } |
103 } |
| 104 */ |
104 */ |
| 105 static ssize_t _qq_xfer_udp_send(const char *buf, size_t len, GaimXfer *xfer) |
105 static ssize_t _qq_xfer_udp_send(const guint8 *buf, size_t len, GaimXfer *xfer) |
| 106 { |
106 { |
| 107 struct sockaddr_in sin; |
107 struct sockaddr_in sin; |
| 108 ft_info *info; |
108 ft_info *info; |
| 109 |
109 |
| 110 info = (ft_info *) xfer->data; |
110 info = (ft_info *) xfer->data; |
| 138 *buf = g_newa(char, QQ_FILE_FRAGMENT_MAXLEN + 100); |
138 *buf = g_newa(char, QQ_FILE_FRAGMENT_MAXLEN + 100); |
| 139 return _qq_xfer_udp_recv(*buf, QQ_FILE_FRAGMENT_MAXLEN + 100, xfer); |
139 return _qq_xfer_udp_recv(*buf, QQ_FILE_FRAGMENT_MAXLEN + 100, xfer); |
| 140 } |
140 } |
| 141 */ |
141 */ |
| 142 |
142 |
| 143 gssize _qq_xfer_write(const guchar *buf, size_t len, GaimXfer *xfer) |
143 gssize _qq_xfer_write(const guint8 *buf, size_t len, GaimXfer *xfer) |
| 144 { |
144 { |
| 145 return _qq_xfer_udp_send(buf, len, xfer); |
145 return _qq_xfer_udp_send(buf, len, xfer); |
| 146 } |
146 } |
| 147 |
147 |
| 148 static void _qq_xfer_recv_packet(gpointer data, gint source, GaimInputCondition condition) |
148 static void _qq_xfer_recv_packet(gpointer data, gint source, GaimInputCondition condition) |
| 444 info->local_internet_port = qd->my_port; |
445 info->local_internet_port = qd->my_port; |
| 445 info->local_real_ip = 0x00000000; |
446 info->local_real_ip = 0x00000000; |
| 446 info->conn_method = 0x00; |
447 info->conn_method = 0x00; |
| 447 qd->xfer->data = info; |
448 qd->xfer->data = info; |
| 448 |
449 |
| 449 filename_len = strlen (filename); |
450 filename_len = strlen(filename); |
| 450 filelen_str = g_strdup_printf ("%d ×Ö½Ú", filesize); |
451 filelen_str = g_strdup_printf("%d ×Ö½Ú", filesize); |
| 451 filelen_strlen = strlen (filelen_str); |
452 filelen_strlen = strlen(filelen_str); |
| 452 |
453 |
| 453 packet_len = 82 + filename_len + filelen_strlen; |
454 packet_len = 82 + filename_len + filelen_strlen; |
| 454 raw_data = g_newa (guint8, packet_len); |
455 raw_data = g_newa(guint8, packet_len); |
| 455 cursor = raw_data; |
456 cursor = raw_data; |
| 456 |
457 |
| 457 bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, QQ_FILE_TRANS_REQ, qd, FALSE); |
458 bytes = _qq_create_packet_file_header(raw_data, &cursor, to_uid, |
| |
459 QQ_FILE_TRANS_REQ, qd, FALSE); |
| 458 bytes += qq_fill_conn_info(raw_data, &cursor, info); |
460 bytes += qq_fill_conn_info(raw_data, &cursor, info); |
| 459 /* 079: 0x20 */ |
461 /* 079: 0x20 */ |
| 460 bytes += create_packet_b (raw_data, &cursor, 0x20); |
462 bytes += create_packet_b (raw_data, &cursor, 0x20); |
| 461 /* 080: 0x1f */ |
463 /* 080: 0x1f */ |
| 462 bytes += create_packet_b (raw_data, &cursor, 0x1f); |
464 bytes += create_packet_b (raw_data, &cursor, 0x1f); |
| 463 /* undetermined len: filename */ |
465 /* undetermined len: filename */ |
| 464 bytes += create_packet_data (raw_data, &cursor, filename, |
466 bytes += create_packet_data (raw_data, &cursor, (guint8 *) filename, |
| 465 filename_len); |
467 filename_len); |
| 466 /* 0x1f */ |
468 /* 0x1f */ |
| 467 bytes += create_packet_b (raw_data, &cursor, 0x1f); |
469 bytes += create_packet_b (raw_data, &cursor, 0x1f); |
| 468 /* file length */ |
470 /* file length */ |
| 469 bytes += create_packet_data (raw_data, &cursor, filelen_str, |
471 bytes += create_packet_data (raw_data, &cursor, (guint8 *) filelen_str, |
| 470 filelen_strlen); |
472 filelen_strlen); |
| 471 |
473 |
| 472 if (packet_len == bytes) |
474 if (packet_len == bytes) |
| 473 qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, |
475 qq_send_cmd (gc, QQ_CMD_SEND_IM, TRUE, 0, TRUE, raw_data, |
| 474 cursor - raw_data); |
476 cursor - raw_data); |
| 483 /* tell the buddy we want to accept the file */ |
485 /* tell the buddy we want to accept the file */ |
| 484 static void _qq_send_packet_file_accept(GaimConnection *gc, guint32 to_uid) |
486 static void _qq_send_packet_file_accept(GaimConnection *gc, guint32 to_uid) |
| 485 { |
487 { |
| 486 qq_data *qd; |
488 qq_data *qd; |
| 487 guint8 *cursor, *raw_data; |
489 guint8 *cursor, *raw_data; |
| |
490 guint16 minor_port; |
| |
491 guint32 real_ip; |
| 488 gint packet_len, bytes; |
492 gint packet_len, bytes; |
| 489 ft_info *info; |
493 ft_info *info; |
| 490 |
494 |
| 491 g_return_if_fail (gc != NULL && gc->proto_data != NULL); |
495 g_return_if_fail (gc != NULL && gc->proto_data != NULL); |
| 492 qd = (qq_data *) gc->proto_data; |
496 qd = (qq_data *) gc->proto_data; |
| 493 info = (ft_info *) qd->xfer->data; |
497 info = (ft_info *) qd->xfer->data; |
| 494 |
498 |
| 495 gaim_debug(GAIM_DEBUG_INFO, "QQ", "I've accepted the file transfer request from %d\n", to_uid); |
499 gaim_debug(GAIM_DEBUG_INFO, "QQ", "I've accepted the file transfer request from %d\n", to_uid); |
| 496 _qq_xfer_init_socket(qd->xfer); |
500 _qq_xfer_init_socket(qd->xfer); |
| 497 guint16 minor_port; |
|
| 498 guint32 real_ip; |
|
| 499 |
501 |
| 500 packet_len = 79; |
502 packet_len = 79; |
| 501 raw_data = g_newa (guint8, packet_len); |
503 raw_data = g_newa (guint8, packet_len); |
| 502 cursor = raw_data; |
504 cursor = raw_data; |
| 503 |
505 |
| 801 read_packet_w(data, cursor, data_len, &(info->send_seq)); |
803 read_packet_w(data, cursor, data_len, &(info->send_seq)); |
| 802 |
804 |
| 803 *cursor = data + 18 + 12; |
805 *cursor = data + 18 + 12; |
| 804 qq_get_conn_info(data, cursor, data_len, info); |
806 qq_get_conn_info(data, cursor, data_len, info); |
| 805 |
807 |
| 806 gchar **fileinfo; |
808 fileinfo = g_strsplit((gchar *) (data + 81 + 12), "\x1f", 2); |
| 807 fileinfo = g_strsplit(data + 81 + 12, "\x1f", 2); |
|
| 808 g_return_if_fail (fileinfo != NULL && fileinfo[0] != NULL && fileinfo[1] != NULL); |
809 g_return_if_fail (fileinfo != NULL && fileinfo[0] != NULL && fileinfo[1] != NULL); |
| 809 |
810 |
| 810 sender_name = uid_to_gaim_name(sender_uid); |
811 sender_name = uid_to_gaim_name(sender_uid); |
| 811 |
812 |
| 812 /* FACE from IP detector, ignored by gfhuang */ |
813 /* FACE from IP detector, ignored by gfhuang */ |