aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2010-06-02 14:57:24 +0000
committerGravatar Szymon Tomasz Stefanek2010-06-02 14:57:24 +0000
commit0edeeda7aa5ba240293cc2055666042b3e1a59fc (patch)
tree25c39452c7762a4eeafb836b8dab7d84820fe40f /src
parentSome fixes in classeditor + code improvements in tablewidget kvs class (diff)
downloadKVIrc-0edeeda7aa5ba240293cc2055666042b3e1a59fc.tar.gz
KVIrc-0edeeda7aa5ba240293cc2055666042b3e1a59fc.tar.bz2
KVIrc-0edeeda7aa5ba240293cc2055666042b3e1a59fc.zip
DCC works. Support 64bit resume offsets. Add option for routers that remap DCC SEND but not DCC RESUME. Some cleanups...
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@4417 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src')
-rw-r--r--src/kvilib/core/kvi_string.cpp46
-rw-r--r--src/kvilib/core/kvi_string.h2
-rw-r--r--src/kvirc/kernel/kvi_options.cpp5
-rw-r--r--src/kvirc/kernel/kvi_options.h4
-rw-r--r--src/modules/dcc/broker.cpp25
-rw-r--r--src/modules/dcc/requests.cpp2
-rw-r--r--src/modules/dcc/send.cpp111
-rw-r--r--src/modules/options/optw_dcc.cpp10
8 files changed, 155 insertions, 50 deletions
diff --git a/src/kvilib/core/kvi_string.cpp b/src/kvilib/core/kvi_string.cpp
index a561c891b..bd3c851bd 100644
--- a/src/kvilib/core/kvi_string.cpp
+++ b/src/kvilib/core/kvi_string.cpp
@@ -2337,6 +2337,52 @@ KviStr & KviStr::setNum(unsigned long num)
return (*this);
}
+long long KviStr::toLongLong(bool *bOk) const
+{
+ long long result = 0;
+ if(bOk)*bOk = false;
+ register char *p=m_ptr;
+ bool bNeg = false;
+ while(isspace(*p))p++; //skip spaces
+ if(*p == '-'){
+ bNeg = true;
+ p++;
+ } else {
+ if(*p == '+')p++;
+ }
+ if(isdigit(*p)){ //point to something interesting ?
+ do{
+ result = (result * 10) + (*p - '0');
+ p++;
+ } while(isdigit(*p));
+ if(bNeg)result = -result;
+ while(isspace(*p))p++; //skip trailing spaces
+ if(*p)return 0; //if this is not the end...die.
+ if(bOk)*bOk = true;
+ return result;
+ }
+ return 0;
+}
+
+unsigned long long KviStr::toULongLong(bool *bOk) const
+{
+ unsigned long long result = 0;
+ if(bOk)*bOk = false;
+ register char *p=m_ptr;
+ while(isspace(*p))p++; //skip spaces
+ if(isdigit(*p)){ //point to something interesting ?
+ do{
+ result = (result * 10) + (*p - '0');
+ p++;
+ } while(isdigit(*p));
+ while(isspace(*p))p++; //skip trailing spaces
+ if(*p)return 0; //if this is not the end...die.
+ if(bOk)*bOk = true;
+ return result;
+ }
+ return 0;
+}
+
long KviStr::toLong(bool *bOk) const
{
long result = 0;
diff --git a/src/kvilib/core/kvi_string.h b/src/kvilib/core/kvi_string.h
index 6b32c2f8f..381c97927 100644
--- a/src/kvilib/core/kvi_string.h
+++ b/src/kvilib/core/kvi_string.h
@@ -415,6 +415,8 @@ public:
// everything in base 10.... no overflow checks here
long toLong(bool *bOk=0) const;
unsigned long toULong(bool *bOk=0) const;
+ long long toLongLong(bool *bOk=0) const;
+ unsigned long long toULongLong(bool *bOk=0) const;
char toChar(bool *bOk=0) const { return (char)toLong(bOk); };
unsigned char toUChar(bool *bOk=0) const { return (unsigned char)toULong(bOk); };
int toInt(bool *bOk=0) const { return (int)toLong(bOk); };
diff --git a/src/kvirc/kernel/kvi_options.cpp b/src/kvirc/kernel/kvi_options.cpp
index 516730a5c..0401b30e3 100644
--- a/src/kvirc/kernel/kvi_options.cpp
+++ b/src/kvirc/kernel/kvi_options.cpp
@@ -196,7 +196,7 @@ KviBoolOption g_boolOptionsTable[KVI_NUM_BOOL_OPTIONS]=
BOOL_OPTION("AutoJoinOnInvite",false,KviOption_sectFlagConnection),
BOOL_OPTION("ShowServersConnectDialogOnStart",true, KviOption_sectFlagFrame),
BOOL_OPTION("ShowServersConnectDialogAsToplevel",true,KviOption_sectFlagFrame),
- BOOL_OPTION("AcceptBrokenFileNameDccResumeRequests",true,KviOption_sectFlagFrame),
+ BOOL_OPTION("AcceptBrokenFileNameDccResumeRequests",true,KviOption_sectFlagDcc),
BOOL_OPTION("AutoReconnectOnUnexpectedDisconnect",true,KviOption_sectFlagFrame),
BOOL_OPTION("RejoinChannelsAfterReconnect",true,KviOption_sectFlagFrame),
BOOL_OPTION("ReopenQueriesAfterReconnect",true,KviOption_sectFlagFrame),
@@ -326,7 +326,8 @@ KviBoolOption g_boolOptionsTable[KVI_NUM_BOOL_OPTIONS]=
BOOL_OPTION("FrameIsMaximized",false,KviOption_sectFlagGeometry),
BOOL_OPTION("PrependNickColorInfoToRealname",true,KviOption_sectFlagConnection),
BOOL_OPTION("DontShowNotifierIfActiveWindowIsFullScreen",false,KviOption_sectFlagFrame),
- BOOL_OPTION("WheelScrollsWindowsList",true,KviOption_sectFlagWindowList)
+ BOOL_OPTION("WheelScrollsWindowsList",true,KviOption_sectFlagWindowList),
+ BOOL_OPTION("AcceptMismatchedPortDccResumeRequests",false,KviOption_sectFlagDcc)
};
#define STRING_OPTION(_txt,_val,_flags) KviStringOption(KVI_STRING_OPTIONS_PREFIX _txt,_val,_flags)
diff --git a/src/kvirc/kernel/kvi_options.h b/src/kvirc/kernel/kvi_options.h
index 50f51a90f..609fdb552 100644
--- a/src/kvirc/kernel/kvi_options.h
+++ b/src/kvirc/kernel/kvi_options.h
@@ -335,8 +335,10 @@ DECLARE_OPTION_STRUCT(KviStringListOption,QStringList)
#define KviOption_boolPrependNickColorInfoToRealname 241
#define KviOption_boolDontShowNotifierIfActiveWindowIsFullScreen 242 /* notifier */
#define KviOption_boolWheelScrollsWindowsList 243
+#define KviOption_boolAcceptMismatchedPortDccResumeRequests 244 /* dcc::send */
-#define KVI_NUM_BOOL_OPTIONS 244
+
+#define KVI_NUM_BOOL_OPTIONS 245
#define KVI_STRING_OPTIONS_PREFIX "string"
diff --git a/src/modules/dcc/broker.cpp b/src/modules/dcc/broker.cpp
index 2b82d8a5a..820fc781d 100644
--- a/src/modules/dcc/broker.cpp
+++ b/src/modules/dcc/broker.cpp
@@ -957,18 +957,17 @@ bool KviDccBroker::handleResumeRequest(KviDccRequest * dcc,const char * filename
KviDccZeroPortTag * t = findZeroPortTag(QString(szZeroPortTag));
if(t)
{
- //debug("FOUND");
// valid zero port resume request
- if(filePos < t->m_uFileSize)
- {
- //debug("VALID");
- // ok!
- t->m_uResumePosition = filePos;
+ if(filePos >= t->m_uFileSize)
+ return false; // invalid resume size
+
+ // ok!
+ t->m_uResumePosition = filePos;
- KviStr szBuffy;
- KviServerParser::encodeCtcpParameter(filename,szBuffy);
+ KviStr szBuffy;
+ KviServerParser::encodeCtcpParameter(filename,szBuffy);
- dcc->ctcpMsg->msg->console()->connection()->sendFmtData(
+ dcc->ctcpMsg->msg->console()->connection()->sendFmtData(
"PRIVMSG %s :%cDCC ACCEPT %s %s %u %s%c",
dcc->ctcpMsg->msg->console()->connection()->encodeText(dcc->ctcpMsg->pSource->nick()).data(),
0x01,
@@ -976,12 +975,10 @@ bool KviDccBroker::handleResumeRequest(KviDccRequest * dcc,const char * filename
port,
filePos,
szZeroPortTag,
- 0x01);
+ 0x01
+ );
- return true;
- } else {
- return false; // invalid resume size
- }
+ return true;
}
}
//debug("NOT A ZeRO PORT");
diff --git a/src/modules/dcc/requests.cpp b/src/modules/dcc/requests.cpp
index 88d6fe968..f758d36ec 100644
--- a/src/modules/dcc/requests.cpp
+++ b/src/modules/dcc/requests.cpp
@@ -566,7 +566,7 @@ static void dccModuleParseDccResume(KviDccRequest *dcc)
// DCC SEND <filename> <remoteip> <remoteport> <filesize> <tag>
bool bOk;
- quint64 filePos = dcc->szParam3.toULong(&bOk);
+ quint64 filePos = (quint64)(dcc->szParam3.toULongLong(&bOk));
if(!bOk)
{
if(!dcc->ctcpMsg->msg->haltOutput())
diff --git a/src/modules/dcc/send.cpp b/src/modules/dcc/send.cpp
index f9da44da8..b3a8628b0 100644
--- a/src/modules/dcc/send.cpp
+++ b/src/modules/dcc/send.cpp
@@ -1438,11 +1438,13 @@ bool KviDccFileTransfer::handleResumeAccepted(const char * filename,const char *
bool KviDccFileTransfer::handleResumeRequest(const char * filename,const char * port,quint64 filePos)
{
- if(!g_pDccFileTransfers)return false;
+ if(!g_pDccFileTransfers)
+ return false;
for(KviDccFileTransfer * t = g_pDccFileTransfers->first();t;t = g_pDccFileTransfers->next())
{
- if(t->doResume(filename,port,filePos))return true;
+ if(t->doResume(filename,port,filePos))
+ return true;
}
return false;
@@ -1785,42 +1787,89 @@ bool KviDccFileTransfer::resumeAccepted(const char *filename,const char *port,co
bool KviDccFileTransfer::doResume(const char * filename,const char * port,quint64 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;
- quint64 iLocalFileSize = m_pDescriptor->szLocalFileSize.toULongLong(&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;
- }
+ if(m_pSlaveRecvThread)
+ return false; // we're already receiving stuff...
+ if(m_pSlaveSendThread)
+ return false; // we're already sending stuff...
- outputAndLog(KVI_OUT_DCCERROR,__tr2qs_ctx("Accepting RESUME request, transfer will begin at position %1","dcc").arg(filePos));
+ if(m_pDescriptor->bRecvFile)
+ return false; // we're receiving... can't resume anything
- m_pDescriptor->szFileSize.setNum(filePos);
+ bool bFileNameMatches = KviQString::equalCI(filename,m_pDescriptor->szFileName);
+ bool bPortMatches = KviQString::equalCI(port,m_pMarshal->dccPort());
+ if(!bPortMatches)
+ {
+ // port doesn't match
+ if(!bFileNameMatches)
+ return false; // neither filename nor port match
+
+ if(!KVI_OPTION_BOOL(KviOption_boolAcceptMismatchedPortDccResumeRequests))
+ return false;
- KviStr szBuffy;
- KviServerParser::encodeCtcpParameter(filename,szBuffy);
+ // hmm.. try to accept a mismatched port request
- 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;
+ if(_OUTPUT_VERBOSE)
+ outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with mismatched port (%1)","dcc").arg(port));
+ }
+
+ // port matches
+
+ if(!bFileNameMatches)
+ {
+ // bad file name
+ if(!bPortMatches)
+ return false; // neither filename nor port match
+
+ // port matches (this is very likely to be the right transfer)
+
+ if(!KVI_OPTION_BOOL(KviOption_boolAcceptBrokenFileNameDccResumeRequests))
+ {
+ if(_OUTPUT_VERBOSE)
+ outputAndLog(
+ KVI_OUT_DCCMSG,
+ __tr2qs_ctx("Invalid RESUME request: Invalid file name (got '%1' but should be '%2')","dcc")
+ .arg(filename)
+ .arg(m_pDescriptor->szFileName)
+ );
+ return false; // bad file name
}
+
+ if(_OUTPUT_VERBOSE)
+ outputAndLog(KVI_OUT_DCCMSG,__tr2qs_ctx("Processing RESUME request with broken filename (%1)","dcc").arg(filename));
}
- return false;
+
+ bool bOk;
+ quint64 iLocalFileSize = m_pDescriptor->szLocalFileSize.toULongLong(&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;
}
diff --git a/src/modules/options/optw_dcc.cpp b/src/modules/options/optw_dcc.cpp
index c13ed086b..0ada5ad12 100644
--- a/src/modules/options/optw_dcc.cpp
+++ b/src/modules/options/optw_dcc.cpp
@@ -217,11 +217,19 @@ KviDccSendAdvancedOptionsWidget::KviDccSendAdvancedOptionsWidget(QWidget * paren
"the DCC transfer with some buggy IRC clients.<br>" \
"Use it only if your DCC transfers stall just after establishing a connection without sending any data.</center>","options"));
- b = addBoolSelector(g,__tr2qs_ctx("Accept broken RESUME (mIRC file.ext)","options"),KviOption_boolAcceptBrokenFileNameDccResumeRequests);
+ b = addBoolSelector(g,__tr2qs_ctx("Accept RESUME requests with broken filename (mIRC file.ext)","options"),KviOption_boolAcceptBrokenFileNameDccResumeRequests);
mergeTip(b,
__tr2qs_ctx("<center>This option causes KVIrc to accept RESUME requests with invalid filenames.<br>" \
"Use it if KVIrc fails to accept RESUME requests from other clients (e.g. some versions of mIRC).</center>","options"));
+
+ b = addBoolSelector(g,__tr2qs_ctx("Accept RESUME requests with mismatched ports","options"),KviOption_boolAcceptMismatchedPortDccResumeRequests);
+ mergeTip(b,
+ __tr2qs_ctx("<center>This option causes KVIrc to accept RESUME requests with mismatched ports.<br>" \
+ "Use it if some router on the path between you and the receiver remaps the ports in DCC SEND " \
+ "but not in DCC RESUME requests.<br>Please note that this option may misbehave in certain usage " \
+ "patterns since KVIrc must differentiate between transfers only by looking at the filename. Be careful.</center>","options"));
+
b = addBoolSelector(g,__tr2qs_ctx("Replace spaces with underscores in outgoing filenames","options"),KviOption_boolDCCFileTransferReplaceOutgoingSpacesWithUnderscores);
mergeTip(b,
__tr2qs_ctx("<center>This option causes KVIrc to replace spaces with underscores in filenames " \