[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: Re: ftp kio: reconnect after timeout
From: Koos Vriezen <koos.vriezen () xs4all ! nl>
Date: 2002-03-28 17:13:20
[Download RAW message or body]
Hi,
Ok my next patch, which calls ftpSendCmd("xxx", 0 ) when logging in,
calling "quit" and when ftpSendCmd("xxx") is called before in the same
function. Otherwise call ftpSendCmd("xxx").
I've tested it with a ftpd that timeout after 60 seconds. It seems to
work.
Can I commit this to HEAD?
On Thu, 28 Mar 2002, Koos Vriezen wrote:
> Oops, maxretries = 1 means one retry, so all ftpSendCmd("xx") should be
> ftpSendCmd("xxx", 0) and ftpSendCmd("xxx", 2) should be ftpSendCmd("xx").
> Will send a new patch tomorrow.
>
> Koos
>
> On Thu, 28 Mar 2002, Koos Vriezen wrote:
>
> > Hi,
> >
> > I've attached a patch for kio_ftp, to fix it's timeout behaviour.
> >
> > First, after a timeout kio_ftp exits with a SIGPIPE.
> > This happens in kio/kio/slavebase.cpp with a PIPE signal
> > void SlaveBase::sigpipe_handler (int)
> > {
> > signal(SIGPIPE,SIG_IGN);
> > // We ignore a SIGPIPE in slaves.
> > // A SIGPIPE can happen in two cases:
> > // 1) Communication error with application.
> > // 2) Communication error with network.
> > kdDebug(7019) << "SIGPIPE" << endl;
> > exit(0);
> > // signal(SIGPIPE,&sigpipe_handler);
> > }
> > Must be a reason for changing ignoring SIGPIPE to exit(0), but we should
> > ignore it when sending a command and a timeout did occur.
> >
> > Next, in kioslave/ftp/ftp.h ftpSendCmd is declared as
> > bool ftpSendCmd( const QCString& cmd, int maxretries = 1 );
> > and all calls leave the default value of maxretries, so a reconnect never
> > happens. I changed some calls with maxretries to 2.
> >
> > Finally, don't exit on timeout when doing a "quit" call.
Regards,
Koos Vriezen
["ftp.patch2" (TEXT/PLAIN)]
--- ftp.cc 2002/03/01 18:56:50 1.162
+++ ftp.cc 2002/03/28 17:02:11
@@ -40,6 +40,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <signal.h>
#if TIME_WITH_SYS_TIME
#include <time.h>
@@ -227,7 +228,7 @@ void Ftp::closeConnection()
if( sControl != 0 )
{
kdDebug(7102) << "Ftp::closeConnection() sending quit" << endl;
- if ( !ftpSendCmd( "quit" ) || rspbuf[0] != '2' )
+ if ( !ftpSendCmd( "quit", 0 ) || rspbuf[0] != '2' )
kdWarning(7102) << "Ftp::closeConnection() 'quit' failed with err="
<< QString(QChar(rspbuf[0]))+QChar(rspbuf[1])+QChar(rspbuf[2]) << endl;
free( nControl );
@@ -487,7 +488,7 @@ bool Ftp::ftpLogin()
}
}
kdDebug(7102) << "Sending Login name: " << user << endl;
- bool loggedIn = (ftpSendCmd( tempbuf ) &&
+ bool loggedIn = (ftpSendCmd( tempbuf, 0 ) &&
!strncmp( rspbuf, "230", 3));
bool needPass = !strncmp( rspbuf, "331", 3);
// Prompt user for login info if we do not
@@ -503,7 +504,7 @@ bool Ftp::ftpLogin()
tempbuf = "pass ";
tempbuf += pass.latin1();
kdDebug(7102) << "Sending Login password: " << "[protected]" << endl;
- loggedIn = (ftpSendCmd( tempbuf ) && !strncmp(rspbuf, "230", 3));
+ loggedIn = (ftpSendCmd( tempbuf, 0 ) && !strncmp(rspbuf, "230", 3));
}
if ( loggedIn )
@@ -521,16 +522,16 @@ bool Ftp::ftpLogin()
// Okay, we're logged in. If this is IIS 4, switch dir listing style to Unix:
// Thanks to jk@soegaard.net (Jens Kristian Søgaard) for this hint
- if( ftpSendCmd( "syst" ) && rspbuf[0] == '2' )
+ if( ftpSendCmd( "syst", 0 ) && rspbuf[0] == '2' )
{
if( !strncmp( rspbuf, "215 Windows_NT version", 22 ) ) // should do for any \
version {
- (void)ftpSendCmd( "site dirstyle" );
+ (void)ftpSendCmd( "site dirstyle", 0 );
// Check if it was already in Unix style
// Patch from Keith Refson <Keith.Refson@earth.ox.ac.uk>
if( !strncmp( rspbuf, "200 MSDOS-like directory output is on", 37 ))
//It was in Unix style already!
- (void)ftpSendCmd( "site dirstyle" );
+ (void)ftpSendCmd( "site dirstyle", 0 );
}
}
@@ -557,7 +558,7 @@ bool Ftp::ftpLogin()
// TODO: Add support for arbitrary commands
// besides simply changing directory!!
if ( (*it).startsWith( "cwd" ) )
- ftpSendCmd( (*it).latin1() );
+ ftpSendCmd( (*it).latin1(), 0 );
}
break;
}
@@ -567,7 +568,7 @@ bool Ftp::ftpLogin()
// Get the current working directory
kdDebug(7102) << "Searching for pwd" << endl;
- if ( !ftpSendCmd( "pwd" ) || rspbuf[0] != '2' )
+ if ( !ftpSendCmd( "pwd", 0 ) || rspbuf[0] != '2' )
{
kdDebug(7102) << "Couldn't issue pwd command" << endl;
error( ERR_COULD_NOT_LOGIN, i18n("Could not login to %1.").arg(m_host) ); // or \
anything better ? @@ -611,8 +612,10 @@ bool Ftp::ftpSendCmd( const QCString& cm
if ( cmd.left(4).lower() != "pass" ) // don't print out the password
kdDebug(7102) << cmd.data() << endl;
-
- if ( KSocks::self()->write( sControl, buf.data(), buf.length() ) <= 0 ) {
+ void (*oldsighandler)(int) = signal(SIGPIPE, SIG_IGN);
+ int num = KSocks::self()->write(sControl, buf.data(), buf.length());
+ signal(SIGPIPE, oldsighandler);
+ if (num <= 0 ) {
error( ERR_COULD_NOT_WRITE, QString::null );
return false;
}
@@ -620,9 +623,9 @@ bool Ftp::ftpSendCmd( const QCString& cm
char rsp = readresp();
if (!rsp || ( rsp == '4' && rspbuf[1] == '2' && rspbuf[2] == '1' ))
{
- kdDebug(7102) << "got 421 -> timeout" << endl;
+ kdDebug(7102) << "got 421 -> timeout " << endl;
// 421 is "421 No Transfer Timeout (300 seconds): closing control connection"
- if ( cmd=="list" && maxretries > 0 ) // Only retry for "list". retr/stor/... \
need to redo the whole thing + if ( maxretries > 0 ) // Only retry for "list". \
retr/stor/... need to redo the whole thing {
// It might mean a timeout occured, let's try logging in again
m_bLoggedOn = false;
@@ -636,7 +639,7 @@ bool Ftp::ftpSendCmd( const QCString& cm
kdDebug(7102) << "Logged back in, reissuing command" << endl;
// On success, try the command again
return ftpSendCmd( cmd, maxretries - 1 );
- } else
+ } else if (cmd != "quit")
{
error( ERR_SERVER_TIMEOUT, m_host );
return false;
@@ -998,7 +1001,7 @@ bool Ftp::ftpOpenCommand( const char *_c
// send rest command if offset > 0, this applies to retr and stor commands
char buf[100];
sprintf(buf, "rest %ld", _offset);
- if ( !ftpSendCmd( buf ) )
+ if ( !ftpSendCmd( buf, 0 ) )
return false;
if ( rspbuf[0] != '3' ) {
error( ERR_CANNOT_RESUME, _path ); // should never happen
@@ -1013,7 +1016,7 @@ bool Ftp::ftpOpenCommand( const char *_c
tmp += _path.ascii();
}
- if ( !ftpSendCmd( tmp ) || rspbuf[0] != '1' ) {
+ if ( !ftpSendCmd( tmp, 0 ) || rspbuf[0] != '1' ) {
if ( _offset > 0 && strcmp(_command, "retr") == 0 && rspbuf[0] == '4')
{
// Failed to resume
@@ -1132,7 +1135,7 @@ bool Ftp::ftpRename( const QString & src
return false;
cmd = "RNTO ";
cmd += dst.ascii();
- return ftpSendCmd( cmd ) && rspbuf[0] == '2';
+ return ftpSendCmd( cmd, 0 ) && rspbuf[0] == '2';
}
void Ftp::del( const KURL& url, bool isfile )
@@ -1164,7 +1167,7 @@ void Ftp::del( const KURL& url, bool isf
QCString cmd = isfile ? "DELE " : "RMD ";
cmd += path.ascii();
- if ( !ftpSendCmd( cmd ) || rspbuf[0] != '2' )
+ if ( !ftpSendCmd( cmd, isfile ? 1 : 0 ) || rspbuf[0] != '2' )
error( ERR_CANNOT_DELETE, path );
else
finished();
@@ -1448,7 +1451,7 @@ void Ftp::stat( const KURL &url)
// Now cwd the parent dir, to prepare for listing
tmp = "cwd ";
tmp += parentDir.latin1();
- if ( !ftpSendCmd( tmp ) )
+ if ( !ftpSendCmd( tmp, 0 ) )
// error already emitted
return;
@@ -2173,7 +2176,7 @@ void Ftp::put( const KURL& dest_url, int
{
QCString cmd = "DELE ";
cmd += dest.ascii();
- (void) ftpSendCmd( cmd );
+ (void) ftpSendCmd( cmd, 0 );
}
}
return;
@@ -2240,7 +2243,7 @@ bool Ftp::ftpSize( const QString & path,
buf="SIZE ";
buf+=path.ascii();
- if ( !ftpSendCmd( buf ) || rspbuf[0] !='2' ) {
+ if ( !ftpSendCmd( buf, 0 ) || rspbuf[0] !='2' ) {
m_size = 0;
return false;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic