1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
4 * $Id: tcpfilehandle.c 2096 2001-07-31 01:00:39Z warmenhoven $
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
7 * Bill Soudan <soudan@kde.org>
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.
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.
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.
38 #include "stdpackets.h"
39 #include "filesession.h"
41 void icq_TCPOnFileReqReceived(icq_Link
*icqlink
, DWORD uin
, const char *message
,
42 const char *filename
, unsigned long filesize
, DWORD id
)
44 /* use the current system time for time received */
46 struct tm
*ptime
=localtime(&t
);
48 #ifdef TCP_PACKET_TRACE
49 printf("file request packet received from %lu { sequence=%lx, message=%s }\n",
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
);
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 */
62 void icq_TCPProcessFilePacket(icq_Packet
*p
, icq_TCPLink
*plink
)
64 icq_FileSession
*psession
=(icq_FileSession
*)plink
->session
;
65 icq_Link
*icqlink
= plink
->icqlink
;
74 icq_Packet
*presponse
;
78 type
=icq_PacketRead8(p
);
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
);
95 presponse
=icq_TCPCreateFile01Packet(speed
, icqlink
->icq_Nick
);
97 icq_TCPLinkSend(plink
, presponse
);
98 #ifdef TCP_PACKET_TRACE
99 printf("file 01 packet sent to uin %lu\n", plink
->remote_uin
);
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
);
112 icq_FileSessionPrepareNextFile(psession
);
113 presponse
=icq_TCPCreateFile02Packet(psession
->current_file
,
114 psession
->current_file_size
, psession
->current_speed
);
116 icq_TCPLinkSend(plink
, presponse
);
117 #ifdef TCP_PACKET_TRACE
118 printf("file 02 packet sent to uin %lu\n", plink
->remote_uin
);
123 /* when files are skipped
124 psession->total_transferred_bytes+=
125 (psession->current_file_size-psession->current_file_progress);
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
);
141 presponse
=icq_TCPCreateFile03Packet(psession
->current_file_progress
,
144 icq_TCPLinkSend(plink
, presponse
);
145 #ifdef TCP_PACKET_TRACE
146 printf("file 03 packet sent to uin %lu\n", plink
->remote_uin
);
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
;
158 icq_FileSessionSetStatus(psession
, FILE_STATUS_NEXT_FILE
);
159 icq_FileSessionSetStatus(psession
, FILE_STATUS_SENDING
);
163 (void)icq_PacketRead32(p
);
164 invoke_callback(icqlink
, icq_FileNotify
)(psession
,
165 FILE_NOTIFY_STOP_FILE
, 0, NULL
);
169 speed
=icq_PacketRead32(p
);
170 psession
->current_speed
=speed
;
171 invoke_callback(icqlink
, icq_FileNotify
)(psession
,
172 FILE_NOTIFY_NEW_SPEED
, speed
, NULL
);
177 void *data
= p
->data
+sizeof(BYTE
);
178 int length
= p
->length
-sizeof(BYTE
);
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
;
190 icq_FmtLog(icqlink
, ICQ_LOG_WARNING
, "unknown file packet type %d!\n", type
);
195 void icq_HandleFileHello(icq_TCPLink
*plink
)
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);
206 plink
->session
=pfile
;
207 pfile
->tcplink
=plink
;
208 icq_FileSessionSetStatus(pfile
, FILE_STATUS_CONNECTED
);
212 icq_FmtLog(plink
->icqlink
, ICQ_LOG_WARNING
,
213 "unexpected file hello received from %d, closing link\n",
215 icq_TCPLinkClose(plink
);
220 void icq_HandleFileAck(icq_TCPLink
*plink
, icq_Packet
*p
, int port
)
222 icq_TCPLink
*pfilelink
;
223 icq_FileSession
*pfile
;
226 pfilelink
=icq_TCPLinkNew(plink
->icqlink
);
227 pfilelink
->type
=TCP_LINK_FILE
;
230 /* once the ack packet has been processed, link up with the file session */
231 pfile
=icq_FindFileSession(plink
->icqlink
, plink
->remote_uin
, 0);
233 pfile
->tcplink
=pfilelink
;
234 pfilelink
->id
=pfile
->id
;
236 invoke_callback(plink
->icqlink
, icq_RequestNotify
)(plink
->icqlink
,
237 pfile
->id
, ICQ_NOTIFY_FILESESSION
, sizeof(icq_FileSession
), pfile
);
239 icq_FileSessionSetStatus(pfile
, FILE_STATUS_CONNECTING
);
240 icq_TCPLinkConnect(pfilelink
, plink
->remote_uin
, port
);
242 pfilelink
->session
=pfile
;
244 p2
=icq_TCPCreateFile00Packet( pfile
->total_files
,
245 pfile
->total_bytes
, pfile
->current_speed
, plink
->icqlink
->icq_Nick
);
246 icq_TCPLinkSend(pfilelink
, p2
);