32 #define KIO_FTP_PRIVATE_INCLUDE
35 #ifdef HAVE_SYS_TIME_H
39 #if TIME_WITH_SYS_TIME
48 #include <QtCore/QCoreApplication>
49 #include <QtCore/QDir>
50 #include <QtNetwork/QHostAddress>
51 #include <QtNetwork/QTcpSocket>
52 #include <QtNetwork/QTcpServer>
53 #include <QtNetwork/QAuthenticator>
68 #define charToLongLong(a) strtoll(a, 0, 10)
70 #define charToLongLong(a) strtol(a, 0, 10)
73 #define FTP_LOGIN "anonymous"
74 #define FTP_PASSWD "anonymous@"
77 #define ENABLE_CAN_RESUME
81 if (path.endsWith(QLatin1String(
";type=A"), Qt::CaseInsensitive) ||
82 path.endsWith(QLatin1String(
";type=I"), Qt::CaseInsensitive) ||
83 path.endsWith(QLatin1String(
";type=D"), Qt::CaseInsensitive)) {
84 return path.left((path.length() - qstrlen(
";type=X")));
92 const int index = path.lastIndexOf(QLatin1String(
";type="));
94 if (index > -1 && (index+6) < path.size()) {
95 const QChar mode = path.at(index+6);
97 if (mode == QLatin1Char(
'A') || mode == QLatin1Char(
'a') ||
98 mode == QLatin1Char(
'I') || mode == QLatin1Char(
'i')) {
99 return mode.toUpper().toLatin1();
108 return (scheme == QLatin1String(
"ftp") || scheme == QLatin1String(
"socks"));
113 return (QNetworkProxy::applicationProxy().type() == QNetworkProxy::Socks5Proxy);
125 maximumIpcSize = 32 * 1024,
130 initialIpcSize = 2 * 1024,
134 minimumMimeSize = 1024
146 int WriteToFile(
int fd,
const char *buf,
size_t len)
150 ssize_t written = write(fd, buf, len);
157 {
case EINTR:
continue;
173 QCoreApplication app(argc, argv);
177 kDebug(7102) <<
"Starting " << getpid();
181 fprintf(stderr,
"Usage: kio_ftp protocol domain-socket1 domain-socket2\n");
185 Ftp slave(argv[2], argv[3]);
186 slave.dispatchLoop();
196 Ftp::Ftp(
const QByteArray &pool,
const QByteArray &app )
200 m_data = m_control = NULL;
202 ftpCloseControlConnection();
206 m_socketProxyAuth = 0;
219 void Ftp::ftpCloseDataConnection()
231 void Ftp::ftpCloseControlConnection()
246 const char* Ftp::ftpResponse(
int iOffset)
248 Q_ASSERT(m_control != NULL);
249 const char *pTxt = m_lastControlLine.data();
263 while (!m_control->canReadLine() && m_control->waitForReadyRead((readTimeout() * 1000))) {}
264 m_lastControlLine = m_control->readLine();
265 pTxt = m_lastControlLine.data();
266 int iCode = atoi(pTxt);
269 kDebug(7102) <<
" > " << pTxt;
272 if (pTxt[3] ==
'-') {
277 kWarning(7102) <<
"Cannot parse valid code from line" << pTxt;
281 kDebug(7102) <<
" > " << pTxt;
282 if (iCode >= 100 && iCode == iMore && pTxt[3] ==
' ') {
287 kDebug(7102) <<
"resp> " << pTxt;
289 m_iRespType = (m_iRespCode > 0) ? m_iRespCode / 100 : 0;
293 while(iOffset-- > 0 && pTxt[0])
301 if(m_control != NULL || m_data != NULL)
302 kDebug(7102) <<
"m_bLoggedOn=" << m_bLoggedOn <<
" m_bBusy=" << m_bBusy;
306 kWarning(7102) <<
"Abandoned data stream";
307 ftpCloseDataConnection();
312 if( !ftpSendCmd(
"quit", 0 ) || (m_iRespType != 2) )
313 kWarning(7102) <<
"QUIT returned error: " << m_iRespCode;
317 ftpCloseDataConnection();
318 ftpCloseControlConnection();
324 kDebug(7102) << _host <<
"port=" << _port <<
"user=" << _user;
328 kDebug(7102) <<
"proxy urls:" << m_proxyUrls;
330 if ( m_host != _host || m_port != _port ||
331 m_user != _user || m_pass != _pass )
342 ftpOpenConnection(loginExplicit);
345 bool Ftp::ftpOpenConnection (LoginMode loginMode)
348 if(loginMode == loginImplicit && m_bLoggedOn)
350 Q_ASSERT(m_control != NULL);
354 kDebug(7102) <<
"host=" << m_host <<
", port=" << m_port <<
", user=" << m_user <<
"password= [password hidden]";
356 infoMessage(
i18n(
"Opening connection to host %1", m_host) );
358 if ( m_host.isEmpty() )
360 error( ERR_UNKNOWN_HOST,
QString() );
364 Q_ASSERT( !m_bLoggedOn );
366 m_initialPath.clear();
367 m_currentPath.clear();
369 if (!ftpOpenControlConnection() )
371 infoMessage(
i18n(
"Connected to host %1", m_host) );
373 bool userNameChanged =
false;
374 if(loginMode != loginDefered)
376 m_bLoggedOn = ftpLogin(&userNameChanged);
381 m_bTextMode =
config()->readEntry(
"textmode",
false);
385 if (userNameChanged && m_bLoggedOn)
393 realURL.setHost( m_host );
394 if ( m_port > 0 && m_port != DEFAULT_FTP_PORT )
395 realURL.setPort( m_port );
396 if ( m_initialPath.isEmpty() )
398 realURL.
setPath( m_initialPath );
399 kDebug(7102) <<
"User name changed! Redirecting to" << realURL.
prettyUrl();
400 redirection( realURL );
414 bool Ftp::ftpOpenControlConnection()
416 if (m_proxyUrls.isEmpty())
417 return ftpOpenControlConnection(m_host, m_port);
422 Q_FOREACH (
const QString& proxyUrl, m_proxyUrls) {
423 const KUrl url (proxyUrl);
424 const QString scheme (url.protocol());
429 errorMessage = url.url();
433 if (scheme == QLatin1String(
"socks")) {
434 kDebug(7102) <<
"Connecting to SOCKS proxy @" << url;
435 const int proxyPort = url.port();
436 QNetworkProxy proxy (QNetworkProxy::Socks5Proxy, url.host(), (proxyPort == -1 ? 0 : proxyPort));
437 QNetworkProxy::setApplicationProxy(proxy);
438 if (ftpOpenControlConnection(m_host, m_port)) {
441 QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
443 if (ftpOpenControlConnection(url.host(), url.port())) {
451 error(errorCode, errorMessage);
457 bool Ftp::ftpOpenControlConnection(
const QString &host,
int port )
467 connect(m_control, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
468 this, SLOT(proxyAuthentication(QNetworkProxy,QAuthenticator*)));
474 const char* psz = ftpResponse(-1);
478 sErrorMsg =
i18n(
"%1.\n\nReason: %2", host, psz);
484 if (m_control->error() == QAbstractSocket::HostNotFoundError)
485 iErrorCode = ERR_UNKNOWN_HOST;
487 sErrorMsg =
QString(
"%1: %2").arg(host).arg(m_control->errorString());
494 error(iErrorCode, sErrorMsg);
505 bool Ftp::ftpLogin(
bool* userChanged)
507 infoMessage(
i18n(
"Sending login information") );
509 Q_ASSERT( !m_bLoggedOn );
520 pass =
config()->readEntry(
"autoLoginPass");
526 info.
url.setHost( m_host );
527 if ( m_port > 0 && m_port != DEFAULT_FTP_PORT )
528 info.
url.setPort( m_port );
535 pass.isEmpty() && checkCachedAuthentication(info))
543 if (user.isEmpty() && pass.isEmpty())
552 bool promptForRetry =
false;
562 if ( failedAuth > 0 || (!user.isEmpty() && pass.isEmpty()) )
565 kDebug(7102) <<
"Prompting user for login info...";
568 if( failedAuth > 0 && promptForRetry)
570 errorMsg =
i18n(
"Message sent:\nLogin using username=%1 and "
571 "password=[hidden]\n\nServer replied:\n%2\n\n"
572 , user, lastServerResponse);
578 info.
prompt =
i18n(
"You need to supply a username and a password "
579 "to access this site.");
585 bool disablePassDlg =
config()->readEntry(
"DisablePassDlg",
false );
586 if ( disablePassDlg || !openPasswordDialog( info, errorMsg ) )
588 error( ERR_USER_CANCELED, m_host );
604 promptForRetry =
true;
609 tempbuf += user.toLatin1();
610 if ( m_proxyURL.isValid() )
613 tempbuf += m_host.toLatin1();
614 if ( m_port > 0 && m_port != DEFAULT_FTP_PORT )
617 tempbuf += QString::number(m_port).toLatin1();
621 kDebug(7102) <<
"Sending Login name: " << tempbuf;
623 bool loggedIn = ( ftpSendCmd(tempbuf) && (m_iRespCode == 230) );
624 bool needPass = (m_iRespCode == 331);
627 if ( !loggedIn && !needPass )
629 lastServerResponse = ftpResponse(0);
630 kDebug(7102) <<
"Login failed: " << lastServerResponse;
638 tempbuf += pass.toLatin1();
639 kDebug(7102) <<
"Sending Login password: " <<
"[protected]";
640 loggedIn = ( ftpSendCmd(tempbuf) && (m_iRespCode == 230) );
647 *userChanged = (!m_user.isEmpty() && (m_user != user));
653 if (!m_user.isEmpty()) {
660 cacheAuthentication(info);
669 lastServerResponse = ftpResponse(0);
670 if (!ftpOpenControlConnection())
675 }
while( ++failedAuth );
678 kDebug(7102) <<
"Login OK";
679 infoMessage(
i18n(
"Login OK") );
683 if( ftpSendCmd(
"SYST") && (m_iRespType == 2) )
685 if( !qstrncmp( ftpResponse(0),
"215 Windows_NT", 14 ) )
687 ftpSendCmd(
"site dirstyle" );
690 if( !qstrncmp( ftpResponse(0),
"200 MSDOS-like directory output is on", 37 ))
692 ftpSendCmd(
"site dirstyle" );
694 m_extControl |= chmodUnknown;
700 if (
config()->readEntry (
"EnableAutoLoginMacro",
false) )
701 ftpAutoLoginMacro ();
704 kDebug(7102) <<
"Searching for pwd";
705 if( !ftpSendCmd(
"PWD") || (m_iRespType != 2) )
707 kDebug(7102) <<
"Couldn't issue pwd command";
708 error( ERR_COULD_NOT_LOGIN,
i18n(
"Could not login to %1.", m_host) );
712 QString sTmp = remoteEncoding()->decode( ftpResponse(3) );
713 int iBeg = sTmp.indexOf(
'"');
714 int iEnd = sTmp.lastIndexOf(
'"');
715 if(iBeg > 0 && iBeg < iEnd)
717 m_initialPath = sTmp.mid(iBeg+1, iEnd-iBeg-1);
718 if(m_initialPath[0] !=
'/') m_initialPath.prepend(
'/');
719 kDebug(7102) <<
"Initial path set to: " << m_initialPath;
720 m_currentPath = m_initialPath;
725 void Ftp::ftpAutoLoginMacro ()
727 QString macro = metaData(
"autoLoginMacro" );
729 if ( macro.isEmpty() )
734 for(QStringList::const_iterator it = list.begin() ; it != list.end() ; ++it )
736 if ( (*it).startsWith(QLatin1String(
"init")) )
738 const QStringList list2 = macro.split(
'\\',QString::SkipEmptyParts);
742 for( ; it != list2.end() ; ++it )
746 if ( (*it).startsWith( QLatin1String(
"cwd") ) )
747 (
void)ftpFolder( (*it).mid(4), false );
765 bool Ftp::ftpSendCmd(
const QByteArray& cmd,
int maxretries )
767 Q_ASSERT(m_control != NULL);
769 if ( cmd.indexOf(
'\r' ) != -1 || cmd.indexOf(
'\n' ) != -1)
771 kWarning(7102) <<
"Invalid command received (contains CR or LF):"
773 error( ERR_UNSUPPORTED_ACTION, m_host );
778 bool isPassCmd = (cmd.left(4).toLower() ==
"pass");
780 kDebug(7102) <<
"send> " << cmd.data();
782 kDebug(7102) <<
"send> pass [protected]";
785 QByteArray buf = cmd;
787 int num = m_control->write(buf);
788 while (m_control->bytesToWrite() && m_control->waitForBytesWritten()) {}
797 m_iRespType = m_iRespCode = 0;
802 if( (m_iRespType <= 0) || (m_iRespCode == 421) )
811 if (maxretries > 0 && !isPassCmd)
814 if( ftpOpenConnection(loginDefered) )
815 ftpSendCmd ( cmd, maxretries - 1 );
822 if ( maxretries < 1 )
826 kDebug(7102) <<
"Was not able to communicate with " << m_host
827 <<
"Attempting to re-establish connection.";
834 if (m_control != NULL)
836 kDebug(7102) <<
"Login failure, aborting";
837 error (ERR_COULD_NOT_LOGIN, m_host);
843 kDebug(7102) <<
"Logged back in, re-issuing command";
849 return ftpSendCmd( cmd, maxretries );
864 int Ftp::ftpOpenPASVDataConnection()
866 Q_ASSERT(m_control != NULL);
867 Q_ASSERT(m_data == NULL);
870 QHostAddress address = m_control->peerAddress();
871 if (address.protocol() != QAbstractSocket::IPv4Protocol)
874 if (m_extControl & pasvUnknown)
880 if( !ftpSendCmd(
"PASV") || (m_iRespType != 2) )
882 kDebug(7102) <<
"PASV attempt failed";
884 if( m_iRespType == 5 )
886 kDebug(7102) <<
"disabling use of PASV";
887 m_extControl |= pasvUnknown;
895 const char *start = strchr(ftpResponse(3),
'(');
897 start = strchr(ftpResponse(3),
'=');
899 ( sscanf(start,
"(%d,%d,%d,%d,%d,%d)",&i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) != 6 &&
900 sscanf(start,
"=%d,%d,%d,%d,%d,%d", &i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) != 6 ) )
902 kError(7102) <<
"parsing IP and port numbers failed. String parsed: " << start;
911 quint16 port = i[4] << 8 | i[5];
915 return m_data->state() == QAbstractSocket::ConnectedState ? 0 :
ERR_INTERNAL;
921 int Ftp::ftpOpenEPSVDataConnection()
923 Q_ASSERT(m_control != NULL);
924 Q_ASSERT(m_data == NULL);
926 QHostAddress address = m_control->peerAddress();
929 if (m_extControl & epsvUnknown)
933 if( !ftpSendCmd(
"EPSV") || (m_iRespType != 2) )
936 if( m_iRespType == 5 )
938 kDebug(7102) <<
"disabling use of EPSV";
939 m_extControl |= epsvUnknown;
944 const char *start = strchr(ftpResponse(3),
'|');
945 if ( !start || sscanf(start,
"|||%d|", &portnum) != 1)
965 int Ftp::ftpOpenDataConnection()
968 Q_ASSERT( m_bLoggedOn );
969 ftpCloseDataConnection();
972 int iErrCodePASV = 0;
977 iErrCode = ftpOpenPASVDataConnection();
980 iErrCodePASV = iErrCode;
981 ftpCloseDataConnection();
985 iErrCode = ftpOpenEPSVDataConnection();
988 ftpCloseDataConnection();
993 if (m_extControl & epsvAllSent)
998 iErrCode = ftpOpenPortDataConnection();
1002 ftpCloseDataConnection();
1004 return iErrCodePASV ? iErrCodePASV : iErrCode;
1013 int Ftp::ftpOpenPortDataConnection()
1015 Q_ASSERT(m_control != NULL);
1016 Q_ASSERT(m_data == NULL);
1019 if (m_extControl & eprtUnknown)
1025 if (!m_server->isListening()) {
1031 m_server->setMaxPendingConnections(1);
1034 QHostAddress localAddress = m_control->localAddress();
1035 if (localAddress.protocol() == QAbstractSocket::IPv4Protocol)
1042 data.ip4 = localAddress.toIPv4Address();
1043 data.port = m_server->serverPort();
1045 unsigned char *pData =
reinterpret_cast<unsigned char*
>(&data);
1046 command.sprintf(
"PORT %d,%d,%d,%d,%d,%d",pData[3],pData[2],pData[1],pData[0],pData[5],pData[4]);
1048 else if (localAddress.protocol() == QAbstractSocket::IPv6Protocol)
1050 command =
QString(
"EPRT |2|%2|%3|").arg(localAddress.toString()).arg(m_server->serverPort());
1053 if( ftpSendCmd(command.toLatin1()) && (m_iRespType == 2) )
1063 bool Ftp::ftpOpenCommand(
const char *_command,
const QString & _path,
char _mode,
1070 errCode = ftpOpenDataConnection();
1074 error(errCode, m_host);
1078 if ( _offset > 0 ) {
1081 sprintf(buf,
"rest %lld", _offset);
1082 if ( !ftpSendCmd( buf ) )
1084 if( m_iRespType != 3 )
1086 error( ERR_CANNOT_RESUME, _path );
1091 QByteArray tmp = _command;
1094 if ( !_path.isEmpty() ) {
1099 if( !ftpSendCmd( tmp ) || (m_iRespType != 1) )
1101 if( _offset > 0 && qstrcmp(_command,
"retr") == 0 && (m_iRespType == 4) )
1104 errormessage = _path;
1110 if ( _offset > 0 && qstrcmp(_command,
"retr") == 0 )
1113 if(m_server && !m_data) {
1114 kDebug(7102) <<
"waiting for connection from remote.";
1115 m_server->waitForNewConnection(connectTimeout() * 1000);
1116 m_data = m_server->nextPendingConnection();
1120 kDebug(7102) <<
"connected with remote.";
1125 kDebug(7102) <<
"no connection received from remote.";
1127 errormessage=m_host;
1131 error(errorcode, errormessage);
1136 bool Ftp::ftpCloseCommand()
1140 ftpCloseDataConnection();
1145 kDebug(7102) <<
"ftpCloseCommand: reading command result";
1148 if(!ftpResponse(-1) || (m_iRespType != 2) )
1150 kDebug(7102) <<
"ftpCloseCommand: no transfer complete message";
1158 if( !ftpOpenConnection(loginImplicit) )
1161 const QByteArray encodedPath (remoteEncoding()->encode(url));
1162 const QString path = QString::fromLatin1(encodedPath.constData(), encodedPath.size());
1164 if( !ftpSendCmd( (QByteArray (
"mkd ") + encodedPath) ) || (m_iRespType != 2) )
1166 QString currentPath( m_currentPath );
1170 if( ftpFolder( path,
false ) )
1174 (void) ftpFolder( currentPath,
false );
1182 if ( permissions != -1 )
1185 (void) ftpChmod( path, permissions );
1193 if( !ftpOpenConnection(loginImplicit) )
1197 if ( ftpRename( src.
path(), dst.
path(), flags ) )
1201 bool Ftp::ftpRename(
const QString & src,
const QString & dst, KIO::JobFlags jobFlags)
1203 Q_ASSERT(m_bLoggedOn);
1207 if (ftpFileExists(dst)) {
1208 error(ERR_FILE_ALREADY_EXIST, dst);
1213 if (ftpFolder(dst,
false)) {
1214 error(ERR_DIR_ALREADY_EXIST, dst);
1219 const int pos = src.lastIndexOf(
'/');
1221 if(!ftpFolder(src.left(pos+1),
false))
1225 QByteArray from_cmd =
"RNFR ";
1226 from_cmd += remoteEncoding()->encode(src.mid(pos+1));
1227 if (!ftpSendCmd(from_cmd) || (m_iRespType != 3)) {
1228 error( ERR_CANNOT_RENAME, src );
1232 QByteArray to_cmd =
"RNTO ";
1233 to_cmd += remoteEncoding()->encode(dst);
1234 if (!ftpSendCmd(to_cmd) || (m_iRespType != 2)) {
1235 error( ERR_CANNOT_RENAME, src );
1244 if( !ftpOpenConnection(loginImplicit) )
1250 ftpFolder(remoteEncoding()->directory(url),
false);
1252 QByteArray cmd = isfile ?
"DELE " :
"RMD ";
1253 cmd += remoteEncoding()->encode(url);
1255 if( !ftpSendCmd( cmd ) || (m_iRespType != 2) )
1261 bool Ftp::ftpChmod(
const QString & path,
int permissions )
1263 Q_ASSERT( m_bLoggedOn );
1265 if(m_extControl & chmodUnknown)
1270 QString cmd = QString::fromLatin1(
"SITE CHMOD ") + QString::number( permissions & 511, 8 ) +
' ';
1273 ftpSendCmd(remoteEncoding()->encode(cmd));
1274 if(m_iRespType == 2)
1277 if(m_iRespCode == 500)
1279 m_extControl |= chmodUnknown;
1280 kDebug(7102) <<
"ftpChmod: CHMOD not supported - disabling";
1287 if( !ftpOpenConnection(loginImplicit) )
1290 if ( !ftpChmod( url.
path(), permissions ) )
1298 Q_ASSERT(entry.
count() == 0);
1305 if ( !ftpEnt.
group.isEmpty() )
1310 if ( !ftpEnt.
link.isEmpty() )
1314 KMimeType::Ptr mime = KMimeType::findByUrl(
KUrl(
"ftp://host/" + filename ) );
1319 if ( mime->name() == KMimeType::defaultMimeType() )
1321 kDebug(7102) <<
"Setting guessed mime type to inode/directory for " << filename;
1333 void Ftp::ftpShortStatAnswer(
const QString& filename,
bool isDir )
1350 void Ftp::ftpStatAnswerNotFound(
const QString & path,
const QString & filename )
1355 QString statSide = metaData(
"statSide");
1356 kDebug(7102) <<
"statSide=" << statSide;
1357 if ( statSide ==
"source" )
1359 kDebug(7102) <<
"Not found, but assuming found, because some servers don't allow listing";
1365 ftpShortStatAnswer( filename,
false );
1370 error( ERR_DOES_NOT_EXIST, path );
1376 if( !ftpOpenConnection(loginImplicit) )
1380 kDebug(7102) <<
"cleaned path=" << path;
1383 if( path.isEmpty() || path ==
"/" )
1400 KUrl tempurl( url );
1405 Q_ASSERT(!filename.isEmpty());
1410 bool isDir = ftpFolder(path,
false);
1413 QString sDetails = metaData(
"details");
1414 int details = sDetails.isEmpty() ? 2 : sDetails.toInt();
1415 kDebug(7102) <<
"details=" << details;
1418 if ( !isDir && !ftpFileExists(path) )
1420 ftpStatAnswerNotFound( path, filename );
1423 ftpShortStatAnswer( filename, isDir );
1451 if( !ftpFolder(parentDir,
true) )
1456 kError(7102) <<
"COULD NOT LIST";
1459 kDebug(7102) <<
"Starting of list was ok";
1461 Q_ASSERT( !search.isEmpty() && search !=
"/" );
1463 bool bFound =
false;
1467 while (ftpReadDir(ftpEnt)) {
1468 if (!ftpEnt.
name.isEmpty() && ftpEnt.
name.at(0).isSpace()) {
1469 ftpValidateEntList.append(ftpEnt);
1476 bFound = maybeEmitStatEntry(ftpEnt, search, filename, isDir);
1481 for (
int i = 0, count = ftpValidateEntList.count(); i < count; ++i) {
1482 FtpEntry& ftpEnt = ftpValidateEntList[i];
1483 fixupEntryName(&ftpEnt);
1484 if (maybeEmitStatEntry(ftpEnt, search, filename, isDir)) {
1493 ftpStatAnswerNotFound( path, filename );
1497 if ( !linkURL.isEmpty() )
1499 if ( linkURL == url || linkURL == tempurl )
1508 kDebug(7102) <<
"stat : finished successfully";
1512 bool Ftp::maybeEmitStatEntry(
FtpEntry& ftpEnt,
const QString& search,
const QString& filename,
bool isDir)
1514 if ((search == ftpEnt.
name || filename == ftpEnt.
name) && !filename.isEmpty()) {
1516 ftpCreateUDSEntry( filename, ftpEnt, entry, isDir );
1527 if( !ftpOpenConnection(loginImplicit) )
1532 if ( path.isEmpty() )
1538 realURL.setHost( m_host );
1540 realURL.setPort( m_port );
1541 if ( m_initialPath.isEmpty() )
1542 m_initialPath =
'/';
1543 realURL.
setPath( m_initialPath );
1545 redirection( realURL );
1550 kDebug(7102) <<
"hunting for path" << path;
1552 if (!ftpOpenDir(path)) {
1553 if (ftpFileExists(path)) {
1566 while( ftpReadDir(ftpEnt) )
1570 if (!ftpEnt.
name.isEmpty()) {
1571 if (ftpEnt.
name.at(0).isSpace()) {
1572 ftpValidateEntList.append(ftpEnt);
1580 ftpCreateUDSEntry( ftpEnt.
name, ftpEnt, entry,
false );
1581 listEntry( entry,
false );
1586 for (
int i = 0, count = ftpValidateEntList.count(); i < count; ++i) {
1587 FtpEntry& ftpEnt = ftpValidateEntList[i];
1588 fixupEntryName(&ftpEnt);
1589 ftpCreateUDSEntry( ftpEnt.
name, ftpEnt, entry,
false );
1590 listEntry( entry,
false );
1594 listEntry( entry,
true );
1601 kDebug(7102) <<
"Got slave_status host = " << (!m_host.toLatin1().isEmpty() ? m_host.toAscii() :
"[None]") <<
" [" << (m_bLoggedOn ?
"Connected" :
"Not connected") <<
"]";
1602 slaveStatus( m_host, m_bLoggedOn );
1605 bool Ftp::ftpOpenDir(
const QString & path )
1614 if( !ftpFolder(tmp,
false) )
1623 if( !ftpOpenCommand(
"list -la",
QString(),
'I', ERR_CANNOT_ENTER_DIRECTORY ) )
1625 if ( !ftpOpenCommand(
"list",
QString(),
'I', ERR_CANNOT_ENTER_DIRECTORY ) )
1627 kWarning(7102) <<
"Can't open for listing";
1631 kDebug(7102) <<
"Starting of list was ok";
1637 Q_ASSERT(m_data != NULL);
1642 while (!m_data->canReadLine() && m_data->waitForReadyRead((readTimeout() * 1000))) {}
1643 QByteArray data = m_data->readLine();
1644 if (data.size() == 0)
1647 const char* buffer = data.data();
1648 kDebug(7102) <<
"dir > " << buffer;
1656 const char *p_access, *p_junk, *p_owner, *p_group, *p_size;
1657 if( (p_access = strtok((
char*)buffer,
" ")) == 0)
continue;
1658 if( (p_junk = strtok(NULL,
" ")) == 0)
continue;
1659 if( (p_owner = strtok(NULL,
" ")) == 0)
continue;
1660 if( (p_group = strtok(NULL,
" ")) == 0)
continue;
1661 if( (p_size = strtok(NULL,
" ")) == 0)
continue;
1666 if ( qstrlen( p_access ) == 1 && p_junk[0] ==
'[' ) {
1667 de.
access = S_IRWXU | S_IRWXG | S_IRWXO;
1670 const char *p_date_1, *p_date_2, *p_date_3, *p_name;
1675 if ( strchr( p_size,
',' ) != 0L )
1678 if ((p_size = strtok(NULL,
" ")) == 0)
1695 p_date_1 = strtok(NULL,
" ");
1699 if ( p_date_1 != 0 &&
1700 (p_date_2 = strtok(NULL,
" ")) != 0 &&
1701 (p_date_3 = strtok(NULL,
" ")) != 0 &&
1702 (p_name = strtok(NULL,
"\r\n")) != 0 )
1705 QByteArray tmp( p_name );
1706 if ( p_access[0] ==
'l' )
1708 int i = tmp.lastIndexOf(
" -> " );
1710 de.
link = remoteEncoding()->decode(p_name + i + 4);
1719 if ( tmp[0] ==
'/' )
1722 if (tmp.indexOf(
'/') != -1)
1725 de.
name = remoteEncoding()->decode(tmp);
1729 switch ( p_access[0] ) {
1750 if ( p_access[1] ==
'r' )
1752 if ( p_access[2] ==
'w' )
1754 if ( p_access[3] ==
'x' || p_access[3] ==
's' )
1756 if ( p_access[4] ==
'r' )
1758 if ( p_access[5] ==
'w' )
1760 if ( p_access[6] ==
'x' || p_access[6] ==
's' )
1762 if ( p_access[7] ==
'r' )
1764 if ( p_access[8] ==
'w' )
1766 if ( p_access[9] ==
'x' || p_access[9] ==
't' )
1768 if ( p_access[3] ==
's' || p_access[3] ==
'S' )
1770 if ( p_access[6] ==
's' || p_access[6] ==
'S' )
1772 if ( p_access[9] ==
't' || p_access[9] ==
'T' )
1775 de.
owner = remoteEncoding()->decode(p_owner);
1776 de.
group = remoteEncoding()->decode(p_group);
1783 time_t currentTime = time( 0L );
1784 struct tm * tmptr = gmtime( ¤tTime );
1785 int currentMonth = tmptr->tm_mon;
1788 tmptr->tm_isdst = -1;
1794 tmptr->tm_mday = atoi( p_date_2 );
1799 static const char *
const s_months[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
1800 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
1801 for (
int c = 0 ; c < 12 ; c ++ )
1802 if ( !qstrcmp( p_date_1, s_months[c]) )
1810 if ( qstrlen( p_date_3 ) == 4 )
1811 tmptr->tm_year = atoi( p_date_3 ) - 1900;
1820 if ( tmptr->tm_mon > currentMonth + 1 )
1825 if ( p_date_3 && ( semicolon = (
char*)strchr( p_date_3,
':' ) ) )
1828 tmptr->tm_min = atoi( semicolon + 1 );
1829 tmptr->tm_hour = atoi( p_date_3 );
1832 kWarning(7102) <<
"Can't parse third field " << p_date_3;
1836 de.
date = mktime( tmptr );
1852 const StatusCode cs = ftpGet(iError, -1, url, 0);
1855 if (cs == statusSuccess) {
1861 error(iError, url.
path());
1865 Ftp::StatusCode Ftp::ftpGet(
int& iError,
int iCopyFile,
const KUrl& url,
KIO::fileoffset_t llOffset)
1868 if( !ftpOpenConnection(loginImplicit) )
1869 return statusServerError;
1876 if ( !ftpSize( url.
path(),
'?' ) && (m_iRespCode == 550) &&
1877 ftpFolder(url.
path(),
false) )
1880 kDebug(7102) <<
"it is a directory in fact";
1882 return statusServerError;
1885 QString resumeOffset = metaData(
"resume");
1886 if ( !resumeOffset.isEmpty() )
1888 llOffset = resumeOffset.toLongLong();
1889 kDebug(7102) <<
"got offset from metadata : " << llOffset;
1894 kWarning(7102) <<
"Can't open for reading";
1895 return statusServerError;
1899 if(m_size == UnknownSize)
1901 const char* psz = strrchr( ftpResponse(4),
'(' );
1903 if (!m_size) m_size = UnknownSize;
1907 if (iCopyFile == -1) {
1908 StatusCode status = ftpSendMimeType(iError, url);
1909 if (status != statusSuccess) {
1915 if ( m_size != UnknownSize ) {
1916 bytesLeft = m_size - llOffset;
1917 totalSize( m_size );
1920 kDebug(7102) <<
"starting with offset=" << llOffset;
1924 char buffer[maximumIpcSize];
1928 int iBlockSize = initialIpcSize;
1931 while(m_size == UnknownSize || bytesLeft > 0)
1933 if(processed_size-llOffset > 1024 * 64)
1934 iBlockSize = maximumIpcSize;
1937 if(iBlockSize+iBufferCur > (
int)
sizeof(buffer))
1938 iBlockSize =
sizeof(buffer) - iBufferCur;
1939 if (m_data->bytesAvailable() == 0)
1940 m_data->waitForReadyRead((readTimeout() * 1000));
1941 int n = m_data->read( buffer+iBufferCur, iBlockSize );
1944 if( m_size == UnknownSize && n == 0 )
1948 return statusServerError;
1950 processed_size += n;
1953 if(m_size != UnknownSize)
1957 if(iBufferCur < minimumMimeSize && bytesLeft > 0)
1959 processedSize( processed_size );
1969 array = QByteArray::fromRawData(buffer, n);
1973 else if( (iError = WriteToFile(iCopyFile, buffer, n)) != 0)
1974 return statusClientError;
1975 processedSize( processed_size );
1982 processedSize( m_size == UnknownSize ? processed_size : m_size );
1983 return statusSuccess;
1989 if( !ftpOpenConnection(loginImplicit) )
1993 kWarning(7102) <<
"Can't open for reading";
1996 char buffer[ 2048 ];
2000 int n = m_data->read( buffer, 2048 );
2001 array.setRawData(buffer, n);
2003 array.resetRawData(buffer, n);
2005 kDebug(7102) <<
"aborting";
2008 kDebug(7102) <<
"finished";
2010 kDebug(7102) <<
"after finished";
2013 void Ftp::ftpAbortTransfer()
2021 msg[0] = (char) 255;
2022 msg[1] = (char) 254;
2023 (void) send(sControl, msg, 2, 0);
2025 msg[0] = (char) 255;
2026 msg[1] = (char) 242;
2027 if (send(sControl, msg, 2, MSG_OOB) != 2)
2031 kDebug(7102) <<
"send ABOR";
2032 QCString buf =
"ABOR\r\n";
2033 if ( KSocks::self()->write( sControl, buf.data(), buf.length() ) <= 0 ) {
2034 error( ERR_COULD_NOT_WRITE,
QString() );
2039 kDebug(7102) <<
"read resp";
2040 if ( readresp() !=
'2' )
2042 error( ERR_COULD_NOT_READ,
QString() );
2046 kDebug(7102) <<
"close sockets";
2060 const StatusCode cs = ftpPut(iError, -1, url, permissions, flags);
2063 if (cs == statusSuccess) {
2069 error(iError, url.
path());
2073 Ftp::StatusCode Ftp::ftpPut(
int& iError,
int iCopyFile,
const KUrl& dest_url,
2074 int permissions, KIO::JobFlags flags)
2076 if( !ftpOpenConnection(loginImplicit) )
2077 return statusServerError;
2082 if (m_user.isEmpty () || m_user ==
FTP_LOGIN)
2083 bMarkPartial =
false;
2085 bMarkPartial =
config()->readEntry(
"MarkPartial",
true);
2088 QString dest_part( dest_orig );
2089 dest_part +=
".part";
2091 if ( ftpSize( dest_orig,
'I' ) )
2095 QByteArray cmd =
"DELE ";
2096 cmd += remoteEncoding()->encode(dest_orig);
2097 if( !ftpSendCmd( cmd ) || (m_iRespType != 2) )
2100 return statusServerError;
2103 else if ( !(flags & KIO::Overwrite) && !(flags &
KIO::Resume) )
2106 return statusServerError;
2108 else if ( bMarkPartial )
2110 if ( !ftpRename( dest_orig, dest_part, KIO::Overwrite ) )
2113 return statusServerError;
2119 else if ( bMarkPartial && ftpSize( dest_part,
'I' ) )
2123 QByteArray cmd =
"DELE ";
2124 cmd += remoteEncoding()->encode(dest_part);
2125 if ( !ftpSendCmd( cmd ) || (m_iRespType != 2) )
2128 return statusServerError;
2131 else if ( !(flags & KIO::Overwrite) && !(flags & KIO::Resume) )
2134 if (!(flags & KIO::Resume))
2137 return statusServerError;
2147 if ( bMarkPartial ) {
2148 kDebug(7102) <<
"Adding .part extension to " << dest_orig;
2156 if( (flags & KIO::Resume) && m_size > 0 )
2161 if( KDE_lseek(iCopyFile, offset, SEEK_SET) < 0 )
2164 return statusClientError;
2169 if (! ftpOpenCommand(
"stor", dest,
'?', ERR_COULD_NOT_WRITE, offset ) )
2170 return statusServerError;
2172 kDebug(7102) <<
"ftpPut: starting with offset=" << offset;
2177 int iBlockSize = initialIpcSize;
2184 result = readData( buffer );
2188 if(processed_size-offset > 1024 * 64)
2189 iBlockSize = maximumIpcSize;
2190 buffer.resize(iBlockSize);
2191 result = ::read(iCopyFile, buffer.data(), buffer.size());
2195 buffer.resize(result);
2200 m_data->write( buffer );
2201 while (m_data->bytesToWrite() && m_data->waitForBytesWritten()) {}
2202 processed_size += result;
2203 processedSize (processed_size);
2206 while ( result > 0 );
2211 kDebug(7102) <<
"Error during 'put'. Aborting.";
2215 if ( ftpSize( dest,
'I' ) &&
2216 ( processed_size <
config()->
readEntry(
"MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE) ) )
2218 QByteArray cmd =
"DELE ";
2219 cmd += remoteEncoding()->encode(dest);
2220 (void) ftpSendCmd( cmd );
2223 return statusServerError;
2226 if ( !ftpCloseCommand() )
2229 return statusServerError;
2235 kDebug(7102) <<
"renaming dest (" << dest <<
") back to dest_orig (" << dest_orig <<
")";
2236 if ( !ftpRename( dest, dest_orig, KIO::Overwrite ) )
2239 return statusServerError;
2244 if ( permissions != -1 )
2247 kDebug(7102) <<
"Trying to chmod over anonymous FTP ???";
2249 if ( ! ftpChmod( dest_orig, permissions ) )
2257 return statusSuccess;
2260 const char* Ftp::ftpSendSizeCmd(
const QString& path)
2264 QString currentPath(m_currentPath);
2265 if (!currentPath.endsWith(QLatin1Char(
'/'))) {
2266 currentPath += QLatin1Char(
'/');
2271 if (path.startsWith(currentPath)) {
2272 buf += remoteEncoding()->encode(path.mid(currentPath.length()));
2274 buf += remoteEncoding()->encode(path);
2277 if (!ftpSendCmd(buf) || m_iRespType != 2) {
2282 return ftpResponse(4);
2288 bool Ftp::ftpSize(
const QString & path,
char mode)
2290 m_size = UnknownSize;
2291 if (!ftpDataMode(mode)) {
2295 const QByteArray psz(ftpSendSizeCmd(path));
2296 if (psz.isEmpty()) {
2301 m_size = psz.trimmed().toLongLong(&ok);
2303 m_size = UnknownSize;
2309 bool Ftp::ftpFileExists(
const QString& path)
2311 return ftpSendSizeCmd(path) != 0;
2321 bool Ftp::ftpDataMode(
char cMode)
2323 if(cMode ==
'?') cMode = m_bTextMode ?
'A' :
'I';
2324 else if(cMode ==
'a') cMode =
'A';
2325 else if(cMode !=
'A') cMode =
'I';
2327 kDebug(7102) <<
"want" << cMode <<
"has" << m_cDataMode;
2328 if(m_cDataMode == cMode)
2331 QByteArray buf =
"TYPE ";
2333 if( !ftpSendCmd(buf) || (m_iRespType != 2) )
2335 m_cDataMode = cMode;
2340 bool Ftp::ftpFolder(
const QString& path,
bool bReportError)
2343 int iLen = newPath.length();
2344 if(iLen > 1 && newPath[iLen-1] ==
'/') newPath.truncate(iLen-1);
2347 if(m_currentPath == newPath)
2350 QByteArray tmp =
"cwd ";
2351 tmp += remoteEncoding()->encode(newPath);
2352 if( !ftpSendCmd(tmp) )
2354 if(m_iRespType != 2)
2357 error(ERR_CANNOT_ENTER_DIRECTORY, path);
2360 m_currentPath = newPath;
2374 StatusCode cs = statusSuccess;
2379 if(bSrcLocal && !bDestLocal)
2382 kDebug(7102) <<
"local file" << sCopyFile <<
"-> ftp" << dest.
path();
2383 cs = ftpCopyPut(iError, iCopyFile, sCopyFile, dest, permissions, flags);
2384 if( cs == statusServerError) sCopyFile = dest.
url();
2386 else if(!bSrcLocal && bDestLocal)
2389 kDebug(7102) <<
"ftp" << src.
path() <<
"-> local file" << sCopyFile;
2390 cs = ftpCopyGet(iError, iCopyFile, sCopyFile, src, permissions, flags);
2391 if( cs == statusServerError ) sCopyFile = src.
url();
2403 error(iError, sCopyFile);
2409 Ftp::StatusCode Ftp::ftpCopyPut(
int& iError,
int& iCopyFile,
const QString &sCopyFile,
2410 const KUrl& url,
int permissions, KIO::JobFlags flags)
2413 KDE_struct_stat buff;
2414 bool bSrcExists = (
KDE::stat( sCopyFile, &buff ) != -1);
2416 {
if(S_ISDIR(buff.st_mode))
2419 return statusClientError;
2425 return statusClientError;
2428 iCopyFile =
KDE::open( sCopyFile, O_RDONLY );
2432 return statusClientError;
2436 totalSize(buff.st_size);
2437 #ifdef ENABLE_CAN_RESUME
2438 return ftpPut(iError, iCopyFile, url, permissions, flags & ~KIO::Resume);
2440 return ftpPut(iError, iCopyFile, url, permissions, flags | KIO::Resume);
2445 Ftp::StatusCode Ftp::ftpCopyGet(
int& iError,
int& iCopyFile,
const QString &sCopyFile,
2446 const KUrl& url,
int permissions, KIO::JobFlags flags)
2449 KDE_struct_stat buff;
2450 const bool bDestExists = (
KDE::stat( sCopyFile, &buff ) != -1);
2452 {
if(S_ISDIR(buff.st_mode))
2455 return statusClientError;
2457 if(!(flags & KIO::Overwrite))
2460 return statusClientError;
2465 const QString sPart = sCopyFile + QLatin1String(
".part");
2466 bool bResume =
false;
2467 const bool bPartExists = (
KDE::stat( sPart, &buff ) != -1);
2468 const bool bMarkPartial =
config()->readEntry(
"MarkPartial",
true);
2469 const QString dest = bMarkPartial ? sPart : sCopyFile;
2470 if (bMarkPartial && bPartExists && buff.st_size > 0)
2472 if(S_ISDIR(buff.st_mode))
2475 return statusClientError;
2478 #ifdef ENABLE_CAN_RESUME
2479 bResume = canResume( buff.st_size );
2485 if (bPartExists && !bResume)
2486 QFile::remove(sPart);
2491 if (permissions != -1)
2492 initialMode = permissions | S_IWUSR;
2500 hCopyOffset = KDE_lseek(iCopyFile, 0, SEEK_END);
2504 return statusClientError;
2506 kDebug(7102) <<
"resuming at " << hCopyOffset;
2509 iCopyFile =
KDE::open(dest, O_CREAT | O_TRUNC | O_WRONLY, initialMode);
2514 kDebug(7102) <<
"### COULD NOT WRITE " << sCopyFile;
2515 iError = (errno == EACCES) ? ERR_WRITE_ACCESS_DENIED
2516 : ERR_CANNOT_OPEN_FOR_WRITING;
2517 return statusClientError;
2521 StatusCode iRes = ftpGet(iError, iCopyFile, url, hCopyOffset);
2522 if( ::
close(iCopyFile) && iRes == statusSuccess )
2525 iRes = statusClientError;
2532 if(iRes == statusSuccess)
2537 if (!bDestExists || !(QFile::remove(sCopyFile) &&
KDE::rename(sPart, sCopyFile) == 0)) {
2538 kDebug(7102) <<
"cannot rename " << sPart <<
" to " << sCopyFile;
2540 iRes = statusClientError;
2546 int size =
config()->readEntry(
"MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
2547 if (buff.st_size < size)
2548 QFile::remove(sPart);
2552 if (iRes == statusSuccess) {
2553 const QString mtimeStr = metaData(
"modified");
2554 if (!mtimeStr.isEmpty()) {
2555 QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate);
2557 kDebug(7102) <<
"Updating modified timestamp to" << mtimeStr;
2558 struct utimbuf utbuf;
2559 utbuf.actime = buff.st_atime;
2560 utbuf.modtime = dt.toTime_t();
2569 Ftp::StatusCode Ftp::ftpSendMimeType(
int& iError,
const KUrl& url)
2573 mimeType(QLatin1String(
"application/x-zerosize"));
2574 return statusSuccess;
2577 const int totalSize = ((m_size == UnknownSize || m_size > 1024) ? 1024 : m_size);
2578 QByteArray buffer(totalSize,
'\0');
2582 if (m_data->bytesAvailable() == 0 && !m_data->waitForReadyRead((readTimeout() * 1000))) {
2584 return statusServerError;
2587 const int bytesRead = m_data->peek(buffer.data(), totalSize);
2590 if (bytesRead == -1) {
2592 return statusServerError;
2597 if (bytesRead == 0 || bytesRead == totalSize || m_size == UnknownSize) {
2602 if (!buffer.isEmpty()) {
2603 KMimeType::Ptr mime = KMimeType::findByNameAndContent(url.
fileName(), buffer);
2604 kDebug(7102) <<
"Emitting mimetype" << mime->name();
2605 mimeType( mime->name() );
2608 return statusSuccess;
2611 void Ftp::proxyAuthentication(
const QNetworkProxy& proxy, QAuthenticator* authenticator)
2614 kDebug(7102) <<
"Authenticator received -- realm:" << authenticator->realm() <<
"user:"
2615 << authenticator->user();
2618 info.
url = m_proxyURL;
2621 info.
username = authenticator->user();
2623 const bool haveCachedCredentials = checkCachedAuthentication(info);
2627 if (!haveCachedCredentials || m_socketProxyAuth) {
2630 connect(m_control, SIGNAL(connected()),
this, SLOT(saveProxyAuthentication()));
2632 info.
prompt =
i18n(
"You need to supply a username and a password for "
2633 "the proxy server listed below before you are allowed "
2634 "to access any sites.");
2638 const bool dataEntered = openPasswordDialog(info,
i18n(
"Proxy Authentication Failed."));
2640 kDebug(7102) <<
"looks like the user canceled proxy authentication.";
2641 error(ERR_USER_CANCELED, m_proxyURL.host());
2645 authenticator->setUser(info.
username);
2646 authenticator->setPassword(info.
password);
2647 authenticator->setOption(QLatin1String(
"keepalive"), info.
keepPassword);
2649 if (m_socketProxyAuth) {
2650 *m_socketProxyAuth = *authenticator;
2652 m_socketProxyAuth =
new QAuthenticator(*authenticator);
2656 m_proxyURL.setPassword(info.
password);
2659 void Ftp::saveProxyAuthentication()
2662 disconnect(m_control, SIGNAL(connected()),
this, SLOT(saveProxyAuthentication()));
2663 Q_ASSERT(m_socketProxyAuth);
2664 if (m_socketProxyAuth) {
2665 kDebug(7102) <<
"-- realm:" << m_socketProxyAuth->realm() <<
"user:" << m_socketProxyAuth->user();
2670 a.
username = m_socketProxyAuth->user();
2671 a.
password = m_socketProxyAuth->password();
2672 a.
keepPassword = m_socketProxyAuth->option(QLatin1String(
"keepalive")).toBool();
2673 cacheAuthentication(a);
2675 delete m_socketProxyAuth;
2676 m_socketProxyAuth = 0;
2679 void Ftp::fixupEntryName(
FtpEntry* e)
2682 if (e->
type == S_IFDIR) {
2683 if (!ftpFolder(e->
name,
false)) {
2685 if (ftpFolder(name,
false)) {
2687 kDebug(7102) <<
"fixing up directory name from" << e->
name <<
"to" <<
name;
2690 while (e->
name.at(index).isSpace()) {
2693 if (ftpFolder(name,
false)) {
2694 kDebug(7102) <<
"fixing up directory name from" << e->
name <<
"to" <<
name;
2702 if (!ftpFileExists(e->
name)) {
2704 if (ftpFileExists(name)) {
2706 kDebug(7102) <<
"fixing up filename from" << e->
name <<
"to" <<
name;
2709 while (e->
name.at(index).isSpace()) {
2712 if (ftpFileExists(name)) {
2713 kDebug(7102) <<
"fixing up filename from" << e->
name <<
"to" <<
name;
QString i18n(const char *text)
static QString ftpCleanPath(const QString &path)
virtual void chmod(const KUrl &url, int permissions)
KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, const KAutostart::StartPhase &aDefault)
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
virtual void mkdir(const KUrl &url, int permissions)
void setExtraField(const QString &fieldName, const QVariant &value)
void insert(uint field, const QString &value)
int stat(const QString &path, KDE_struct_stat *buf)
int rename(const QString &in, const QString &out)
const char * name(StandardAction id)
QVariant getExtraField(const QString &fieldName) const
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QTcpSocket * synchronousConnectToHost(const QString &protocol, const QString &host, quint16 port, int msecs=30000, QObject *parent=0)
virtual void get(const KUrl &url)
QTcpServer * listen(const QString &protocol, const QHostAddress &address=QHostAddress::Any, quint16 port=0, QObject *parent=0)
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
#define charToLongLong(a)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual void mimetype(const KUrl &url)
virtual void del(const KUrl &url, bool isfile)
KSharedConfigPtr config()
void setPath(const QString &path)
void setUser(const QString &user)
int open(const QString &pathname, int flags, mode_t mode)
void setProtocol(const QString &proto)
virtual void listDir(const KUrl &url)
virtual void copy(const KUrl &src, const KUrl &dest, int permissions, KIO::JobFlags flags)
Handles the case that one side of the job is a local file.
void setPass(const QString &pass)
Ftp(const QByteArray &pool, const QByteArray &app)
static char ftpModeFromPath(const QString &path, char defaultMode= '\0')
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
int kdemain(int argc, char **argv)
virtual void slave_status()
virtual void put(const KUrl &url, int permissions, KIO::JobFlags flags)
virtual void stat(const KUrl &url)
void setModified(bool flag)
virtual void rename(const KUrl &src, const KUrl &dst, KIO::JobFlags flags)
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
virtual void setHost(const QString &host, quint16 port, const QString &user, const QString &pass)
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual void closeConnection()
Closes the connection.
static bool supportedProxyScheme(const QString &scheme)
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
virtual void openConnection()
Connects to a ftp server and logs us in m_bLoggedOn is set to true if logging on was successful...
static bool isSocksProxy()
int utime(const QString &filename, struct utimbuf *buf)
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KAction * close(const QObject *recvr, const char *slot, QObject *parent)
QStringList list(const QString &fileClass)