aboutsummaryrefslogtreecommitdiffstats
path: root/3.4.0/src/modules/dcc/send.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3.4.0/src/modules/dcc/send.cpp')
-rw-r--r--3.4.0/src/modules/dcc/send.cpp1898
1 files changed, 0 insertions, 1898 deletions
diff --git a/3.4.0/src/modules/dcc/send.cpp b/3.4.0/src/modules/dcc/send.cpp
deleted file mode 100644
index e88c1424b..000000000
--- a/3.4.0/src/modules/dcc/send.cpp
+++ /dev/null
@@ -1,1898 +0,0 @@
-//=============================================================================
-//
-// File : send.cpp
-// Creation date : Tue Sep 20 09 2000 15:14:14 by Szymon Stefanek
-//
-// This file is part of the KVirc irc client distribution
-// Copyright (C) 2000-2005 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 opinion) 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-//
-//=============================================================================
-
-#include "send.h"
-#include "broker.h"
-#include "marshal.h"
-#include "broker.h"
-#include "window.h"
-#include "kvi_styled_controls.h"
-
-#ifdef COMPILE_ON_WINDOWS
- // Ugly Windoze compiler...
- #include "dialogs.h"
-#endif
-
-#define _KVI_DEBUG_CHECK_RANGE_
-#include "kvi_debug.h"
-#include "kvi_app.h"
-#include "kvi_options.h"
-#include "kvi_ircview.h"
-#include "kvi_iconmanager.h"
-#include "kvi_locale.h"
-#include "kvi_error.h"
-#include "kvi_out.h"
-#include "kvi_netutils.h"
-#include "kvi_console.h"
-#include "kvi_frame.h"
-#include "kvi_malloc.h"
-#include "kvi_memmove.h"
-#include "kvi_thread.h"
-#include "kvi_ircsocket.h"
-
-#include "kvi_mediatype.h"
-#include "kvi_socket.h"
-#include "kvi_kvs_eventtriggers.h"
-#include "kvi_parameterlist.h"
-#include "kvi_ircconnection.h"
-#include "kvi_ircconnectionuserinfo.h"
-#include "kvi_sparser.h"
-#include "kvi_kvs_script.h"
-
-#include <qevent.h>
-#include <qfile.h>
-#include <qpainter.h>
-#include <qdatetime.h>
-#include <qglobal.h>
-#include <qcheckbox.h>
-#include <qspinbox.h>
-#include <qlayout.h>
-#include <qpushbutton.h>
-
-#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS 3000
-#define INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS 3
-
-// This limit, when multiplied by INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS
-// must fit in 31 bits (0x7fffffff)! (because of data size limits)
-#define MAX_DCC_BANDWIDTH_LIMIT 0x1fffffff
-
-//#include <unistd.h> //close()
-
-// FIXME: SSL Support here!
-// FIXME: The events OnDCCConnect etc are in wrong places here...!
-
-extern KviDccBroker * g_pDccBroker;
-
-extern KVIRC_API KviMediaManager * g_pMediaManager; // kvi_app.cpp
-
-
-static KviPointerList<KviDccFileTransfer> * g_pDccFileTransfers = 0;
-static QPixmap * g_pDccFileTransferIcon = 0;
-
-//#warning "The events that have a KviStr data pointer should become real classes, that take care of deleting the data pointer!"
-//#warning "Otherwise, when left undispatched we will be leaking memory (event class destroyed but not the data ptr)"
-
-KviDccRecvThread::KviDccRecvThread(QObject * par,kvi_socket_t fd,KviDccRecvThreadOptions * opt)
-: KviDccThread(par,fd)
-{
- m_pOpt = opt;
- m_iAverageSpeed = -1;
- m_iInstantSpeed = -1;
- m_iFilePosition = 0;
-
- m_iTotalReceivedBytes = 0;
- m_iInstantReceivedBytes = 0;
- m_pFile = 0;
- m_pTimeInterval = new KviMSecTimeInterval();
- m_uStartTime = 0;
- m_uInstantSpeedInterval = 0;
-}
-
-KviDccRecvThread::~KviDccRecvThread()
-{
- if(m_pOpt)delete m_pOpt;
- if(m_pFile)delete m_pFile;
- delete m_pTimeInterval;
-}
-
-bool KviDccRecvThread::sendAck(int filePos)
-{
- int size = htonl(filePos);
- if(kvi_socket_send(m_fd,(void *)(&size),4) != 4)
- {
- postErrorEvent(KviError_acknowledgeError);
- return false;
- }
- return true;
-}
-
-void KviDccRecvThread::updateStats()
-{
- m_uInstantSpeedInterval += m_pTimeInterval->mark();
- unsigned long uCurTime = m_pTimeInterval->secondsCounter();
-
- m_pMutex->lock();
- unsigned long uElapsedTime = uCurTime - m_uStartTime;
- if(uElapsedTime < 1)uElapsedTime = 1;
-
- m_iFilePosition = m_pFile->at();
- m_iAverageSpeed = m_iTotalReceivedBytes / uElapsedTime;
-
- if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS)
- {
- unsigned int uMSecsOfTheNextInterval = 0;
- if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2)))
- uMSecsOfTheNextInterval = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS;
- m_iInstantSpeed = (m_iInstantReceivedBytes * 1000) / m_uInstantSpeedInterval;
- m_iInstantReceivedBytes = 0;
- m_uInstantSpeedInterval = uMSecsOfTheNextInterval;
- } else {
- if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS)
- m_iInstantSpeed = m_iAverageSpeed;
- }
- m_pMutex->unlock();
-}
-
-void KviDccRecvThread::postMessageEvent(const char * m)
-{
- KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_MESSAGE);
- e->setData(new KviStr(m));
- postEvent(parent(),e);
-}
-
-// FIXME: This stuff should be somewhat related to the 1448 bytes TCP basic packet size
-#define KVI_DCC_RECV_BLOCK_SIZE 8192
-#define KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE 6150
-
-void KviDccRecvThread::run()
-{
- // take care of sleeping a bit if we can't read stuff
- // so we don't hog the CPU too much...
- int iFailedSelects = 0;
- // take care of sleeping a bit if we get a lot of short reads
- // so we don't hog the CPU too much...
- int iShortReadQuantifier = 0;
- // the algorithm is as follows:
- // attempt to read KVI_DCC_RECV_BLOCK_SIZE bytes
- // iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENT_OF_BLOCK_SIZE - realReadedBytes) / 42);
- // thus we gain points if we read less than 75% of the requested size
- // and we loose points otherwise
- // there are nearly 24 points per KB
- // if(iShortReadQuantifier > 10)
- // msleep(iShortReadQuantifier);
- // also never sleep more than 500 msecs since it will
- // rise our exit latency too much
-
- m_pTimeInterval->mark();
- m_pMutex->lock();
- m_uStartTime = m_pTimeInterval->secondsCounter();
- m_pMutex->unlock();
-
- int iProbableTerminationTime = 0;
-
- m_pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr()));
-
- if(m_pOpt->bResume)
- {
- if(!m_pFile->open(IO_WriteOnly | IO_Append))
- {
- postErrorEvent(KviError_cantOpenFileForAppending);
- goto exit_dcc;
- } // else pFile is already at end
- } else {
- if(!m_pFile->open(IO_WriteOnly))
- {
- postErrorEvent(KviError_cantOpenFileForWriting);
- goto exit_dcc;
- }
- }
-
- if(m_pOpt->bSendZeroAck && (!m_pOpt->bNoAcks))
- {
- if(!sendAck(m_pFile->at()))goto exit_dcc;
- }
-
- for(;;)
- {
- // Dequeue events
- while(KviThreadEvent * e = dequeueEvent())
- {
- if(e->id() == KVI_THREAD_EVENT_TERMINATE)
- {
- delete e;
- goto exit_dcc;
- } else {
- // Other events are senseless to us
- delete e;
- }
- }
-
- bool bCanRead;
- bool bDummy;
-
- if(kvi_select(m_fd,&bCanRead,&bDummy,15000))
- {
- // reset sleep time
-
- if(bCanRead)
- {
- iFailedSelects = 0;
-
- // Read a data block
- char buffer[KVI_DCC_RECV_BLOCK_SIZE];
-
- m_pMutex->lock(); // FIXME: how to remove this lock ?
- unsigned int uMaxPossible = (m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT) ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS;
- m_pMutex->unlock();
- unsigned int uToRead = uMaxPossible > ((unsigned int)(m_iInstantReceivedBytes)) ? uMaxPossible - m_iInstantReceivedBytes : 0;
- if(uToRead > KVI_DCC_RECV_BLOCK_SIZE)uToRead = KVI_DCC_RECV_BLOCK_SIZE;
-
- if(uToRead > 0)
- {
- int readLen = kvi_socket_recv(m_fd,buffer,uToRead);
-
- if(readLen > 0)
- {
- // Readed something useful...write back
- if((m_pOpt->iTotalFileSize > -1) && ((readLen + (int)m_pFile->at()) > m_pOpt->iTotalFileSize))
- {
- postMessageEvent(__tr2qs_ctx("WARNING: The peer is sending garbage data past the end of the file","dcc"));
- postMessageEvent(__tr2qs_ctx("WARNING: Ignoring data past the declared end of file and closing the connection","dcc"));
-
- readLen = m_pOpt->iTotalFileSize - m_pFile->at();
- if(readLen > 0)
- {
- if(m_pFile->writeBlock(buffer,readLen) != readLen)
- postErrorEvent(KviError_fileIOError);
- }
- break;
-
- } else {
- if(m_pFile->writeBlock(buffer,readLen) != readLen)
- {
- postErrorEvent(KviError_fileIOError);
- break;
- }
- }
-
- // Update stats
- m_iTotalReceivedBytes += readLen;
- m_iInstantReceivedBytes += readLen;
-
- updateStats();
- // Now send the ack
- if(m_pOpt->bNoAcks)
- {
- // No acks...
- // Interrupt if the whole file has been received
- if(m_pOpt->iTotalFileSize > 0)
- {
- if(((int)(m_pFile->at())) == m_pOpt->iTotalFileSize)
- {
- // Received the whole file...die
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- }
- }
- } else {
- // Must send the ack... the peer must close the connection
- if(!sendAck(m_pFile->at()))break;
- }
-
- // now take care of short reads
- iShortReadQuantifier += ((KVI_DCC_RECV_75PERCENTOF_BLOCK_SIZE - readLen) / 42);
- if(iShortReadQuantifier > 10)
- {
- // we're having short reads.. sleep a while
- // but don't allow it to go too high: 0.45 sec is really a lot
- if(iShortReadQuantifier > 500)
- iShortReadQuantifier = 500;
- msleep(iShortReadQuantifier);
- } else {
- // don't allow it to go too low
- if(iShortReadQuantifier < -500)
- iShortReadQuantifier = -500;
- }
-
- } else {
- updateStats();
- // Read problem...
-
- if(readLen == 0)
- {
- // readed EOF..
- if((((int)(m_pFile->at())) == m_pOpt->iTotalFileSize) || (m_pOpt->iTotalFileSize < 0))
- {
- // success if we got the whole file or if we don't know the file size (we trust the peer)
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- }
- }
- if(!handleInvalidSocketRead(readLen))break;
- }
- } else {
- updateStats();
-
- // reached the bandwidth limit: slow down a bit
- if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100))
- msleep(100);
- else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20))
- msleep(20);
- }
- } else {
- // Can't read stuff (can just write)
- updateStats();
-
- // sleep up to 300 msecs (if data arrives...we want low exit latency here)
- if(iFailedSelects < 100)iFailedSelects++;
- updateStats();
- if(iFailedSelects > 3)
- msleep(3 * iFailedSelects);
-
- if(((int)(m_pFile->at())) == m_pOpt->iTotalFileSize)
- {
- // Wait for the peer to close the connection
- if(iProbableTerminationTime == 0)
- {
- iProbableTerminationTime = (int)kvi_unixTime();
- m_pFile->flush();
- postMessageEvent(__tr2qs_ctx("Data transfer terminated, waiting 30 seconds for the peer to close the connection...","dcc"));
- // FIXME: Close the file ?
- } else {
- int iDiff = (((int)kvi_unixTime()) - iProbableTerminationTime);
- if(iDiff > 30)
- {
- // success if we got the whole file or if we don't know the file size (we trust the peer)
- postMessageEvent(__tr2qs_ctx("Data transfer was terminated 30 seconds ago, closing the connection","dcc"));
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- }
- }
- }
- }
- // include the artificial delay if needed
- if(m_pOpt->iIdleStepLengthInMSec > 0)
- {
- debug("LOOP: artificial delay");
- msleep(m_pOpt->iIdleStepLengthInMSec);
- }
- } else {
- // sleep up to 200 msecs (if data arrives...we want low exit latency here)
- if(iFailedSelects < 100)iFailedSelects++;
- updateStats();
- if(iFailedSelects > 3)
- msleep(2 * iFailedSelects);
- }
- }
-
-exit_dcc:
- if(m_pFile)
- {
- m_pFile->close();
- delete m_pFile;
- m_pFile = 0;
- }
- kvi_socket_close(m_fd);
- m_fd = KVI_INVALID_SOCKET;
-}
-
-void KviDccRecvThread::initGetInfo()
-{
- m_pMutex->lock();
-}
-
-void KviDccRecvThread::doneGetInfo()
-{
- m_pMutex->unlock();
-}
-
-KviDccSendThread::KviDccSendThread(QObject * par,kvi_socket_t fd,KviDccSendThreadOptions * opt)
-: KviDccThread(par,fd)
-{
- m_pOpt = opt;
- // stats
- m_iAverageSpeed = -1;
- m_iInstantSpeed = -1;
- m_iFilePosition = 0;
- m_iTotalSentBytes = 0;
- m_pTimeInterval = new KviMSecTimeInterval();
- m_uStartTime = 0;
- m_uInstantSpeedInterval = 0;
-}
-
-KviDccSendThread::~KviDccSendThread()
-{
- if(m_pOpt)delete m_pOpt;
- delete m_pTimeInterval;
-}
-
-void KviDccSendThread::updateStats()
-{
- m_uInstantSpeedInterval += m_pTimeInterval->mark();
-
- m_pMutex->lock();
- unsigned long uElapsedTime = m_pTimeInterval->secondsCounter() - m_uStartTime;
- if(uElapsedTime < 1)uElapsedTime = 1;
-
- if(m_pOpt->bNoAcks)
- {
- // There are no acks : the avg bandwidth is based on the sent bytes
- m_iAverageSpeed = m_iTotalSentBytes / uElapsedTime;
- } else {
- // acknowledges : we compute the avg bandwidth based on the acks we receive
- m_iAverageSpeed = (m_iAckedBytes - m_pOpt->iStartPosition) / uElapsedTime;
- }
-
- if(m_uInstantSpeedInterval >= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS)
- {
- // we often overcount the time interval of 10-20 msecs
- // and thus our bandwidth is used less than requested.
- // for this reason we try to account the time in excess
- // to the next period in order to balance the bandwidth usage.
- unsigned long uMSecsOfNextPeriodUsed = 0;
- if(m_uInstantSpeedInterval > INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS)
- {
- if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS + (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS / 2)))
- {
- uMSecsOfNextPeriodUsed = m_uInstantSpeedInterval - INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS;
- m_uInstantSpeedInterval = INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS;
- }
- // else we have been delayed for a time comparable to a period
- // and thus we can't recover the bandwidth... let it go as it does...
- }
- m_iInstantSpeed = (m_iInstantSentBytes * 1000) / m_uInstantSpeedInterval;
- m_uInstantSpeedInterval = uMSecsOfNextPeriodUsed;
- m_iInstantSentBytes = 0;
- } else {
- if(uElapsedTime <= INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS)
- m_iInstantSpeed = m_iAverageSpeed;
- }
- m_pMutex->unlock();
-}
-
-void KviDccSendThread::run()
-{
- m_pTimeInterval->mark();
- m_pMutex->lock();
- m_uStartTime = m_pTimeInterval->secondsCounter();
- m_pMutex->unlock();
-
- m_iTotalSentBytes = 0;
- m_iInstantSentBytes = 0;
- int iFailedSelects = 0;
- char ackbuffer[4];
- int iBytesInAckBuffer = 0;
- Q_UINT32 iLastAck = 0;
-
- if(m_pOpt->iPacketSize < 32)m_pOpt->iPacketSize = 32;
- char * buffer = (char *)kvi_malloc(m_pOpt->iPacketSize * sizeof(char));
-
- QFile * pFile = new QFile(QString::fromUtf8(m_pOpt->szFileName.ptr()));
-
- if(!pFile->open(IO_ReadOnly))
- {
- postErrorEvent(KviError_cantOpenFileForReading);
- goto exit_dcc;
- }
-
- if(pFile->size() < 1)
- {
- postErrorEvent(KviError_cantSendAZeroSizeFile);
- goto exit_dcc;
- }
-
- if(m_pOpt->iStartPosition > 0)
- {
- // seek
- if(!(pFile->at(m_pOpt->iStartPosition)))
- {
- postErrorEvent(KviError_fileIOError);
- goto exit_dcc;
- }
- }
-
- iLastAck = m_pOpt->iStartPosition;
-
- for(;;)
- {
- // Dequeue events
- while(KviThreadEvent * e = dequeueEvent())
- {
- if(e->id() == KVI_THREAD_EVENT_TERMINATE)
- {
- delete e;
- goto exit_dcc;
- } else {
- // Other events are senseless to us
- delete e;
- }
- }
-
- bool bCanRead;
- bool bCanWrite;
-
- if(kvi_select(m_fd,&bCanRead,&bCanWrite,15000))
- {
- // reset the sleep time
- iFailedSelects = 0;
- if(bCanRead)
- {
- if(!m_pOpt->bNoAcks)
- {
- int iAckBytesToRead = 4 - iBytesInAckBuffer;
- int readLen = kvi_socket_recv(m_fd,(void *)(ackbuffer + iBytesInAckBuffer),iAckBytesToRead);
- if(readLen > 0)
- {
- iBytesInAckBuffer += readLen;
- if(iBytesInAckBuffer == 4)
- {
- Q_UINT32 iNewAck = ntohl(*((Q_UINT32 *)ackbuffer));
- if((iNewAck > pFile->at()) || (iNewAck < iLastAck))
- {
- // the peer is drunk or is trying to fool us
- postErrorEvent(KviError_acknowledgeError);
- break;
- }
- iLastAck = iNewAck;
- iBytesInAckBuffer = 0;
- }
- } else {
- if(!handleInvalidSocketRead(readLen))break;
- }
-
- // update stats
- m_pMutex->lock(); // is this really necessary ?
- m_iAckedBytes = iLastAck;
- m_pMutex->unlock();
-
- if(iLastAck >= pFile->size())
- {
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- }
- } else {
- // No acknowledges
- if(m_pOpt->bIsTdcc)
- {
- // We expect the remote end to close the connection when the whole file has been sent
- if(pFile->atEnd())
- {
- int iAck;
- int readLen = kvi_socket_recv(m_fd,(void *)&iAck,4);
- if(readLen == 0)
- {
- // done...success
- updateStats();
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- } else {
- if(readLen < 0)
- {
- if(!handleInvalidSocketRead(readLen))break;
- } else {
- KviThreadDataEvent<KviStr> * e = new KviThreadDataEvent<KviStr>(KVI_DCC_THREAD_EVENT_MESSAGE);
- e->setData(new KviStr(__tr2qs_ctx("WARNING: Received data in a DCC TSEND, there should be no acknowledges","dcc")));
- postEvent(parent(),e);
- }
- }
- }
- }
- }
- }
- if(bCanWrite)
- {
- if(!pFile->atEnd())
- {
- if(m_pOpt->bFastSend || m_pOpt->bNoAcks || (iLastAck == pFile->at()))
- {
- // maximum readable size
- int toRead = pFile->size() - pFile->at();
- // the max number of bytes we can send in this interval (bandwidth limit)
- m_pMutex->lock(); // FIXME: how to remove this lock ?
- int iMaxPossible = m_pOpt->uMaxBandwidth < MAX_DCC_BANDWIDTH_LIMIT ? m_pOpt->uMaxBandwidth * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS : MAX_DCC_BANDWIDTH_LIMIT * INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_SECS;
- m_pMutex->unlock();
- if(iMaxPossible < m_iInstantSentBytes)toRead = 0; // already sent too much!
- else {
- iMaxPossible -= m_iInstantSentBytes;
- if(toRead > iMaxPossible)toRead = iMaxPossible;
- }
- // limit to packet size
- if(toRead > m_pOpt->iPacketSize)toRead = m_pOpt->iPacketSize;
-
- int written = 0;
- if(toRead > 0)
- {
- // read data
- int readed = pFile->readBlock(buffer,toRead);
- if(readed < toRead)
- {
- postErrorEvent(KviError_fileIOError);
- break;
- }
- // send it out
- written = kvi_socket_send(m_fd,buffer,toRead);
- if(written < toRead)
- {
- if(written < 0)
- {
- // error ?
- if(!handleInvalidSocketRead(written))break;
- } else {
- // seek back to the right position
- pFile->at(pFile->at() - (toRead - written));
- }
- }
- } else {
- // just nothing to send out in this interval
- // sleep a while
- if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 100))
- {
- msleep(100);
- } else if(m_uInstantSpeedInterval < (INSTANT_BANDWIDTH_CHECK_INTERVAL_IN_MSECS - 20))
- {
- msleep(20);
- }
- }
-
- m_iTotalSentBytes += written;
- m_iInstantSentBytes += written;
- m_iFilePosition = pFile->at();
- updateStats();
- }
- } else {
- if(m_pOpt->bNoAcks && !m_pOpt->bIsTdcc)
- {
- // at end of the file in a blind dcc send...
- // not in a tdcc: we can close the file...
- updateStats();
- KviThreadEvent * e = new KviThreadEvent(KVI_DCC_THREAD_EVENT_SUCCESS);
- postEvent(parent(),e);
- break;
- } else {
- // upload finished but we're waiting for the last ack
- // sleep a bit: don't lag the kernie too much while waiting
- msleep(100);
- }
- }
- }
- } else {
- // after 2 failed selects start to sleep
- if(iFailedSelects > 3)
- {
- // sleep up to 200 msecs
- if(iFailedSelects < 100)iFailedSelects++;
- msleep(3 * iFailedSelects);
- } else {
- iFailedSelects++;
- }
- }
-
- // include the artificial delay if needed
- if(m_pOpt->iIdleStepLengthInMSec > 0)
- {
- msleep(m_pOpt->iIdleStepLengthInMSec);
- }
- }
-
-exit_dcc:
- kvi_free(buffer);
- pFile->close();
- delete pFile;
- pFile = 0;
- kvi_socket_close(m_fd);
- m_fd = KVI_INVALID_SOCKET;
-}
-
-void KviDccSendThread::initGetInfo()
-{
- m_pMutex->lock();
-}
-
-void KviDccSendThread::doneGetInfo()
-{
- m_pMutex->unlock();
-}
-
-
-KviDccFileTransfer::KviDccFileTransfer(KviDccDescriptor * dcc)
-: KviFileTransfer()
-{
- init(); // ensure we're initialized
- g_pDccFileTransfers->append(this);
-
- m_pResumeTimer = 0;
- m_pBandwidthDialog = 0;
-
- KviQString::sprintf(m_szTransferIdString,__tr2qs_ctx("TRANSFER %d","dcc"),id());
-
- m_pDescriptor = dcc;
- m_pDescriptor->setTransfer(this);
-
- m_pMarshal = new KviDccMarshal(this);
-
- connect(m_pMarshal,SIGNAL(error(int)),this,SLOT(handleMarshalError(int)));
- connect(m_pMarshal,SIGNAL(connected()),this,SLOT(connected()));
- connect(m_pMarshal,SIGNAL(inProgress()),this,SLOT(connectionInProgress()));
-#ifdef COMPILE_SSL_SUPPORT
- connect(m_pMarshal,SIGNAL(startingSSLHandshake()),this,SLOT(startingSSLHandshake()));
- connect(m_pMarshal,SIGNAL(sslError(const char *)),this,SLOT(sslError(const char *)));
-#endif
-
- m_szDccType = dcc->bIsTdcc ? (dcc->bRecvFile ? "TRECV" : "TSEND") : (dcc->bRecvFile ? "RECV" : "SEND");
-
- m_pSlaveRecvThread = 0;
- m_pSlaveSendThread = 0;
-
- m_tTransferStartTime = 0;
- m_tTransferEndTime = 0;
-
- m_szStatusString = __tr2qs_ctx("Setting up the connection","dcc");
- m_eGeneralStatus = Connecting;
-
- bool bOk;
- m_uTotalFileSize = dcc->bRecvFile ? dcc->szFileSize.toUInt(&bOk) : dcc->szLocalFileSize.toUInt(&bOk);
- if(!bOk)m_uTotalFileSize = 0;
-
- if(m_pDescriptor->bRecvFile)
- m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccRecvSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccRecvSpeed) : MAX_DCC_BANDWIDTH_LIMIT;
- else
- m_uMaxBandwidth = KVI_OPTION_BOOL(KviOption_boolLimitDccSendSpeed) ? KVI_OPTION_UINT(KviOption_uintMaxDccSendSpeed) : MAX_DCC_BANDWIDTH_LIMIT;
-
- startConnection();
-}
-
-KviDccFileTransfer::~KviDccFileTransfer()
-{
- g_pDccFileTransfers->removeRef(this);
-
- if(m_pResumeTimer)delete m_pResumeTimer;
- if(m_pBandwidthDialog)delete m_pBandwidthDialog;
-
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->terminate();
- delete m_pSlaveRecvThread;
- m_pSlaveRecvThread = 0;
- }
-
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->terminate();
- delete m_pSlaveSendThread;
- m_pSlaveSendThread = 0;
- }
-
- KviThreadManager::killPendingEvents(this);
-
- delete m_pDescriptor;
- delete m_pMarshal;
-}
-
-void KviDccFileTransfer::bandwidthDialogDestroyed()
-{
- m_pBandwidthDialog = 0;
-}
-
-KviWindow * KviDccFileTransfer::eventWindow()
-{
- KviWindow *w = transferWindow();
- if(w)return w;
- return m_pDescriptor->console();
-}
-
-void KviDccFileTransfer::startConnection()
-{
- if(!(m_pDescriptor->bActive))
- {
- // PASSIVE CONNECTION
- m_szStatusString = __tr2qs_ctx("Attempting a passive DCC %1 connection","dcc").arg(m_szDccType.ptr());
- outputAndLog(m_szStatusString);
- } else {
- // ACTIVE CONNECTION
- m_szStatusString = __tr2qs_ctx("Attempting an active DCC %1 connection","dcc").arg(m_szDccType.ptr());
- outputAndLog(m_szStatusString);
- }
-
-
- if(m_pDescriptor->bResume && m_pDescriptor->bRecvFile)
- {
- QString fName;
- KviServerParser::encodeCtcpParameter(m_pDescriptor->szFileName.utf8().data(),fName);
- if(m_pDescriptor->isZeroPortRequest())
- {
- m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s %s%c",
- m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
- 0x01,
- m_pDescriptor->console()->connection()->encodeText(fName).data(),
- m_pDescriptor->szPort.utf8().data(),
- m_pDescriptor->szLocalFileSize.utf8().data(),
- m_pDescriptor->zeroPortRequestTag(),0x01);
- } else {
- m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC RESUME %s %s %s%c",
- m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
- 0x01,
- m_pDescriptor->console()->connection()->encodeText(fName).data(),
- m_pDescriptor->szPort.utf8().data(),
- m_pDescriptor->szLocalFileSize.utf8().data(),0x01);
- }
- m_szStatusString = __tr2qs_ctx("Sent DCC RESUME request to %1, waiting for ACCEPT","dcc").arg(m_pDescriptor->szNick);
- outputAndLog(m_szStatusString);
-
- // setup the resume timer: we don't want to wait forever
-
- if(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) < 5)
- KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) = 5;
-
- if(m_pResumeTimer)delete m_pResumeTimer;
- m_pResumeTimer = new QTimer(this);
- connect(m_pResumeTimer,SIGNAL(timeout()),this,SLOT(resumeTimedOut()));
- m_pResumeTimer->start(KVI_OPTION_UINT(KviOption_uintDccSocketTimeout) * 1000,true);
- } else {
- listenOrConnect();
- }
-
- displayUpdate();
-}
-
-void KviDccFileTransfer::listenOrConnect()
-{
- if(!(m_pDescriptor->bActive))
- {
- int ret = m_pMarshal->dccListen(m_pDescriptor->szListenIp,m_pDescriptor->szListenPort,m_pDescriptor->bDoTimeout);
- if(ret != KviError_success)handleMarshalError(ret);
- } else {
- int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout);
- if(ret != KviError_success)handleMarshalError(ret);
- }
-
- displayUpdate();
-}
-
-void KviDccFileTransfer::resumeTimedOut()
-{
- if(m_pResumeTimer)
- {
- delete m_pResumeTimer;
- m_pResumeTimer = 0;
- }
- handleMarshalError(KviError_connectionTimedOut);
-}
-
-KviWindow * KviDccFileTransfer::dccMarshalOutputWindow()
-{
- return transferWindow();
-}
-
-const char * KviDccFileTransfer::dccMarshalOutputContextString()
-{
- return m_szTransferIdString.utf8().data();
-}
-
-void KviDccFileTransfer::die()
-{
- delete this;
-}
-
-QString KviDccFileTransfer::localFileName()
-{
- return m_pDescriptor->szLocalFileName;
-}
-
-void KviDccFileTransfer::abort()
-{
- if(m_pSlaveRecvThread)m_pSlaveRecvThread->terminate();
- if(m_pSlaveSendThread)m_pSlaveSendThread->terminate();
- if(m_pMarshal)m_pMarshal->abort();
-
- if(m_pDescriptor->bRecvFile)
- g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data(),__tr_ctx("Aborted","dcc"));
-
- KviStr tmp;
-
- if(m_pSlaveRecvThread)tmp.setNum(m_pSlaveRecvThread->receivedBytes());
- else if(m_pSlaveSendThread)tmp.setNum(m_pSlaveSendThread->sentBytes());
- else tmp = '0';
-
- m_eGeneralStatus = Failure;
- m_tTransferEndTime = kvi_unixTime();
- m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc");
- m_szStatusString += __tr2qs_ctx("Aborted","dcc");
-
- KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),QString("Aborted by user"),QString(tmp.ptr()),m_pDescriptor->idString());
-
- outputAndLog(KVI_OUT_DCCERROR,m_szStatusString);
- displayUpdate();
-}
-
-
-void KviDccFileTransfer::fillContextPopup(KviTalPopupMenu * m,int column)
-{
- m->insertItem(__tr2qs_ctx("Configure Bandwidth...","dcc"),this,SLOT(configureBandwidth()));
- m->insertSeparator();
- m->insertItem(__tr2qs_ctx("Resend DCC","dcc"),this,SLOT(retryDCC()));
- m->insertItem(__tr2qs_ctx("Resend TDCC","dcc"),this,SLOT(retryTDCC()));
- m->insertItem(__tr2qs_ctx("Resend RevDCC","dcc"),this,SLOT(retryRevDCC()));
- /* FIX ME credo che il problema sia che se riavvio un trasferimento, a sua volta gia'
- avviato, questo non ha irc contex, perche' la finestra "in cui e' nato"e' sta
- quella della dcc. Conservarsi l'id della finestra? */
- int id = m->insertItem(__tr2qs_ctx("Abort","dcc"),this,SLOT(abort()));
- if(!active())m->setItemEnabled(id,false);
-}
-
-void KviDccFileTransfer::configureBandwidth()
-{
- if(m_pBandwidthDialog)return;
- m_pBandwidthDialog = new KviDccFileTransferBandwidthDialog(g_pFrame,this);
- connect(m_pBandwidthDialog,SIGNAL(destroyed()),this,SLOT(bandwidthDialogDestroyed()));
- m_pBandwidthDialog->setModal(true);
- m_pBandwidthDialog->show();
-}
-
-void KviDccFileTransfer::retryDCC()
-{
- abort();
- QString szRemoteNick = m_pDescriptor->remoteNick();
- QString szFileName = m_pDescriptor->localFileName();
- QString szId;
- szId.setNum(m_pDescriptor->id());
- QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + "\"" + szFileName + "\"";
- KviKvsScript::run(szCommand,g_pActiveWindow);
-}
-
-void KviDccFileTransfer::retryTDCC()
-{
- abort();
- QString szRemoteNick = m_pDescriptor->remoteNick();
- QString szFileName = m_pDescriptor->localFileName();
- QString szId;
- szId.setNum(m_pDescriptor->id());
- QString szCommand = "dcc.send -r=$console($dcc.irccontext(" + szId + ")) -t " + szRemoteNick + " " + "\"" + szFileName + "\"";
- KviKvsScript::run(szCommand,g_pActiveWindow);
-}
-void KviDccFileTransfer::retryRevDCC()
-{
- abort();
- QString szRemoteNick = m_pDescriptor->remoteNick();
- QString szFileName = m_pDescriptor->localFileName();
- QString szId;
- szId.setNum(m_pDescriptor->id());
- QString szCommand = "dcc.rsend -z -r=$console($dcc.irccontext(" + szId + ")) " + szRemoteNick + " " + "\"" + szFileName + "\"";
- KviKvsScript::run(szCommand,g_pActiveWindow);
-}
-
-void KviDccFileTransfer::fillStatusString(QString &szBuffer)
-{
- switch(m_eGeneralStatus)
- {
- case Connecting:
- szBuffer = "connecting";
- break;
- case Transferring:
- szBuffer = "transferring";
- break;
- case Failure:
- szBuffer = "failure";
- break;
- case Success:
- szBuffer = "success";
- break;
- default:
- szBuffer = "unknown";
- break;
- }
-}
-
-bool KviDccFileTransfer::active()
-{
- return ((m_eGeneralStatus == Connecting) || (m_eGeneralStatus == Transferring));
-}
-
-int KviDccFileTransfer::bandwidthLimit()
-{
- int iLimit = m_uMaxBandwidth; // we have the cached value anyway...
- if(m_pDescriptor->bRecvFile)
- {
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->initGetInfo();
- iLimit = (int)m_pSlaveRecvThread->bandwidthLimit();
- m_pSlaveRecvThread->doneGetInfo();
- if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT;
- }
- } else {
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->initGetInfo();
- iLimit = (int)m_pSlaveSendThread->bandwidthLimit();
- m_pSlaveSendThread->doneGetInfo();
- if(iLimit < 0)iLimit = MAX_DCC_BANDWIDTH_LIMIT;
- }
- }
- return iLimit;
-}
-
-void KviDccFileTransfer::setBandwidthLimit(int iVal)
-{
- if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT;
- if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT;
- m_uMaxBandwidth = iVal;
- if(m_pDescriptor->bRecvFile)
- {
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->initGetInfo();
- m_pSlaveRecvThread->setBandwidthLimit(iVal);
- m_pSlaveRecvThread->doneGetInfo();
- }
- } else {
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->initGetInfo();
- m_pSlaveSendThread->setBandwidthLimit(iVal);
- m_pSlaveSendThread->doneGetInfo();
- }
- }
-}
-
-unsigned int KviDccFileTransfer::averageSpeed()
-{
- unsigned int iAvgBandwidth = 0;
- if(m_pDescriptor->bRecvFile)
- {
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->initGetInfo();
- iAvgBandwidth = (unsigned int)m_pSlaveRecvThread->averageSpeed();
- m_pSlaveRecvThread->doneGetInfo();
- }
- } else {
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->initGetInfo();
- iAvgBandwidth = (unsigned int)m_pSlaveSendThread->averageSpeed();
- m_pSlaveSendThread->doneGetInfo();
- }
- }
- return iAvgBandwidth;
-}
-
-unsigned int KviDccFileTransfer::transferredBytes()
-{
- unsigned int uTransferred = 0;
- if(m_pDescriptor->bRecvFile)
- {
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->initGetInfo();
- uTransferred = m_pSlaveRecvThread->filePosition();
- m_pSlaveRecvThread->doneGetInfo();
- }
- } else {
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->initGetInfo();
- uTransferred = m_pSlaveSendThread->filePosition();
- m_pSlaveSendThread->doneGetInfo();
- }
- }
- return uTransferred;
-}
-
-void KviDccFileTransfer::displayPaint(QPainter * p,int column,int width,int height)
-{
-
- QString txt;
- bool bIsTerminated = ((m_eGeneralStatus == Success) || (m_eGeneralStatus == Failure));
-
- switch(column)
- {
- case COLUMN_TRANSFERTYPE:
- {
- int xoffset = 0;
- int yoffset = 0;
- if(m_pDescriptor->bRecvFile)yoffset = 64;
- switch(m_eGeneralStatus)
- {
- case Connecting: xoffset = 0; break;
- case Transferring: xoffset = 48; break;
- case Success: xoffset = 96; break;
- case Failure: xoffset = 144; break;
- }
- p->drawPixmap(3,3,*g_pDccFileTransferIcon,xoffset,yoffset,48,64);
- }
- break;
- case COLUMN_FILEINFO:
- {
-
- QFontMetrics fm(p->font());
-
- QString szFrom = __tr2qs_ctx("From: ","dcc");
- QString szTo = __tr2qs_ctx("To: ","dcc");
-
- int daW1 = fm.width(szFrom);
- int daW2 = fm.width(szTo);
- if(daW1 < daW2)daW1 = daW2;
- int iLineSpacing = fm.lineSpacing();
-
- int iY = 4;
-
- p->setPen(Qt::black);
-
- KviStr szRemote(KviStr::Format,"dcc://%s@%s:%s/%s",m_pDescriptor->szNick.utf8().data(),m_pDescriptor->szIp.utf8().data(),m_pDescriptor->szPort.utf8().data(),
- m_pDescriptor->szFileName.utf8().data());
-
- p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,
- m_pDescriptor->bRecvFile ? szRemote.ptr() : m_pDescriptor->szLocalFileName.utf8().data());
- iY += iLineSpacing;
-
- p->drawText(4 + daW1,iY,width - (8 + daW1),height - 8,Qt::AlignTop | Qt::AlignLeft,
- m_pDescriptor->bRecvFile ? m_pDescriptor->szLocalFileName.utf8().data() : szRemote.ptr());
- iY += iLineSpacing;
-
-
- p->setPen(Qt::darkGray);
-
- p->drawText(4,4,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szFrom);
- p->drawText(4,4 + iLineSpacing,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,szTo);
-
-
- p->setPen(QColor(180,180,200));
-
- iLineSpacing += 2;
-
- p->drawRect(4,height - (iLineSpacing + 4),width - 8,iLineSpacing);
- p->fillRect(5,height - (iLineSpacing + 3),width - 10,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
-
- p->setPen(Qt::black);
-
- p->drawText(7,height - (iLineSpacing + 4),width - 14,iLineSpacing,Qt::AlignVCenter | Qt::AlignLeft,m_szStatusString);
-
- }
- break;
- case COLUMN_PROGRESS:
- {
-
- QFontMetrics fm(p->font());
-
- int iW = width - 8;
- int iAvgBandwidth = -1;
- int iInstantSpeed = -1;
- int iAckedBytes = -1;
-
- int iEta = -1;
-
- unsigned int uTransferred = 0;
-
- if(m_pDescriptor->bRecvFile)
- {
- if(m_pSlaveRecvThread)
- {
- m_pSlaveRecvThread->initGetInfo();
- iAvgBandwidth = m_pSlaveRecvThread->averageSpeed();
- iInstantSpeed = m_pSlaveRecvThread->instantSpeed();
- uTransferred = m_pSlaveRecvThread->filePosition();
- m_pSlaveRecvThread->doneGetInfo();
- }
- } else {
- if(m_pSlaveSendThread)
- {
- m_pSlaveSendThread->initGetInfo();
- iAvgBandwidth = m_pSlaveSendThread->averageSpeed();
- iInstantSpeed = m_pSlaveSendThread->instantSpeed();
- uTransferred = m_pSlaveSendThread->filePosition();
- iAckedBytes = m_pSlaveSendThread->ackedBytes();
- m_pSlaveSendThread->doneGetInfo();
- }
- }
-
- p->setPen(bIsTerminated ? Qt::lightGray : QColor(210,210,240));
- p->drawRect(4,4,iW,12);
-
- iW -= 2;
-
- if(m_uTotalFileSize > 0)
- {
- if(iAvgBandwidth > 0)
- {
- unsigned int uRemaining = m_uTotalFileSize - uTransferred;
- iEta = uRemaining / iAvgBandwidth;
- }
-
- if(!m_pDescriptor->bNoAcks && (iAckedBytes > 0) && (iAckedBytes < ((int)(uTransferred))))
- {
- // we are sending a file and are getting acks
-
- double dPerc1 = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize;
- int iL1 = (int) ((((double)iW) * dPerc1) / 100.0);
- double dPerc2 = (double)(((double)iAckedBytes) * 100.0) / (double)m_uTotalFileSize;
- int iL2 = (int) ((((double)iW) * dPerc2) / 100.0);
- int iW2 = iL1 - iL2;
- if(iW2 > 0)p->fillRect(5 + iL2,5,iW2,10,bIsTerminated ? QColor(150,130,110) : QColor(220,170,100));
- p->fillRect(5,5,iL2,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100));
-
- txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(iAckedBytes)).arg(KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc2,0,'f',2);
- } else {
- // we are receiving a file or not sending acks
- double dPerc = (double)(((double)uTransferred) * 100.0) / (double)m_uTotalFileSize;
- int iL = (int) ((((double)iW) * dPerc) / 100.0);
- p->fillRect(5,5,iL,10,bIsTerminated ? QColor(140,110,110) : QColor(200,100,100));
-
- txt = QString(__tr2qs_ctx("%1 of %2 (%3%)","dcc")).arg(KviQString::makeSizeReadable(uTransferred)).arg(KviQString::makeSizeReadable(m_uTotalFileSize)).arg(dPerc,0,'f',2);
- }
-
- } else {
- txt = QString(__tr2qs_ctx("%1","dcc")).arg(KviQString::makeSizeReadable(uTransferred));
- }
-
- p->setPen(Qt::black);
-
- p->drawText(4,19,width - 8,height - 8,Qt::AlignTop | Qt::AlignLeft,txt);
-
- int iLeftHalf = (iW - 2) / 2;
- int iRightHalf = iW - (iLeftHalf + 1);
- int iLineSpacing = fm.lineSpacing() + 2;
-
- if(!bIsTerminated)
- {
- txt = __tr2qs_ctx("Spd:","dcc");
- txt += " ";
- if(iInstantSpeed >= 0)
- {
- QString tmpisp;
- KviNetUtils::formatNetworkBandwidthString(tmpisp,iInstantSpeed);
- txt += tmpisp;
- } else {
- txt += "? B/s";
- }
- txt += " [";
- } else {
- txt = "";
- }
-
- txt += __tr2qs_ctx("Avg:","dcc");
- txt += " ";
- if(iAvgBandwidth >= 0)
- {
- QString tmpspd;
- KviNetUtils::formatNetworkBandwidthString(tmpspd,iAvgBandwidth);
- txt += tmpspd;
- } else {
- txt += "? B/s";
- }
-
- if(!bIsTerminated)
- {
- txt += "]";
- }
-
- int iDaH = height - (iLineSpacing + 4);
-
- p->setPen(QColor(180,180,200));
- p->drawRect(4,iDaH,iLeftHalf,iLineSpacing);
- p->fillRect(5,iDaH + 1,iLeftHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
- p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
- p->drawText(6,iDaH,iLeftHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt);
-
- if(bIsTerminated)
- {
- if((m_tTransferStartTime != 0) && (m_tTransferEndTime != 0))
- {
- QString tot = KviTimeUtils::formatTimeInterval(kvi_timeSpan(m_tTransferEndTime,m_tTransferStartTime),KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes);
- txt = "TOT: ";
- txt += tot;
- } else {
- txt = "";
- }
- } else {
- if(iEta >= 0)
- {
- QString eta = KviTimeUtils::formatTimeInterval(iEta,KviTimeUtils::NoLeadingEmptyIntervals | KviTimeUtils::NoLeadingZeroes);
- txt = "ETA: ";
- txt += eta;
- } else {
- txt = "ETA: ?";
- }
- }
-
- p->setPen(QColor(180,180,200));
- p->drawRect(width - (4 + iRightHalf),iDaH,iRightHalf,iLineSpacing);
- p->fillRect(width - (3 + iRightHalf),iDaH + 1,iRightHalf - 2,iLineSpacing - 2,bIsTerminated ? QColor(210,210,210) : QColor(190,190,240));
- p->setPen(bIsTerminated ? Qt::darkGray : Qt::black);
- p->drawText(width - (2 + iRightHalf),iDaH,iRightHalf - 4,iLineSpacing,Qt::AlignLeft | Qt::AlignVCenter,txt);
-
- }
- break;
- }
-
-}
-
-int KviDccFileTransfer::displayHeight(int iLineSpacing)
-{
- int iH = (iLineSpacing * 3) + 10;
- return iH >= 70 ? iH : 70;
-}
-
-QString KviDccFileTransfer::tipText()
-{
-
- QString s;
-
- s = QString("<table><tr><td bgcolor=\"#000000\"><font color=\"#FFFFFF\"><b>DCC %1 (ID %2)</b></font></td></tr>").arg(m_szDccType.ptr()).arg(id());
-
- s += "<tr><td bgcolor=\"#404040\"><font color=\"#FFFFFF\">";
- s += __tr2qs_ctx("Transfer Log","dcc");
- s += "</font></td></tr>";
- s += "<tr><td bgcolor=\"#C0C0C0\">";
- s += m_szTransferLog;
- s += "</td></tr>";
- s += "<table>";
-
- return s;
-}
-
-void KviDccFileTransfer::init()
-{
- if(g_pDccFileTransfers)return;
- g_pDccFileTransfers = new KviPointerList<KviDccFileTransfer>;
- g_pDccFileTransfers->setAutoDelete(false);
-
- QPixmap * pix = g_pIconManager->getImage("kvi_dccfiletransfericons.png");
- if(pix)g_pDccFileTransferIcon = new QPixmap(*pix);
- else g_pDccFileTransferIcon = new QPixmap(192,128);
-}
-
-void KviDccFileTransfer::done()
-{
- if(!g_pDccFileTransfers)return;
- while(KviDccFileTransfer * t = g_pDccFileTransfers->first())
- delete t;
- delete g_pDccFileTransfers;
- g_pDccFileTransfers = 0;
- delete g_pDccFileTransferIcon;
- g_pDccFileTransferIcon = 0;
-}
-
-unsigned int KviDccFileTransfer::transferCount()
-{
- if(!g_pDccFileTransfers)return 0;
- return g_pDccFileTransfers->count();
-}
-
-KviDccFileTransfer * KviDccFileTransfer::nonFailedTransferWithLocalFileName(const QString &szLocalFileName)
-{
- if(!g_pDccFileTransfers)return 0;
- for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next())
- {
-#ifdef COMPILE_ON_WINDOWS
- // on windows the file names are case insensitive
- if(t->localFileName().lower() == szLocalFileName.lower())
-#else
- if(t->localFileName() == szLocalFileName)
-#endif
- {
- if(t->m_eGeneralStatus != Failure)
- return t;
- }
- }
- return 0;
-}
-
-
-unsigned int KviDccFileTransfer::runningTransfersCount()
-{
- if(!g_pDccFileTransfers)return 0;
- unsigned int cnt = 0;
- for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next())
- {
- if(t->active())cnt++;
- }
- return cnt;
-}
-
-bool KviDccFileTransfer::handleResumeAccepted(const char * filename,const char * port,const char * szZeroPortTag)
-{
- if(!g_pDccFileTransfers)return false;
-
- for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next())
- {
- if(t->resumeAccepted(filename,port,szZeroPortTag))return true;
- }
-
- return false;
-}
-
-bool KviDccFileTransfer::handleResumeRequest(const char * filename,const char * port,unsigned int filePos)
-{
- if(!g_pDccFileTransfers)return false;
-
- for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next())
- {
- if(t->doResume(filename,port,filePos))return true;
- }
-
- return false;
-}
-
-void KviDccFileTransfer::outputAndLog(const QString &s)
-{
- KviWindow * out = transferWindow();
- addToTransferLog(s);
- if(out)out->output(KVI_OUT_DCCMSG,"[%Q]: %Q",&m_szTransferIdString,&s);
-}
-
-void KviDccFileTransfer::outputAndLog(int msgtype,const QString &s)
-{
- KviWindow * out = transferWindow();
- addToTransferLog(s);
- if(out)out->output(msgtype,"[%Q]: %Q",&m_szTransferIdString,&s);
-}
-
-
-void KviDccFileTransfer::addToTransferLog(const QString &s)
-{
- QDateTime dt = QDateTime::currentDateTime();
- QString ts;
- ts.sprintf("[%4d.%2d.%2d %2d:%2d:%2d] ",dt.date().year(),dt.date().month(),dt.date().day(),dt.time().hour(),dt.time().minute(),dt.time().second());
- m_szTransferLog += ts+s;
- m_szTransferLog += "<br>";
-}
-
-
-void KviDccFileTransfer::connectionInProgress()
-{
- if(m_pDescriptor->bActive)
- {
- // ACTIVE CONNECTION
-// if((kvi_strEqualCS(m_szDccType.ptr(), "RECV")) || (kvi_strEqualCS(m_szDccType.ptr(),"TRECV")))
-// {
-// // FIXME: that's not true!... we're NOT connected here
-// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCGetConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr()));
-// } else {
-// if(TRIGGER_EVENT_5PARAM_RETVALUE(KviEvent_OnDCCSendConnected,this,m_pDescriptor->szPort.ptr(),m_pDescriptor->szFileName.ptr(),m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),m_pDescriptor->szHost.ptr()));
-// }
-//
- m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp).arg(m_pDescriptor->szPort);
- outputAndLog(m_szStatusString);
- displayUpdate();
- return;
- }
-
- // PASSIVE CONNECTION
- m_szStatusString = __tr2qs_ctx("Listening on interface %1 port %2","dcc").arg(m_pMarshal->localIp()).arg(m_pMarshal->localPort());
- outputAndLog(m_szStatusString);
-
- if(m_pDescriptor->bSendRequest)
- {
- QString ip;
- if(!m_pDescriptor->szFakeIp.isEmpty())
- {
- ip = m_pDescriptor->szFakeIp;
- } else {
- ip = m_pDescriptor->szListenIp;
-
- if(KVI_OPTION_BOOL(KviOption_boolDccGuessIpFromServerWhenLocalIsUnroutable))
- {
- if(!KviNetUtils::isRoutableIpString(ip))
- {
- // try to get the IP that the IRC server can see
- if(m_pDescriptor->console())
- {
- QString tmp = m_pDescriptor->console()->connection() ? m_pDescriptor->console()->connection()->userInfo()->hostIp() : "";
- if(!tmp.isEmpty())
- {
- ip = tmp;
- outputAndLog(__tr2qs_ctx("The local IP address is private, determining from IRC server: %1","dcc").arg(ip));
- } else {
- outputAndLog(__tr2qs_ctx("The local IP address is private, but unable to determine it from the IRC server","dcc"));
- }
- } else {
- outputAndLog(__tr2qs_ctx("The local IP address is private, but have no IRC server to determine it from","dcc"));
- }
- }
- }
- }
-
- KviStr port = !m_pDescriptor->szFakePort.isEmpty() ? m_pDescriptor->szFakePort : m_pMarshal->localPort();
- //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned nuumber)"
- struct in_addr a;
- if(KviNetUtils::stringIpToBinaryIp(ip,&a))ip.setNum(htonl(a.s_addr));
-
- QString tmp = m_pDescriptor->szFileName;
- // just to be sure
- KviQString::cutToLast(tmp,'/');
- KviQString::cutToLast(tmp,'\\');
-
- QString fName;
-
- // BUG-TO-BUG mIrc compatibility
- if(KVI_OPTION_BOOL(KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores))
- tmp.replace(" ","_");
-
- KviServerParser::encodeCtcpParameter(tmp.utf8().data(),fName);
- // Zero port requests want DCC SEND as back-request
- KviStr szReq;
-
- if(m_pDescriptor->isZeroPortRequest())
- {
- szReq = "SEND";
- m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %s %s%c",
- m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
- 0x01,
- m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(),
- m_pDescriptor->console()->connection()->encodeText(fName).data(),
- ip.utf8().data(),port.ptr(),
- m_pDescriptor->szFileSize.utf8().data(),m_pDescriptor->zeroPortRequestTag(),0x01);
- } else {
- szReq = m_szDccType;
- m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC %s %s %s %s %Q%c",
- m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
- 0x01,
- m_pDescriptor->console()->connection()->encodeText(szReq.ptr()).data(),
- m_pDescriptor->console()->connection()->encodeText(fName).data(),
- ip.utf8().data(),port.ptr(),
- &(m_pDescriptor->szLocalFileSize),0x01);
- }
- outputAndLog(__tr2qs_ctx("Sent DCC %1 request to %2, waiting for remote client to connect...","dcc").arg(szReq.ptr()).arg(m_pDescriptor->szNick));
- } else {
- outputAndLog(__tr2qs_ctx("DCC %1 request not sent, awaiting manual connection","dcc").arg(m_szDccType.ptr()));
- }
-
- KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferConnectionInProgress,eventWindow(),m_pDescriptor->idString());
-
- displayUpdate();
-}
-
-void KviDccFileTransfer::startingSSLHandshake()
-{
-#ifdef COMPILE_SSL_SUPPORT
- outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Low-level transport connection established","dcc"));
- outputAndLog(KVI_OUT_SSL,__tr2qs_ctx("Starting Secure Socket Layer handshake","dcc"));
-#endif
-}
-
-void KviDccFileTransfer::sslError(const char * msg)
-{
-#ifdef COMPILE_SSL_SUPPORT
- outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("[SSL ERROR]: %1","dcc").arg(msg));
-#endif
-}
-
-
-
-
-bool KviDccFileTransfer::event(QEvent *e)
-{
- if(e->type() == KVI_THREAD_EVENT)
- {
- switch(((KviThreadEvent *)e)->id())
- {
- case KVI_DCC_THREAD_EVENT_ERROR:
- {
- int * err = ((KviThreadDataEvent<int> *)e)->getData();
- QString szErrorString = KviError::getDescription(*err);
- delete err;
- if(m_pDescriptor->bRecvFile)
- g_pApp->fileDownloadTerminated(false,m_pDescriptor->szFileName.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data(),szErrorString.utf8().data());
-
- m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc");
- m_szStatusString += szErrorString;
- m_eGeneralStatus = Failure;
- m_tTransferEndTime = kvi_unixTime();
-
- KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,
- eventWindow(),
- szErrorString,
- (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()),
- m_pDescriptor->idString());
-
- outputAndLog(KVI_OUT_DCCERROR,m_szStatusString);
- displayUpdate();
- return true;
- }
- break;
- case KVI_DCC_THREAD_EVENT_SUCCESS:
- {
- // FIXME: for >= 3.2.0 change this text to
- // File Upload/Download terminated, or something like this
- if(KVI_OPTION_BOOL(KviOption_boolNotifyDccSendSuccessInConsole))
- {
- KviConsole *c;
- if(!g_pApp->windowExists(m_pDescriptor->console())) c=g_pApp->activeConsole();
- else c=m_pDescriptor->console();
- c->output(KVI_OUT_DCCMSG,__tr2qs_ctx("DCC %s transfer with %Q@%Q:%Q completed: \r![!dbl]play $0\r%s\r","dcc"),
- m_pDescriptor->bIsTdcc ? (m_pDescriptor->bRecvFile ? "TRECV" : "TSEND") : (m_pDescriptor->bRecvFile ? "RECV" : "SEND"),
- &(m_pDescriptor->szNick),&(m_pDescriptor->szIp),&(m_pDescriptor->szPort),
- &(m_pDescriptor->szLocalFileName));
- }
- /*
- // Also add an optional message to the notifier, unless it is an AVATAR download!
- if(KVI_OPTION_BOOL(KviOption_boolNotifiDccDownloadSuccessInNotifier))
- {
- QString szMsg;
- KviQString::sprintf(szMsg,__tr2qs_ctx(""));
- g_pApp->notifierMessage(0,KVI_SMALLICON_DCCMSG,szMsg,30);
- }
- */
- if(m_pDescriptor->bRecvFile)g_pApp->fileDownloadTerminated(true,m_pDescriptor->szFileName.utf8().data(),m_pDescriptor->szLocalFileName.utf8().data(),m_pDescriptor->szNick.utf8().data());
- m_szStatusString = __tr2qs_ctx("Transfer completed","dcc");
- outputAndLog(m_szStatusString);
- m_eGeneralStatus = Success;
- m_tTransferEndTime = kvi_unixTime();
-
- KVS_TRIGGER_EVENT_2(KviEvent_OnDCCFileTransferSuccess,
- eventWindow(),
- (kvs_int_t)(m_pSlaveRecvThread ? m_pSlaveRecvThread->receivedBytes() : m_pSlaveSendThread->sentBytes()),
- m_pDescriptor->idString());
-
- displayUpdate();
-
- if(KVI_OPTION_BOOL(KviOption_boolAutoCloseDccSendOnSuccess))die();
- return true;
- }
- break;
- case KVI_DCC_THREAD_EVENT_MESSAGE:
- {
- KviStr * str = ((KviThreadDataEvent<KviStr> *)e)->getData();
- outputAndLog(QString(__tr_no_xgettext_ctx(str->ptr(),"dcc")));
- delete str;
- return true;
- }
- break;
- default:
- debug("Invalid event type %d received",((KviThreadEvent *)e)->id());
- break;
- }
- }
-//#warning "Remove this!"
-// if(e->type() == QEvent::Close)debug("Close event received");
- return KviFileTransfer::event(e);
-}
-
-void KviDccFileTransfer::handleMarshalError(int err)
-{
- QString szErr = KviError::getDescription(err);
- m_eGeneralStatus = Failure;
- m_szStatusString = __tr2qs_ctx("Transfer failed: ","dcc");
- m_szStatusString += szErr;
- outputAndLog(m_szStatusString);
- KVS_TRIGGER_EVENT_3(KviEvent_OnDCCFileTransferFailed,eventWindow(),szErr,(kvs_int_t)0,m_pDescriptor->idString());
- displayUpdate();
-}
-
-void KviDccFileTransfer::connected()
-{
- outputAndLog(__tr2qs_ctx("Connected to %1:%2","dcc").arg(m_pMarshal->remoteIp()).arg(m_pMarshal->remotePort()));
- outputAndLog(__tr2qs_ctx("Local end is %1:%2","dcc").arg(m_pMarshal->localIp()).arg(m_pMarshal->localPort()));
-
- m_tTransferStartTime = kvi_unixTime();
-
- if(!(m_pDescriptor->bActive))
- {
- m_pDescriptor->szIp = m_pMarshal->remoteIp();
- m_pDescriptor->szPort = m_pMarshal->remotePort();
- m_pDescriptor->szHost = m_pMarshal->remoteIp();
- }
-
- if(m_pDescriptor->bRecvFile)
- {
- KviDccRecvThreadOptions * o = new KviDccRecvThreadOptions;
- o->szFileName = m_pDescriptor->szLocalFileName.utf8().data();
- bool bOk;
- o->iTotalFileSize = m_pDescriptor->szFileSize.toInt(&bOk);
- if(!bOk)o->iTotalFileSize = -1;
- o->bResume = m_pDescriptor->bResume;
- o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0;
- o->bIsTdcc = m_pDescriptor->bIsTdcc;
- o->bSendZeroAck = KVI_OPTION_BOOL(KviOption_boolSendZeroAckInDccRecv);
- o->bNoAcks = m_pDescriptor->bNoAcks;
- o->uMaxBandwidth = m_uMaxBandwidth;
- m_pSlaveRecvThread = new KviDccRecvThread(this,m_pMarshal->releaseSocket(),o);
- m_pSlaveRecvThread->start();
- } else {
- KviDccSendThreadOptions * o = new KviDccSendThreadOptions;
- o->szFileName = m_pDescriptor->szLocalFileName.utf8().data();
- o->bFastSend = KVI_OPTION_BOOL(KviOption_boolUseFastDccSend);
- o->iIdleStepLengthInMSec = KVI_OPTION_BOOL(KviOption_boolDccSendForceIdleStep) ? KVI_OPTION_UINT(KviOption_uintDccSendIdleStepInMSec) : 0;
- bool bOk;
- o->bIsTdcc = m_pDescriptor->bIsTdcc;
- o->iStartPosition = m_pDescriptor->szFileSize.toInt(&bOk);
- if(!bOk || (o->iStartPosition < 0))o->iStartPosition = 0;
- o->iPacketSize = KVI_OPTION_UINT(KviOption_uintDccSendPacketSize);
- if(o->iPacketSize < 32)o->iPacketSize = 32;
- o->uMaxBandwidth = m_uMaxBandwidth;
- o->bNoAcks = m_pDescriptor->bNoAcks;
- m_pSlaveSendThread = new KviDccSendThread(this,m_pMarshal->releaseSocket(),o);
- m_pSlaveSendThread->start();
- }
-
- m_eGeneralStatus = Transferring;
- m_szStatusString = __tr2qs_ctx("Transferring data","dcc");
-
- KVS_TRIGGER_EVENT_1(KviEvent_OnDCCFileTransferBegin,eventWindow(),m_pDescriptor->idString());
-
- outputAndLog(m_szStatusString);
- displayUpdate();
-}
-
-bool KviDccFileTransfer::resumeAccepted(const char *filename,const char *port,const char *szZeroPortTag)
-{
- if(!(kvi_strEqualCI(filename,m_pDescriptor->szFileName.utf8().data()) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests)))
- return false;
-
- if(!(kvi_strEqualCI(port,m_pDescriptor->szPort.utf8().data()) &&
- (!m_pSlaveRecvThread) && m_pDescriptor->bResume && m_pDescriptor->bRecvFile && m_pResumeTimer))
- return false;
-
- if(kvi_strEqualCI(port,"0"))
- {
- if(!kvi_strEqualCI(szZeroPortTag,m_pDescriptor->zeroPortRequestTag()))
- return false;
- }
-
- delete m_pResumeTimer;
- m_pResumeTimer = 0;
-
- outputAndLog(__tr2qs_ctx("RESUME accepted, transfer will begin at position %1","dcc").arg(m_pDescriptor->szLocalFileSize));
-
- listenOrConnect();
-
- /*
- int ret = m_pMarshal->dccConnect(m_pDescriptor->szIp.utf8().data(),
- m_pDescriptor->szPort.utf8().data(),m_pDescriptor->bDoTimeout);
-
- if(ret != KviError_success)handleMarshalError(ret);
- else {
- m_szStatusString = __tr2qs_ctx("Contacting host %1 on port %2","dcc").arg(m_pDescriptor->szIp).arg(m_pDescriptor->szPort);
- outputAndLog(m_szStatusString);
- displayUpdate();
- }
- */
-
- return true;
-}
-
-bool KviDccFileTransfer::doResume(const char * filename,const char * port,unsigned int filePos)
-{
- if(KviQString::equalCI(port,m_pMarshal->dccPort()) &&
- (!m_pSlaveRecvThread) && (!m_pDescriptor->bRecvFile))
- {
- if(KviQString::equalCI(filename,m_pDescriptor->szFileName) || KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests))
- {
- bool bOk;
- unsigned int iLocalFileSize = m_pDescriptor->szLocalFileSize.toUInt(&bOk);
- if(!bOk)
- {
- // ops...internal error
- outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Internal error in RESUME request","dcc"));
- return false;
- }
- if(iLocalFileSize <= filePos)
- {
- outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Invalid RESUME request: Position %1 is larger than file size","dcc").arg(filePos));
- return false;
- }
-
- outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Accepting RESUME request, transfer will begin at position %1","dcc").arg(filePos));
-
- m_pDescriptor->szFileSize.setNum(filePos);
-
-
- KviStr szBuffy;
- KviServerParser::encodeCtcpParameter(filename,szBuffy);
-
- m_pDescriptor->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC ACCEPT %s %s %u%c",
- m_pDescriptor->console()->connection()->encodeText(m_pDescriptor->szNick).data(),
- 0x01,
- m_pDescriptor->console()->connection()->encodeText(szBuffy.ptr()).data(),
- port,filePos,0x01);
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
-
-KviDccFileTransferBandwidthDialog::KviDccFileTransferBandwidthDialog(QWidget * pParent,KviDccFileTransfer * t)
-: QDialog(pParent)
-{
- QGridLayout * g = new QGridLayout(this,3,3,4,4);
-
- m_pTransfer = t;
- int iVal = m_pTransfer->bandwidthLimit();
-
- QString szText = __tr2qs_ctx("Configure bandwidth for DCC transfer %1","dcc").arg(t->id());
- setCaption(szText);
-
- szText = t->isFileUpload() ? __tr2qs_ctx("Limit upload bandwidth to","dcc") : __tr2qs_ctx("Limit download bandwidth to","dcc");
-
- m_pEnableLimitCheck = new KviStyledCheckBox(szText,this);
- g->addWidget(m_pEnableLimitCheck,0,0);
-
- m_pEnableLimitCheck->setChecked((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT));
-
- m_pLimitBox = new QSpinBox(0,MAX_DCC_BANDWIDTH_LIMIT-1,1,this);
- m_pLimitBox->setEnabled((iVal >= 0) && (iVal < MAX_DCC_BANDWIDTH_LIMIT));
- connect(m_pEnableLimitCheck,SIGNAL(toggled(bool)),m_pLimitBox,SLOT(setEnabled(bool)));
- g->addMultiCellWidget(m_pLimitBox,0,0,1,2);
-
- szText = " ";
- szText += __tr2qs_ctx("bytes/sec","dcc");
- m_pLimitBox->setSuffix(szText);
- m_pLimitBox->setValue(iVal < MAX_DCC_BANDWIDTH_LIMIT ? iVal : 0);
-
- QPushButton * pb = new QPushButton(__tr2qs_ctx("OK","dcc"),this);
- connect(pb,SIGNAL(clicked()),this,SLOT(okClicked()));
- pb->setMinimumWidth(80);
- g->addWidget(pb,2,2);
-
- pb = new QPushButton(__tr2qs_ctx("Cancel","dcc"),this);
- connect(pb,SIGNAL(clicked()),this,SLOT(cancelClicked()));
- pb->setMinimumWidth(80);
- g->addWidget(pb,2,1);
-
- g->setColStretch(0,1);
- g->setRowStretch(1,1);
-}
-
-KviDccFileTransferBandwidthDialog::~KviDccFileTransferBandwidthDialog()
-{
-}
-
-void KviDccFileTransferBandwidthDialog::okClicked()
-{
- int iVal = MAX_DCC_BANDWIDTH_LIMIT;
- if(m_pEnableLimitCheck->isChecked())
- {
- iVal = m_pLimitBox->value();
- if(iVal < 0)iVal = MAX_DCC_BANDWIDTH_LIMIT;
- if(iVal > MAX_DCC_BANDWIDTH_LIMIT)iVal = MAX_DCC_BANDWIDTH_LIMIT;
- }
- m_pTransfer->setBandwidthLimit(iVal);
- delete this;
-}
-
-void KviDccFileTransferBandwidthDialog::cancelClicked()
-{
- delete this;
-}
-
-void KviDccFileTransferBandwidthDialog::closeEvent(QCloseEvent * e)
-{
- e->ignore();
- delete this;
-}
-
-
-
-
-#include "m_send.moc"