2086
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2
|
|
3 /*
|
|
4 * $Id: tcpfilehandle.c 2096 2001-07-31 01:00:39Z warmenhoven $
|
|
5 *
|
|
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
|
|
7 * Bill Soudan <soudan@kde.org>
|
|
8 *
|
|
9 * This program is free software; you can redistribute it and/or modify
|
|
10 * it under the terms of the GNU General Public License as published by
|
|
11 * the Free Software Foundation; either version 2 of the License, or
|
|
12 * (at your option) any later version.
|
|
13 *
|
|
14 * This program is distributed in the hope that it will be useful,
|
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 * GNU General Public License for more details.
|
|
18 *
|
|
19 * You should have received a copy of the GNU General Public License
|
|
20 * along with this program; if not, write to the Free Software
|
|
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 #ifdef _MSVC_
|
|
26 #include <io.h>
|
|
27 #define open _open
|
|
28 #define close _close
|
|
29 #define read _read
|
|
30 #define write _write
|
|
31 #endif
|
|
32
|
|
33 #include <errno.h>
|
|
34
|
|
35 #include "icqlib.h"
|
|
36
|
|
37 #include "tcp.h"
|
|
38 #include "stdpackets.h"
|
|
39 #include "filesession.h"
|
|
40
|
|
41 void icq_TCPOnFileReqReceived(icq_Link *icqlink, DWORD uin, const char *message,
|
|
42 const char *filename, unsigned long filesize, DWORD id)
|
|
43 {
|
|
44 /* use the current system time for time received */
|
|
45 time_t t=time(0);
|
|
46 struct tm *ptime=localtime(&t);
|
|
47
|
|
48 #ifdef TCP_PACKET_TRACE
|
|
49 printf("file request packet received from %lu { sequence=%lx, message=%s }\n",
|
|
50 uin, id, message);
|
|
51 #endif
|
|
52
|
|
53 invoke_callback(icqlink,icq_RecvFileReq)(icqlink, uin, ptime->tm_hour,
|
|
54 ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900,
|
|
55 message, filename, filesize, id);
|
|
56
|
|
57 /* don't send an acknowledgement to the remote client!
|
|
58 * GUI is responsible for sending acknowledgement once user accepts
|
|
59 * or denies using icq_TCPSendFileAck */
|
|
60 }
|
|
61
|
|
62 void icq_TCPProcessFilePacket(icq_Packet *p, icq_TCPLink *plink)
|
|
63 {
|
|
64 icq_FileSession *psession=(icq_FileSession *)plink->session;
|
|
65 icq_Link *icqlink = plink->icqlink;
|
|
66 BYTE type;
|
|
67 DWORD num_files;
|
|
68 DWORD total_bytes;
|
|
69 DWORD speed;
|
|
70 DWORD filesize;
|
|
71 const char *name;
|
|
72 int result;
|
|
73
|
|
74 icq_Packet *presponse;
|
|
75
|
|
76 icq_PacketBegin(p);
|
|
77
|
|
78 type=icq_PacketRead8(p);
|
|
79
|
|
80 switch(type)
|
|
81 {
|
|
82 case 0x00:
|
|
83 (void)icq_PacketRead32(p);
|
|
84 num_files=icq_PacketRead32(p);
|
|
85 total_bytes=icq_PacketRead32(p);
|
|
86 speed=icq_PacketRead32(p);
|
|
87 name=icq_PacketReadString(p);
|
|
88 psession->total_files=num_files;
|
|
89 psession->total_bytes=total_bytes;
|
|
90 psession->current_speed=speed;
|
|
91 icq_FileSessionSetHandle(psession, name);
|
|
92 icq_FileSessionSetStatus(psession, FILE_STATUS_INITIALIZING);
|
|
93
|
|
94 /* respond */
|
|
95 presponse=icq_TCPCreateFile01Packet(speed, icqlink->icq_Nick);
|
|
96
|
|
97 icq_TCPLinkSend(plink, presponse);
|
|
98 #ifdef TCP_PACKET_TRACE
|
|
99 printf("file 01 packet sent to uin %lu\n", plink->remote_uin);
|
|
100 #endif
|
|
101
|
|
102 break;
|
|
103
|
|
104 case 0x01:
|
|
105 speed=icq_PacketRead32(p);
|
|
106 name=icq_PacketReadString(p);
|
|
107 psession->current_speed=speed;
|
|
108 icq_FileSessionSetHandle(psession, name);
|
|
109 icq_FileSessionSetStatus(psession, FILE_STATUS_INITIALIZING);
|
|
110
|
|
111 /* respond */
|
|
112 icq_FileSessionPrepareNextFile(psession);
|
|
113 presponse=icq_TCPCreateFile02Packet(psession->current_file,
|
|
114 psession->current_file_size, psession->current_speed);
|
|
115
|
|
116 icq_TCPLinkSend(plink, presponse);
|
|
117 #ifdef TCP_PACKET_TRACE
|
|
118 printf("file 02 packet sent to uin %lu\n", plink->remote_uin);
|
|
119 #endif
|
|
120 break;
|
|
121
|
|
122 case 0x02:
|
|
123 /* when files are skipped
|
|
124 psession->total_transferred_bytes+=
|
|
125 (psession->current_file_size-psession->current_file_progress);
|
|
126 */
|
|
127
|
|
128 (void)icq_PacketRead8(p);
|
|
129 name=icq_PacketReadString(p);
|
|
130 (void)icq_PacketReadString(p);
|
|
131 filesize=icq_PacketRead32(p);
|
|
132 (void)icq_PacketRead32(p);
|
|
133 speed=icq_PacketRead32(p);
|
|
134 icq_FileSessionSetCurrentFile(psession, name);
|
|
135 psession->current_file_size=filesize;
|
|
136 psession->current_speed=speed;
|
|
137 psession->current_file_num++;
|
|
138 icq_FileSessionSetStatus(psession, FILE_STATUS_NEXT_FILE);
|
|
139
|
|
140 /* respond */
|
|
141 presponse=icq_TCPCreateFile03Packet(psession->current_file_progress,
|
|
142 speed);
|
|
143
|
|
144 icq_TCPLinkSend(plink, presponse);
|
|
145 #ifdef TCP_PACKET_TRACE
|
|
146 printf("file 03 packet sent to uin %lu\n", plink->remote_uin);
|
|
147 #endif
|
|
148 break;
|
|
149
|
|
150 case 0x03:
|
|
151 filesize=icq_PacketRead32(p);
|
|
152 (void)icq_PacketRead32(p);
|
|
153 speed=icq_PacketRead32(p);
|
|
154 psession->current_file_progress=filesize;
|
|
155 psession->total_transferred_bytes+=filesize;
|
|
156 psession->current_speed=speed;
|
|
157
|
|
158 icq_FileSessionSetStatus(psession, FILE_STATUS_NEXT_FILE);
|
|
159 icq_FileSessionSetStatus(psession, FILE_STATUS_SENDING);
|
|
160 break;
|
|
161
|
|
162 case 0x04:
|
|
163 (void)icq_PacketRead32(p);
|
|
164 invoke_callback(icqlink, icq_FileNotify)(psession,
|
|
165 FILE_NOTIFY_STOP_FILE, 0, NULL);
|
|
166 break;
|
|
167
|
|
168 case 0x05:
|
|
169 speed=icq_PacketRead32(p);
|
|
170 psession->current_speed=speed;
|
|
171 invoke_callback(icqlink, icq_FileNotify)(psession,
|
|
172 FILE_NOTIFY_NEW_SPEED, speed, NULL);
|
|
173 break;
|
|
174
|
|
175 case 0x06:
|
|
176 {
|
|
177 void *data = p->data+sizeof(BYTE);
|
|
178 int length = p->length-sizeof(BYTE);
|
|
179
|
|
180 invoke_callback(icqlink, icq_FileNotify)(psession,
|
|
181 FILE_NOTIFY_DATAPACKET, length, data);
|
|
182 icq_FileSessionSetStatus(psession, FILE_STATUS_RECEIVING);
|
|
183 result=write(psession->current_fd, data, length);
|
|
184 psession->current_file_progress+=length;
|
|
185 psession->total_transferred_bytes+=length;
|
|
186 break;
|
|
187 }
|
|
188
|
|
189 default:
|
|
190 icq_FmtLog(icqlink, ICQ_LOG_WARNING, "unknown file packet type %d!\n", type);
|
|
191
|
|
192 }
|
|
193 }
|
|
194
|
|
195 void icq_HandleFileHello(icq_TCPLink *plink)
|
|
196 {
|
|
197
|
|
198 /* once the hello packet has been processed and we know which uin this
|
|
199 * link is for, we can link up with a file session */
|
|
200 icq_FileSession *pfile=icq_FindFileSession(plink->icqlink,
|
|
201 plink->remote_uin, 0);
|
|
202
|
|
203 if(pfile)
|
|
204 {
|
|
205 plink->id=pfile->id;
|
|
206 plink->session=pfile;
|
|
207 pfile->tcplink=plink;
|
|
208 icq_FileSessionSetStatus(pfile, FILE_STATUS_CONNECTED);
|
|
209
|
|
210 } else {
|
|
211
|
|
212 icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING,
|
|
213 "unexpected file hello received from %d, closing link\n",
|
|
214 plink->remote_uin);
|
|
215 icq_TCPLinkClose(plink);
|
|
216 }
|
|
217
|
|
218 }
|
|
219
|
|
220 void icq_HandleFileAck(icq_TCPLink *plink, icq_Packet *p, int port)
|
|
221 {
|
|
222 icq_TCPLink *pfilelink;
|
|
223 icq_FileSession *pfile;
|
|
224 icq_Packet *p2;
|
|
225
|
|
226 pfilelink=icq_TCPLinkNew(plink->icqlink);
|
|
227 pfilelink->type=TCP_LINK_FILE;
|
|
228 pfilelink->id=p->id;
|
|
229
|
|
230 /* once the ack packet has been processed, link up with the file session */
|
|
231 pfile=icq_FindFileSession(plink->icqlink, plink->remote_uin, 0);
|
|
232
|
|
233 pfile->tcplink=pfilelink;
|
|
234 pfilelink->id=pfile->id;
|
|
235
|
|
236 invoke_callback(plink->icqlink, icq_RequestNotify)(plink->icqlink,
|
|
237 pfile->id, ICQ_NOTIFY_FILESESSION, sizeof(icq_FileSession), pfile);
|
|
238
|
|
239 icq_FileSessionSetStatus(pfile, FILE_STATUS_CONNECTING);
|
|
240 icq_TCPLinkConnect(pfilelink, plink->remote_uin, port);
|
|
241
|
|
242 pfilelink->session=pfile;
|
|
243
|
|
244 p2=icq_TCPCreateFile00Packet( pfile->total_files,
|
|
245 pfile->total_bytes, pfile->current_speed, plink->icqlink->icq_Nick);
|
|
246 icq_TCPLinkSend(pfilelink, p2);
|
|
247
|
|
248 }
|
|
249
|