1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
#ifndef _SEND_H_
#define _SEND_H_
//=============================================================================
//
// File : DccFileTransfer.h
// Creation date : Tue Sep 24 09 2000 15:06:12 by Szymon Stefanek
//
// This file is part of the KVIrc IRC client distribution
// Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
//
// This program is FREE software. You can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the HOPE that it will be USEFUL,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#include "DccDescriptor.h"
#include "DccWindow.h"
#include "DccThread.h"
#include "KviWindow.h"
#include "KviCString.h"
#include "kvi_sockettype.h"
#include "KviPointerList.h"
#include "KviFileTransfer.h"
#include "KviTimeUtils.h"
#include "KviTalHBox.h"
#include "KviTalVBox.h"
#include <QLabel>
#include <QProgressBar>
#include <QFile>
#include <QDialog>
#include <QCheckBox>
#include <QMenu>
class QSpinBox;
class QTimer;
class QPainter;
class DccFileTransfer;
class DccMarshal;
class QMenu;
struct KviDccSendThreadOptions
{
KviCString szFileName;
quint64 uStartPosition;
int iPacketSize;
int iIdleStepLengthInMSec;
bool bFastSend;
bool bNoAcks;
bool bIsTdcc;
unsigned int uMaxBandwidth;
};
class DccSendThread : public DccThread
{
public:
DccSendThread(QObject * par, kvi_socket_t fd, KviDccSendThreadOptions * opt);
~DccSendThread();
private:
// stats: SHARED!!!
uint m_uAverageSpeed;
uint m_uInstantSpeed;
quint64 m_uFilePosition;
quint64 m_uAckedBytes = 0;
quint64 m_uTotalSentBytes = 0;
// internal
unsigned long m_uStartTime;
unsigned long m_uInstantSpeedInterval;
quint64 m_uInstantSentBytes;
KviDccSendThreadOptions * m_pOpt;
KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth but not only
public:
void initGetInfo();
uint averageSpeed() { return m_uAverageSpeed; };
uint instantSpeed() { return m_uInstantSpeed; };
quint64 filePosition() { return m_uFilePosition; };
// sent ONLY in this session
quint64 sentBytes() { return m_uTotalSentBytes; };
quint64 ackedBytes() { return m_uAckedBytes; };
unsigned int bandwidthLimit() { return m_pOpt->uMaxBandwidth; };
void setBandwidthLimit(unsigned int uMaxBandwidth) { m_pOpt->uMaxBandwidth = uMaxBandwidth; };
void doneGetInfo();
protected:
void updateStats();
virtual void run();
};
struct KviDccRecvThreadOptions
{
bool bResume;
KviCString szFileName;
quint64 uTotalFileSize;
int iIdleStepLengthInMSec;
bool bSendZeroAck;
bool bSend64BitAck;
bool bNoAcks;
bool bIsTdcc;
unsigned int uMaxBandwidth;
};
class DccRecvThread : public DccThread
{
public:
DccRecvThread(QObject * par, kvi_socket_t fd, KviDccRecvThreadOptions * opt);
~DccRecvThread();
protected:
KviDccRecvThreadOptions * m_pOpt;
// stats: SHARED!
uint m_uAverageSpeed;
uint m_uInstantSpeed;
quint64 m_uFilePosition;
quint64 m_uTotalReceivedBytes;
// internal
unsigned long m_uStartTime;
KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth
quint64 m_uInstantReceivedBytes;
quint64 m_uInstantSpeedInterval;
QFile * m_pFile;
public:
void initGetInfo();
uint averageSpeed() { return m_uAverageSpeed; };
uint instantSpeed() { return m_uInstantSpeed; };
quint64 filePosition() { return m_uFilePosition; };
// received ONLY in this session
quint64 receivedBytes() { return m_uTotalReceivedBytes; };
unsigned int bandwidthLimit() { return m_pOpt->uMaxBandwidth; };
void setBandwidthLimit(unsigned int uMaxBandwidth) { m_pOpt->uMaxBandwidth = uMaxBandwidth; };
void doneGetInfo();
protected:
void postMessageEvent(const char * msg);
void updateStats();
bool sendAck(qint64 filePos, bool bUse64BitAck = false);
virtual void run();
};
class DccFileTransferBandwidthDialog : public QDialog
{
Q_OBJECT
public:
DccFileTransferBandwidthDialog(QWidget * pParent, DccFileTransfer * t);
~DccFileTransferBandwidthDialog();
protected:
DccFileTransfer * m_pTransfer;
QCheckBox * m_pEnableLimitCheck;
QSpinBox * m_pLimitBox;
protected:
void closeEvent(QCloseEvent * e) override;
protected slots:
void okClicked();
void cancelClicked();
};
class DccFileTransfer : public KviFileTransfer, public DccMarshalOutputContext
{
enum GeneralStatus
{
Connecting,
Transferring,
Success,
Failure
};
Q_OBJECT
public:
DccFileTransfer(DccDescriptor * dcc);
~DccFileTransfer();
private:
DccSendThread * m_pSlaveSendThread;
DccRecvThread * m_pSlaveRecvThread;
DccDescriptor * m_pDescriptor;
DccMarshal * m_pMarshal;
KviCString m_szTarget;
KviCString m_szDccType;
QString m_szTransferIdString;
QString m_szStatusString;
GeneralStatus m_eGeneralStatus;
QString m_szTransferLog; // html
kvi_time_t m_tTransferStartTime;
kvi_time_t m_tTransferEndTime;
// cached stats
quint64 m_uTotalFileSize; // total file size to transfer
unsigned int m_uMaxBandwidth;
DccFileTransferBandwidthDialog * m_pBandwidthDialog;
QTimer * m_pResumeTimer; // used to signal resume timeout
public:
bool resumeAccepted(const char * filename, const char * port, const char * szZeroPortTag);
bool doResume(const char * filename, const char * port, quint64 filePos);
static void init();
static void done();
static unsigned int runningTransfersCount();
static DccFileTransfer * nonFailedTransferWithLocalFileName(const QString & szLocalFileName);
static unsigned int transferCount();
static bool handleResumeAccepted(const char * filename, const char * port, const char * szZeroPortTag);
static bool handleResumeRequest(const char * filename, const char * port, quint64 filePos);
bool event(QEvent * e) override;
virtual KviWindow * dccMarshalOutputWindow();
virtual const char * dccMarshalOutputContextString();
virtual void displayPaint(QPainter * p, int column, QRect rect);
virtual int displayHeight(int iLineSpacing);
virtual void fillContextPopup(QMenu * m);
virtual void fillStatusString(QString & szBuffer);
virtual bool active();
virtual QString tipText();
virtual QString localFileName();
bool isFileUpload() { return m_pDescriptor->isFileUpload(); };
unsigned int averageSpeed();
unsigned int instantSpeed();
unsigned int transferredBytes();
int bandwidthLimit();
void setBandwidthLimit(int iVal);
virtual DccThread * getSlaveThread();
protected:
void startConnection();
void listenOrConnect();
void addToTransferLog(const QString & s);
void outputAndLog(const QString & s);
void outputAndLog(int msgtype, const QString & s);
KviWindow * eventWindow();
protected slots:
void connectionInProgress();
void sslError(const char * msg);
void startingSSLHandshake();
void handleMarshalError(KviError::Code);
void connected();
void bandwidthDialogDestroyed();
void configureBandwidth();
void resumeTimedOut();
public slots:
void abort();
void retryDCC();
void retryTDCC();
void retryRevDCC();
};
#endif //_SEND_H_
|