26 #include <sys/types.h>
44 #include <kapplication.h>
47 #include <ksimpleconfig.h>
50 #include <kmessagebox.h>
51 #include <kdatastream.h>
52 #include <kmainwindow.h>
57 #include "kmimetype.h"
59 #include "scheduler.h"
60 #include "kdirwatch.h"
61 #include "kmimemagic.h"
62 #include "kprotocolinfo.h"
63 #include "kprotocolmanager.h"
65 #include "kio/observer.h"
67 #include "kssl/ksslcsessioncache.h"
69 #include <kdirnotify_stub.h>
70 #include <ktempfile.h>
71 #include <dcopclient.h>
82 template class TQPtrList<KIO::Job>;
85 #define REPORT_TIMEOUT 200
87 #define KIO_ARGS TQByteArray packedArgs; TQDataStream stream( packedArgs, IO_WriteOnly ); stream
92 JobPrivate() : m_autoErrorHandling( false ), m_autoWarningHandling( true ),
93 m_interactive( true ), m_parentJob( 0L ), m_extraFlags(0),
94 m_processedSize(0), m_userTimestamp(0)
97 bool m_autoErrorHandling;
98 bool m_autoWarningHandling;
100 TQGuardedPtr<TQWidget> m_errorParentWidget;
106 unsigned long m_userTimestamp;
109 Job::Job(
bool showProgressInfo) : TQObject(0,
"job"), m_error(0), m_percent(0)
110 , m_progressId(0), m_speedTimer(0), d( new JobPrivate )
115 if ( showProgressInfo )
118 addMetaData(
"progress-id", TQString::number(m_progressId));
121 connect(
this, TQT_SIGNAL( percent(
KIO::Job*,
unsigned long ) ),
123 connect(
this, TQT_SIGNAL( infoMessage(
KIO::Job*,
const TQString & ) ),
129 connect(
this, TQT_SIGNAL( speed(
KIO::Job*,
unsigned long ) ),
136 updateUserTimestamp( kapp->userTimestamp());
147 int& Job::extraFlags()
149 return d->m_extraFlags;
154 d->m_processedSize = size;
159 return d->m_processedSize;
194 m_incomingMetaData += job->
metaData();
196 if ( subjobs.isEmpty() && emitResultIfLast )
203 unsigned long ipercent = m_percent;
205 if ( totalSize == 0 )
208 m_percent = (
unsigned long)(( (
float)(processedSize) / (
float)(totalSize) ) * 100.0);
210 if ( m_percent != ipercent || m_percent == 100 ) {
211 emit
percent(
this, m_percent );
221 m_speedTimer =
new TQTimer();
222 connect( m_speedTimer, TQT_SIGNAL( timeout() ), TQT_SLOT(
slotSpeedTimeout() ) );
224 emit
speed(
this, bytes_per_second );
225 m_speedTimer->start( 5000 );
233 if ( m_error && d->m_interactive && d->m_autoErrorHandling )
241 kdDebug(7007) <<
"Job::kill this=" <<
this <<
" " << className() <<
" m_progressId=" << m_progressId <<
" quietly=" << quietly << endl;
243 TQPtrListIterator<Job> it( subjobs );
244 for ( ; it.current() ; ++it )
249 m_error = ERR_USER_CANCELED;
263 if ( job->
error() && !m_error )
266 m_error = job->
error();
288 emit
speed(
this, 0 );
289 m_speedTimer->stop();
297 kapp->enableStyles();
299 if ( (m_error != ERR_USER_CANCELED) && (m_error != ERR_NO_CONTENT) ) {
303 KMessageBox::queuedMessageBox( parent, KMessageBox::Error,
errorString() );
307 TQString caption, err, detail;
308 TQStringList::const_iterator it = errors.begin();
309 if ( it != errors.end() )
311 if ( it != errors.end() )
313 if ( it != errors.end() )
315 KMessageBox::queuedDetailedError( parent, err, detail, caption );
321 void Job::setAutoErrorHandlingEnabled(
bool enable, TQWidget *parentWidget )
323 d->m_autoErrorHandling = enable;
324 d->m_errorParentWidget = parentWidget;
329 return d->m_autoErrorHandling;
334 d->m_autoWarningHandling = enable;
339 return d->m_autoWarningHandling;
344 d->m_interactive = enable;
349 return d->m_interactive;
366 if( d->m_userTimestamp == 0 || NET::timestampCompare( time, d->m_userTimestamp ) > 0 )
367 d->m_userTimestamp = time;
371 unsigned long Job::userTimestamp()
const
373 return d->m_userTimestamp;
378 Q_ASSERT(d->m_parentJob == 0L);
380 d->m_parentJob = job;
385 return d->m_parentJob;
390 return m_incomingMetaData;
395 if (!m_incomingMetaData.contains(key))
396 return TQString::null;
397 return m_incomingMetaData[key];
402 m_outgoingMetaData = _metaData;
407 m_outgoingMetaData.insert(key, value);
412 TQMapConstIterator<TQString,TQString> it = values.begin();
413 for(;it != values.end(); ++it)
414 m_outgoingMetaData.insert(it.key(), it.data());
419 TQMapConstIterator<TQString,TQString> it = values.begin();
420 for(;it != values.end(); ++it)
421 m_outgoingMetaData.insert(it.key(), it.data(),
false);
424 MetaData Job::outgoingMetaData()
const
426 return m_outgoingMetaData;
431 bool showProgressInfo )
432 :
Job(showProgressInfo), m_slave(0), m_packedArgs(packedArgs),
433 m_url(url), m_command(command), m_totalSize(0)
435 if (m_url.hasSubURL())
437 KURL::List list = KURL::split(m_url);
438 KURL::List::Iterator it = list.fromLast();
440 m_subUrl = KURL::join(list);
447 if (!m_url.isValid())
449 kdDebug() <<
"ERR_MALFORMED_URL" << endl;
450 m_error = ERR_MALFORMED_URL;
451 m_errorText = m_url.url();
452 TQTimer::singleShot(0,
this, TQT_SLOT(
slotFinished()) );
480 SimpleJob::~SimpleJob()
484 kdDebug(7007) <<
"SimpleJob::~SimpleJob: Killing running job in destructor!" << endl;
494 void SimpleJob::start(
Slave *slave)
498 connect( m_slave, TQT_SIGNAL(
error(
int ,
const TQString & ) ),
499 TQT_SLOT( slotError(
int ,
const TQString & ) ) );
501 connect( m_slave, TQT_SIGNAL(
warning(
const TQString & ) ),
502 TQT_SLOT( slotWarning(
const TQString & ) ) );
504 connect( m_slave, TQT_SIGNAL(
infoMessage(
const TQString & ) ),
507 connect( m_slave, TQT_SIGNAL(
connected() ),
510 connect( m_slave, TQT_SIGNAL( finished() ),
513 if ((extraFlags() & EF_TransferJobDataSent) == 0)
521 connect( m_slave, TQT_SIGNAL(
speed(
unsigned long ) ),
522 TQT_SLOT(
slotSpeed(
unsigned long ) ) );
525 connect( slave, TQT_SIGNAL( needProgressId() ),
526 TQT_SLOT( slotNeedProgressId() ) );
534 addMetaData(
"window-id",
id.setNum((ulong)m_window->winId()));
539 addMetaData(
"user-timestamp",
id.setNum(userTimestamp()));
542 TQString sslSession = KSSLCSessionCache::getSessionForURL(m_url);
543 if ( !sslSession.isNull() )
553 if (!m_outgoingMetaData.isEmpty())
555 KIO_ARGS << m_outgoingMetaData;
556 slave->
send( CMD_META_DATA, packedArgs );
559 if (!m_subUrl.isEmpty())
561 KIO_ARGS << m_subUrl;
562 m_slave->
send( CMD_SUBURL, packedArgs );
565 m_slave->
send( m_command, m_packedArgs );
568 void SimpleJob::slaveDone()
570 if (!m_slave)
return;
581 if (subjobs.isEmpty())
583 if ( !m_error && (m_command == CMD_MKDIR || m_command == CMD_RENAME ) )
585 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*" );
586 if ( m_command == CMD_MKDIR )
588 KURL urlDir(
url() );
589 urlDir.setPath( urlDir.directory() );
590 allDirNotify.FilesAdded( urlDir );
595 TQDataStream str( m_packedArgs, IO_ReadOnly );
597 if ( src.directory() == dst.directory() )
598 allDirNotify.FileRenamed( src, dst );
605 void SimpleJob::slotError(
int error,
const TQString & errorText )
609 if ((m_error == ERR_UNKNOWN_HOST) && m_url.host().isEmpty())
610 m_errorText = TQString::null;
615 void SimpleJob::slotWarning(
const TQString & errorText )
617 TQGuardedPtr<SimpleJob> guard(
this );
620 static uint msgBoxDisplayed = 0;
621 if ( msgBoxDisplayed == 0 )
624 KMessageBox::information( 0L, errorText );
630 if ( !guard.isNull() )
631 emit
warning(
this, errorText );
644 void SimpleJob::slotNeedProgressId()
648 m_slave->setProgressId( m_progressId );
653 if (size > m_totalSize)
665 if ( size > m_totalSize ) {
679 m_incomingMetaData += _metaData;
682 void SimpleJob::storeSSLSessionFromJob(
const KURL &m_redirectionURL) {
685 if ( !sslSession.isNull() ) {
686 const KURL &queryURL = m_redirectionURL.isEmpty()?m_url:m_redirectionURL;
687 KSSLCSessionCache::putSessionForURL(queryURL, sslSession);
693 const TQByteArray &packedArgs,
bool showProgressInfo )
694 :
SimpleJob(url, command, packedArgs, showProgressInfo)
698 void MkdirJob::start(
Slave *slave)
700 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
701 TQT_SLOT( slotRedirection(
const KURL &) ) );
703 SimpleJob::start(slave);
707 void MkdirJob::slotRedirection(
const KURL &url)
709 kdDebug(7007) <<
"MkdirJob::slotRedirection(" << url <<
")" << endl;
710 if (!kapp->authorizeURLAction(
"redirect", m_url, url))
712 kdWarning(7007) <<
"MkdirJob: Redirection from " << m_url <<
" to " << url <<
" REJECTED!" << endl;
713 m_error = ERR_ACCESS_DENIED;
714 m_errorText = url.prettyURL();
717 m_redirectionURL =
url;
718 if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower()))
719 m_redirectionURL.setUser(m_url.user());
724 void MkdirJob::slotFinished()
726 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
736 TQDataStream istream( m_packedArgs, IO_ReadOnly );
737 istream >> dummyUrl >> permissions;
739 m_url = m_redirectionURL;
740 m_redirectionURL = KURL();
741 m_packedArgs.truncate(0);
742 TQDataStream stream( m_packedArgs, IO_WriteOnly );
743 stream << m_url << permissions;
754 KIO_ARGS << url << permissions;
755 return new MkdirJob(url, CMD_MKDIR, packedArgs,
false);
761 KIO_ARGS << url << TQ_INT8(
false);
762 return new SimpleJob(url, CMD_DEL, packedArgs,
false);
768 KIO_ARGS << url << permissions;
769 return new SimpleJob(url, CMD_CHMOD, packedArgs,
false);
775 KIO_ARGS << src << dest << (TQ_INT8) overwrite;
776 return new SimpleJob(src, CMD_RENAME, packedArgs,
false);
782 KIO_ARGS << target << dest << (TQ_INT8) overwrite;
783 return new SimpleJob(dest, CMD_SYMLINK, packedArgs, showProgressInfo);
789 return new SimpleJob(url, CMD_SPECIAL, data, showProgressInfo);
792 SimpleJob *
KIO::mount(
bool ro,
const char *fstype,
const TQString& dev,
const TQString& point,
bool showProgressInfo )
794 KIO_ARGS << int(1) << TQ_INT8( ro ? 1 : 0 )
795 << TQString::fromLatin1(fstype) << dev << point;
797 if ( showProgressInfo )
804 KIO_ARGS << int(2) << point;
806 if ( showProgressInfo )
816 const TQByteArray &packedArgs,
bool showProgressInfo )
817 :
SimpleJob(url, command, packedArgs, showProgressInfo),
818 m_bSource(true), m_details(2)
822 void StatJob::start(
Slave *slave)
824 m_outgoingMetaData.replace(
"statSide", m_bSource ?
"source" :
"dest" );
825 m_outgoingMetaData.replace(
"details", TQString::number(m_details) );
827 connect( slave, TQT_SIGNAL( statEntry(
const KIO::UDSEntry& ) ),
829 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
830 TQT_SLOT( slotRedirection(
const KURL &) ) );
832 SimpleJob::start(slave);
838 m_statResult = entry;
842 void StatJob::slotRedirection(
const KURL &url)
844 kdDebug(7007) <<
"StatJob::slotRedirection(" << url <<
")" << endl;
845 if (!kapp->authorizeURLAction(
"redirect", m_url, url))
847 kdWarning(7007) <<
"StatJob: Redirection from " << m_url <<
" to " << url <<
" REJECTED!" << endl;
848 m_error = ERR_ACCESS_DENIED;
849 m_errorText = url.prettyURL();
852 m_redirectionURL =
url;
853 if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower()))
854 m_redirectionURL.setUser(m_url.user());
859 void StatJob::slotFinished()
861 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
869 m_url = m_redirectionURL;
870 m_redirectionURL = KURL();
871 m_packedArgs.truncate(0);
872 TQDataStream stream( m_packedArgs, IO_WriteOnly );
881 void StatJob::slotMetaData(
const KIO::MetaData &_metaData) {
883 storeSSLSessionFromJob(m_redirectionURL);
889 return stat( url,
true, 2, showProgressInfo );
892 StatJob *
KIO::stat(
const KURL& url,
bool sideIsSource,
short int details,
bool showProgressInfo)
894 kdDebug(7007) <<
"stat " << url << endl;
896 StatJob * job =
new StatJob(url, CMD_STAT, packedArgs, showProgressInfo );
899 if ( showProgressInfo )
906 assert( (url.protocol() ==
"http") || (url.protocol() ==
"https") );
908 KIO_ARGS << (int)2 << url << no_cache << expireDate;
917 const TQByteArray &packedArgs,
918 const TQByteArray &_staticData,
919 bool showProgressInfo)
920 :
SimpleJob(url, command, packedArgs, showProgressInfo), staticData( _staticData)
925 if ( showProgressInfo )
930 void TransferJob::slotData(
const TQByteArray &_data)
932 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
933 emit
data(
this, _data);
937 void TransferJob::slotRedirection(
const KURL &url)
939 kdDebug(7007) <<
"TransferJob::slotRedirection(" << url <<
")" << endl;
940 if (!kapp->authorizeURLAction(
"redirect", m_url, url))
942 kdWarning(7007) <<
"TransferJob: Redirection from " << m_url <<
" to " << url <<
" REJECTED!" << endl;
949 if (m_redirectionList.contains(url) > 5)
951 kdDebug(7007) <<
"TransferJob::slotRedirection: CYCLIC REDIRECTION!" << endl;
952 m_error = ERR_CYCLIC_LINK;
953 m_errorText = m_url.prettyURL();
957 m_redirectionURL =
url;
958 if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower()))
959 m_redirectionURL.setUser(m_url.user());
960 m_redirectionList.append(url);
961 m_outgoingMetaData[
"ssl_was_in_use"] = m_incomingMetaData[
"ssl_in_use"];
967 void TransferJob::slotFinished()
970 if (m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
980 staticData.truncate(0);
981 m_incomingMetaData.clear();
985 m_url = m_redirectionURL;
986 m_redirectionURL = KURL();
990 TQDataStream istream( m_packedArgs, IO_ReadOnly );
991 switch( m_command ) {
993 m_packedArgs.truncate(0);
994 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1000 TQ_INT8 iOverwrite, iResume;
1001 istream >> dummyUrl >> iOverwrite >> iResume >> permissions;
1002 m_packedArgs.truncate(0);
1003 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1004 stream << m_url << iOverwrite << iResume << permissions;
1009 istream >> specialcmd;
1010 if (specialcmd == 1)
1013 m_packedArgs.truncate(0);
1014 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1016 m_command = CMD_GET;
1031 extraFlags() |= EF_TransferJobAsync;
1033 extraFlags() &= ~EF_TransferJobAsync;
1038 if (extraFlags() & EF_TransferJobNeedData)
1040 m_slave->
send( MSG_DATA, dataForSlave );
1041 if (extraFlags() & EF_TransferJobDataSent)
1046 if ( size > m_totalSize ) {
1053 extraFlags() &= ~EF_TransferJobNeedData;
1059 extraFlags() |= EF_TransferJobDataSent;
1061 extraFlags() &= ~EF_TransferJobDataSent;
1066 return (extraFlags() & EF_TransferJobDataSent);
1071 void TransferJob::slotDataReq()
1073 TQByteArray dataForSlave;
1075 extraFlags() |= EF_TransferJobNeedData;
1077 if (!staticData.isEmpty())
1079 dataForSlave = staticData;
1080 staticData = TQByteArray();
1084 emit
dataReq(
this, dataForSlave);
1086 if (extraFlags() & EF_TransferJobAsync)
1090 static const size_t max_size = 14 * 1024 * 1024;
1091 if (dataForSlave.size() > max_size)
1093 kdDebug(7007) <<
"send " << dataForSlave.size() / 1024 / 1024 <<
"MB of data in TransferJob::dataReq. This needs to be splitted, which requires a copy. Fix the application.\n";
1094 staticData.duplicate(dataForSlave.data() + max_size , dataForSlave.size() - max_size);
1095 dataForSlave.truncate(max_size);
1108 void TransferJob::slotMimetype(
const TQString& type )
1124 m_suspended =
false;
1129 void TransferJob::start(
Slave *slave)
1132 connect( slave, TQT_SIGNAL(
data(
const TQByteArray & ) ),
1133 TQT_SLOT( slotData(
const TQByteArray & ) ) );
1135 connect( slave, TQT_SIGNAL(
dataReq() ),
1136 TQT_SLOT( slotDataReq() ) );
1138 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
1139 TQT_SLOT( slotRedirection(
const KURL &) ) );
1141 connect( slave, TQT_SIGNAL(mimeType(
const TQString& ) ),
1142 TQT_SLOT( slotMimetype(
const TQString& ) ) );
1144 connect( slave, TQT_SIGNAL(errorPage() ),
1145 TQT_SLOT( slotErrorPage() ) );
1147 connect( slave, TQT_SIGNAL( needSubURLData() ),
1148 TQT_SLOT( slotNeedSubURLData() ) );
1155 m_mimetype =
"unknown";
1160 SimpleJob::start(slave);
1165 void TransferJob::slotNeedSubURLData()
1168 m_subJob =
KIO::get( m_subUrl,
false,
false);
1170 connect(m_subJob, TQT_SIGNAL(
data(
KIO::Job*,
const TQByteArray &)),
1171 TQT_SLOT( slotSubURLData(
KIO::Job*,
const TQByteArray &)));
1175 void TransferJob::slotSubURLData(
KIO::Job*,
const TQByteArray &data)
1183 void TransferJob::slotMetaData(
const KIO::MetaData &_metaData) {
1185 storeSSLSessionFromJob(m_redirectionURL);
1188 void TransferJob::slotErrorPage()
1195 emit canResume(
this, offset);
1201 assert(job == m_subJob);
1205 m_error = job->
error();
1212 if (job == m_subJob)
1234 PostErrorJob(
int _error,
const TQString& url,
const TQByteArray &packedArgs,
const TQByteArray &postData,
bool showProgressInfo)
1235 :
TransferJob(KURL(), CMD_SPECIAL, packedArgs, postData, showProgressInfo)
1248 static const int bad_ports[] = {
1310 for (
int cnt=0; bad_ports[cnt]; ++cnt)
1311 if (url.port() == bad_ports[cnt])
1313 _error = KIO::ERR_POST_DENIED;
1319 static bool override_loaded =
false;
1320 static TQValueList< int >* overriden_ports = NULL;
1321 if( !override_loaded )
1323 KConfig cfg(
"kio_httprc",
true );
1324 overriden_ports =
new TQValueList< int >;
1325 *overriden_ports = cfg.readIntListEntry(
"OverriddenPorts" );
1326 override_loaded =
true;
1328 for( TQValueList< int >::ConstIterator it = overriden_ports->begin();
1329 it != overriden_ports->end();
1331 if( overriden_ports->contains( url.port()))
1336 if ((url.protocol() !=
"http") && (url.protocol() !=
"https" ))
1337 _error = KIO::ERR_POST_DENIED;
1339 bool redirection =
false;
1341 if (_url.path().isEmpty())
1347 if (!_error && !kapp->authorizeURLAction(
"open", KURL(), _url))
1348 _error = KIO::ERR_ACCESS_DENIED;
1353 KIO_ARGS << (int)1 << url;
1354 TransferJob * job =
new PostErrorJob(_error, url.prettyURL(), packedArgs, postData, showProgressInfo);
1359 KIO_ARGS << (int)1 << _url;
1361 packedArgs, postData, showProgressInfo );
1364 TQTimer::singleShot(0, job, TQT_SLOT(slotPostRedirection()) );
1372 void TransferJob::slotPostRedirection()
1374 kdDebug(7007) <<
"TransferJob::slotPostRedirection(" << m_url <<
")" << endl;
1381 bool overwrite,
bool resume,
bool showProgressInfo )
1383 KIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1391 const TQByteArray &packedArgs,
1392 const TQByteArray &_staticData,
1393 bool showProgressInfo)
1394 :
TransferJob( url, command, packedArgs, _staticData, showProgressInfo ),
1397 connect(
this, TQT_SIGNAL(
data(
KIO::Job *,
const TQByteArray & ) ),
1398 TQT_SLOT( slotStoredData(
KIO::Job *,
const TQByteArray & ) ) );
1400 TQT_SLOT( slotStoredDataReq(
KIO::Job *, TQByteArray & ) ) );
1405 Q_ASSERT( m_data.isNull() );
1406 Q_ASSERT( m_uploadOffset == 0 );
1410 void StoredTransferJob::slotStoredData(
KIO::Job *,
const TQByteArray &data )
1413 if ( data.size() == 0 )
1415 unsigned int oldSize = m_data.size();
1416 m_data.resize( oldSize + data.size(), TQGArray::SpeedOptim );
1417 memcpy( m_data.data() + oldSize, data.data(), data.size() );
1420 void StoredTransferJob::slotStoredDataReq(
KIO::Job *, TQByteArray &data )
1424 const int MAX_CHUNK_SIZE = 64*1024;
1425 int remainingBytes = m_data.size() - m_uploadOffset;
1426 if( remainingBytes > MAX_CHUNK_SIZE ) {
1428 data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
1429 m_uploadOffset += MAX_CHUNK_SIZE;
1434 data.duplicate( m_data.data() + m_uploadOffset, remainingBytes );
1435 m_data = TQByteArray();
1452 bool overwrite,
bool resume,
bool showProgressInfo )
1454 KIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1463 const TQByteArray &packedArgs,
bool showProgressInfo )
1464 :
TransferJob(url, command, packedArgs, TQByteArray(), showProgressInfo)
1468 void MimetypeJob::start(
Slave *slave)
1470 TransferJob::start(slave);
1474 void MimetypeJob::slotFinished( )
1477 if ( m_error == KIO::ERR_IS_DIRECTORY )
1482 kdDebug(7007) <<
"It is in fact a directory!" << endl;
1483 m_mimetype = TQString::fromLatin1(
"inode/directory");
1487 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error )
1490 TransferJob::slotFinished();
1495 staticData.truncate(0);
1496 m_suspended =
false;
1497 m_url = m_redirectionURL;
1498 m_redirectionURL = KURL();
1499 m_packedArgs.truncate(0);
1500 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1513 if ( showProgressInfo )
1520 DirectCopyJob::DirectCopyJob(
const KURL& url,
int command,
1521 const TQByteArray &packedArgs,
bool showProgressInfo )
1522 :
SimpleJob(url, command, packedArgs, showProgressInfo)
1526 void DirectCopyJob::start(
Slave* slave )
1530 SimpleJob::start(slave);
1535 emit canResume(
this, offset);
1541 class FileCopyJob::FileCopyJobPrivate
1545 time_t m_modificationTime;
1556 FileCopyJob::FileCopyJob(
const KURL& src,
const KURL& dest,
int permissions,
1557 bool move,
bool overwrite,
bool resume,
bool showProgressInfo)
1558 :
Job(showProgressInfo), m_src(src), m_dest(dest),
1559 m_permissions(permissions), m_move(move), m_overwrite(overwrite), m_resume(resume),
1562 if (showProgressInfo && !move)
1564 else if (showProgressInfo && move)
1572 d =
new FileCopyJobPrivate;
1575 d->m_modificationTime =
static_cast<time_t
>( -1 );
1576 TQTimer::singleShot(0,
this, TQT_SLOT(slotStart()));
1579 void FileCopyJob::slotStart()
1584 if ((m_src.protocol() == m_dest.protocol()) &&
1585 (m_src.host() == m_dest.host()) &&
1586 (m_src.port() == m_dest.port()) &&
1587 (m_src.user() == m_dest.user()) &&
1588 (m_src.pass() == m_dest.pass()) &&
1589 !m_src.hasSubURL() && !m_dest.hasSubURL())
1591 startRenameJob(m_src);
1594 else if (m_src.isLocalFile() && KProtocolInfo::canRenameFromFile(m_dest))
1596 startRenameJob(m_dest);
1601 startRenameJob(m_src);
1606 startBestCopyMethod();
1609 void FileCopyJob::startBestCopyMethod()
1611 if ((m_src.protocol() == m_dest.protocol()) &&
1612 (m_src.host() == m_dest.host()) &&
1613 (m_src.port() == m_dest.port()) &&
1614 (m_src.user() == m_dest.user()) &&
1615 (m_src.pass() == m_dest.pass()) &&
1616 !m_src.hasSubURL() && !m_dest.hasSubURL())
1622 startCopyJob(m_dest);
1626 startCopyJob(m_src);
1634 FileCopyJob::~FileCopyJob()
1641 d->m_sourceSize = size;
1642 if (size != (off_t) -1)
1648 d->m_sourceSize = size;
1655 d->m_modificationTime = mtime;
1658 void FileCopyJob::startCopyJob()
1660 startCopyJob(m_src);
1663 void FileCopyJob::startCopyJob(
const KURL &slave_url)
1666 KIO_ARGS << m_src << m_dest << m_permissions << (TQ_INT8) m_overwrite;
1667 m_copyJob =
new DirectCopyJob(slave_url, CMD_COPY, packedArgs,
false);
1669 connectSubjob( m_copyJob );
1674 void FileCopyJob::startRenameJob(
const KURL &slave_url)
1676 KIO_ARGS << m_src << m_dest << (TQ_INT8) m_overwrite;
1677 m_moveJob =
new SimpleJob(slave_url, CMD_RENAME, packedArgs,
false);
1679 connectSubjob( m_moveJob );
1682 void FileCopyJob::connectSubjob(
SimpleJob * job )
1699 if ( size > m_totalSize ) {
1707 if (size > m_totalSize)
1716 if ( pct > m_percent )
1719 emit
percent(
this, m_percent );
1723 void FileCopyJob::startDataPump()
1727 m_canResume =
false;
1728 m_resumeAnswerSent =
false;
1730 m_putJob =
put( m_dest, m_permissions, m_overwrite, m_resume,
false );
1731 if ( d->m_modificationTime != static_cast<time_t>( -1 ) ) {
1732 TQDateTime dt; dt.setTime_t( d->m_modificationTime );
1733 m_putJob->
addMetaData(
"modified", dt.toString( Qt::ISODate ) );
1741 connect( m_putJob, TQT_SIGNAL(dataReq(
KIO::Job *, TQByteArray&)),
1742 TQT_SLOT( slotDataReq(
KIO::Job *, TQByteArray&)));
1748 if ( job == m_putJob || job == m_copyJob )
1761 job, i18n(
"File Already Exists"),
1764 (RenameDlg_Mode) (M_OVERWRITE | M_RESUME | M_NORENAME), newPath,
1765 d->m_sourceSize, offset );
1768 if ( res == R_OVERWRITE || m_overwrite )
1770 else if ( res == R_CANCEL )
1772 if ( job == m_putJob )
1773 m_putJob->
kill(
true);
1775 m_copyJob->kill(
true);
1776 m_error = ERR_USER_CANCELED;
1782 m_resumeAnswerSent =
true;
1784 if ( job == m_putJob )
1786 m_getJob =
get( m_src,
false,
false );
1789 m_getJob->
addMetaData(
"AllowCompressedPage",
"false" );
1804 m_putJob->slave()->setOffset( offset );
1808 connectSubjob( m_getJob );
1811 connect( m_getJob, TQT_SIGNAL(data(
KIO::Job*,
const TQByteArray&)),
1812 TQT_SLOT( slotData(
KIO::Job*,
const TQByteArray&)) );
1814 TQT_SLOT(slotMimetype(
KIO::Job*,
const TQString&)) );
1818 m_copyJob->slave()->sendResumeAnswer( offset != 0 );
1821 else if ( job == m_getJob )
1827 m_getJob->slave()->setOffset( m_putJob->slave()->offset() );
1830 kdWarning(7007) <<
"FileCopyJob::slotCanResume from unknown job=" << job
1831 <<
" m_getJob=" << m_getJob <<
" m_putJob=" << m_putJob << endl;
1834 void FileCopyJob::slotData(
KIO::Job * ,
const TQByteArray &data)
1839 if (!m_putJob)
return;
1846 if (!m_resumeAnswerSent)
1848 m_resumeAnswerSent =
true;
1854 void FileCopyJob::slotDataReq(
KIO::Job * , TQByteArray &data)
1857 if (!m_resumeAnswerSent && !m_getJob)
1860 m_error = ERR_INTERNAL;
1861 m_errorText =
"'Put' job didn't send canResume or 'Get' job didn't send data!";
1862 m_putJob->
kill(
true);
1872 m_buffer = TQByteArray();
1875 void FileCopyJob::slotMimetype(
KIO::Job*,
const TQString& type )
1886 if ((job == m_moveJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1889 startBestCopyMethod();
1893 else if ((job == m_copyJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1900 else if (job == m_getJob)
1904 m_putJob->
kill(
true);
1906 else if (job == m_putJob)
1910 m_getJob->
kill(
true);
1912 m_error = job->
error();
1918 if (job == m_moveJob)
1923 if (job == m_copyJob)
1933 if (job == m_getJob)
1940 if (job == m_putJob)
1946 kdWarning(7007) <<
"WARNING ! Get still going on..." << endl;
1956 if (job == d->m_delJob)
1964 bool overwrite,
bool resume,
bool showProgressInfo)
1966 return new FileCopyJob( src, dest, permissions,
false, overwrite, resume, showProgressInfo );
1970 bool overwrite,
bool resume,
bool showProgressInfo)
1972 return new FileCopyJob( src, dest, permissions,
true, overwrite, resume, showProgressInfo );
1977 KIO_ARGS << src << TQ_INT8(
true);
1978 return new SimpleJob(src, CMD_DEL, packedArgs, showProgressInfo );
1984 ListJob::ListJob(
const KURL& u,
bool showProgressInfo,
bool _recursive, TQString _prefix,
bool _includeHidden) :
1985 SimpleJob(u, CMD_LISTDIR, TQByteArray(), showProgressInfo),
1986 recursive(_recursive), includeHidden(_includeHidden), prefix(_prefix), m_processedEntries(0)
1990 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1994 void ListJob::slotListEntries(
const KIO::UDSEntryList& list )
1997 m_processedEntries += list.count();
2001 UDSEntryListConstIterator it = list.begin();
2002 UDSEntryListConstIterator end = list.end();
2004 for (; it != end; ++it) {
2006 bool isLink =
false;
2009 UDSEntry::ConstIterator it2 = (*it).begin();
2010 UDSEntry::ConstIterator end2 = (*it).end();
2011 for( ; it2 != end2; it2++ ) {
2012 switch( (*it2).m_uds ) {
2014 isDir = S_ISDIR((*it2).m_long);
2017 if( itemURL.isEmpty() ) {
2019 itemURL.addPath( (*it2).m_str );
2023 itemURL = (*it2).m_str;
2027 isLink = !(*it2).m_str.isEmpty();
2033 if (isDir && !isLink) {
2034 const TQString filename = itemURL.fileName();
2036 if (filename !=
".." && filename !=
"." && (includeHidden || filename[0] !=
'.')) {
2040 prefix + filename +
"/",
2044 const KIO::UDSEntryList& )),
2046 const KIO::UDSEntryList& )));
2056 if (prefix.isNull() && includeHidden) {
2060 UDSEntryList newlist;
2062 UDSEntryListConstIterator it = list.begin();
2063 UDSEntryListConstIterator end = list.end();
2064 for (; it != end; ++it) {
2067 UDSEntry::Iterator it2 = newone.begin();
2069 for( ; it2 != newone.end(); it2++ ) {
2071 filename = (*it2).m_str;
2072 (*it2).m_str = prefix + filename;
2077 if ( (prefix.isNull() || (filename !=
".." && filename !=
".") )
2078 && (includeHidden || (filename[0] !=
'.') ) )
2079 newlist.append(newone);
2086 void ListJob::gotEntries(
KIO::Job *,
const KIO::UDSEntryList& list )
2092 void ListJob::slotResult(
KIO::Job * job )
2099 void ListJob::slotRedirection(
const KURL & url )
2101 if (!kapp->authorizeURLAction(
"redirect", m_url, url))
2103 kdWarning(7007) <<
"ListJob: Redirection from " << m_url <<
" to " << url <<
" REJECTED!" << endl;
2106 m_redirectionURL =
url;
2107 if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower()))
2108 m_redirectionURL.setUser(m_url.user());
2112 void ListJob::slotFinished()
2115 if ( m_error == KIO::ERR_IS_FILE && m_url.isLocalFile() ) {
2118 TQString proto = ptr->property(
"X-KDE-LocalProtocol").toString();
2120 m_redirectionURL = m_url;
2121 m_redirectionURL.setProtocol( proto );
2127 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) {
2135 m_url = m_redirectionURL;
2136 m_redirectionURL = KURL();
2137 m_packedArgs.truncate(0);
2138 TQDataStream stream( m_packedArgs, IO_WriteOnly );
2147 void ListJob::slotMetaData(
const KIO::MetaData &_metaData) {
2149 storeSSLSessionFromJob(m_redirectionURL);
2154 ListJob * job =
new ListJob(url, showProgressInfo,
false,TQString::null,includeHidden);
2160 ListJob * job =
new ListJob(url, showProgressInfo,
true,TQString::null,includeHidden);
2167 extraFlags() |= EF_ListJobUnrestricted;
2169 extraFlags() &= ~EF_ListJobUnrestricted;
2172 void ListJob::start(
Slave *slave)
2174 if (kapp && !kapp->authorizeURLAction(
"list", m_url, m_url) && !(extraFlags() & EF_ListJobUnrestricted))
2176 m_error = ERR_ACCESS_DENIED;
2177 m_errorText = m_url.url();
2178 TQTimer::singleShot(0,
this, TQT_SLOT(slotFinished()) );
2181 connect( slave, TQT_SIGNAL( listEntries(
const KIO::UDSEntryList& )),
2182 TQT_SLOT( slotListEntries(
const KIO::UDSEntryList& )));
2185 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
2186 TQT_SLOT( slotRedirection(
const KURL &) ) );
2188 SimpleJob::start(slave);
2191 class CopyJob::CopyJobPrivate
2195 m_defaultPermissions =
false;
2196 m_bURLDirty =
false;
2204 CopyJob::DestinationState m_globalDestinationState;
2206 bool m_defaultPermissions;
2211 TQValueList<CopyInfo> m_directoriesCopied;
2215 :
Job(showProgressInfo), m_mode(mode), m_asMethod(asMethod),
2216 destinationState(DEST_NOT_STATED), state(STATE_STATING),
2217 m_totalSize(0), m_processedSize(0), m_fileProcessedSize(0),
2218 m_processedFiles(0), m_processedDirs(0),
2219 m_srcList(src), m_currentStatSrc(m_srcList.begin()),
2220 m_bCurrentOperationIsLink(false), m_bSingleFileCopy(false), m_bOnlyRenames(mode==Move),
2221 m_dest(dest), m_bAutoSkip( false ), m_bOverwriteAll( false ),
2222 m_conflictError(0), m_reportTimer(0)
2224 d =
new CopyJobPrivate;
2225 d->m_globalDest = dest;
2226 d->m_globalDestinationState = destinationState;
2228 if ( showProgressInfo ) {
2235 TQTimer::singleShot(0,
this, TQT_SLOT(
slotStart()));
2264 m_reportTimer =
new TQTimer(
this);
2266 connect(m_reportTimer,TQT_SIGNAL(timeout()),
this,TQT_SLOT(slotReport()));
2267 m_reportTimer->start(REPORT_TIMEOUT,
false);
2276 KIO_EXPORT
bool kio_resolve_local_urls =
true;
2278 void CopyJob::slotResultStating(
Job *job )
2282 if (job->
error() && destinationState != DEST_NOT_STATED )
2285 if ( !srcurl.isLocalFile() )
2290 kdDebug(7007) <<
"Error while stating source. Activating hack" << endl;
2291 subjobs.remove( job );
2292 assert ( subjobs.isEmpty() );
2293 struct CopyInfo info;
2294 info.permissions = (mode_t) -1;
2295 info.mtime = (time_t) -1;
2296 info.ctime = (time_t) -1;
2298 info.uSource = srcurl;
2299 info.uDest = m_dest;
2301 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2302 info.uDest.addPath( srcurl.fileName() );
2304 files.append( info );
2318 TQString sLocalPath;
2319 UDSEntry::ConstIterator it2 = entry.begin();
2320 for( ; it2 != entry.end(); it2++ ) {
2322 bDir = S_ISDIR( (mode_t)(*it2).m_long );
2324 bLink = !((*it2).m_str.isEmpty());
2325 else if ( ((*it2).m_uds) ==
UDS_NAME )
2326 sName = (*it2).m_str;
2328 sLocalPath = (*it2).m_str;
2331 if ( destinationState == DEST_NOT_STATED )
2335 destinationState = DEST_DOESNT_EXIST;
2338 destinationState = bDir ? DEST_IS_DIR : DEST_IS_FILE;
2341 const bool isGlobalDest = m_dest == d->m_globalDest;
2343 d->m_globalDestinationState = destinationState;
2345 if ( !sLocalPath.isEmpty() && kio_resolve_local_urls ) {
2347 m_dest.setPath(sLocalPath);
2349 d->m_globalDest = m_dest;
2352 subjobs.remove( job );
2353 assert ( subjobs.isEmpty() );
2360 m_currentDest = m_dest;
2377 m_bCurrentSrcIsDir =
false;
2378 slotEntries(job, lst);
2381 if (!sLocalPath.isEmpty())
2382 srcurl.setPath(sLocalPath);
2386 subjobs.remove( job );
2387 assert ( subjobs.isEmpty() );
2395 m_bCurrentSrcIsDir =
true;
2396 if ( destinationState == DEST_IS_DIR )
2401 TQString directory = srcurl.fileName();
2406 m_currentDest.addPath( directory );
2409 else if ( destinationState == DEST_IS_FILE )
2411 m_error = ERR_IS_FILE;
2412 m_errorText = m_dest.prettyURL();
2422 destinationState = DEST_IS_DIR;
2423 if ( m_dest == d->m_globalDest )
2424 d->m_globalDestinationState = destinationState;
2427 startListing( srcurl );
2436 void CopyJob::slotReport()
2441 case STATE_COPYING_FILES:
2443 if (observer) observer->slotProcessedFiles(
this, m_processedFiles);
2447 d->m_bURLDirty =
false;
2450 if (observer) observer->slotMoving(
this, m_currentSrcURL, m_currentDestURL);
2451 emit
moving(
this, m_currentSrcURL, m_currentDestURL);
2453 else if (m_mode==Link)
2455 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2456 emit
linking(
this, m_currentSrcURL.path(), m_currentDestURL );
2460 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2461 emit
copying(
this, m_currentSrcURL, m_currentDestURL );
2466 case STATE_CREATING_DIRS:
2467 if (observer) observer->slotProcessedDirs(
this, m_processedDirs );
2471 d->m_bURLDirty =
false;
2473 if (observer) observer->slotCreatingDir(
this, m_currentDestURL);
2481 d->m_bURLDirty =
false;
2482 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2494 void CopyJob::slotEntries(
KIO::Job* job,
const UDSEntryList& list)
2496 UDSEntryListConstIterator it = list.begin();
2497 UDSEntryListConstIterator end = list.end();
2498 for (; it != end; ++it) {
2499 UDSEntry::ConstIterator it2 = (*it).begin();
2500 struct CopyInfo info;
2501 info.permissions = -1;
2502 info.mtime = (time_t) -1;
2503 info.ctime = (time_t) -1;
2505 TQString displayName;
2509 for( ; it2 != (*it).end(); it2++ ) {
2510 switch ((*it2).m_uds) {
2513 isDir = S_ISDIR( (mode_t)((*it2).m_long) );
2516 displayName = (*it2).m_str;
2519 url = KURL((*it2).m_str);
2522 localPath = (*it2).m_str;
2525 info.linkDest = (*it2).m_str;
2528 info.permissions = ((*it2).m_long);
2532 m_totalSize += info.size;
2535 info.mtime = (time_t)((*it2).m_long);
2538 info.ctime = (time_t)((*it2).m_long);
2543 if (displayName !=
".." && displayName !=
".")
2545 bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
2546 if( !hasCustomURL ) {
2549 if ( m_bCurrentSrcIsDir ) {
2551 url.addPath( displayName );
2555 if (!localPath.isEmpty() && kio_resolve_local_urls) {
2557 url.setPath(localPath);
2561 info.uDest = m_currentDest;
2564 if ( destinationState == DEST_IS_DIR &&
2567 ( ! ( m_asMethod && state == STATE_STATING ) ) )
2569 TQString destFileName;
2570 if ( hasCustomURL &&
2571 KProtocolInfo::fileNameUsedForCopying( url ) == KProtocolInfo::FromURL ) {
2574 int numberOfSlashes = displayName.contains(
'/' );
2575 TQString path = url.path();
2577 for (
int n = 0; n < numberOfSlashes + 1; ++n ) {
2578 pos = path.findRev(
'/', pos - 1 );
2580 kdWarning(7007) <<
"kioslave bug: not enough slashes in UDS_URL " << path <<
" - looking for " << numberOfSlashes <<
" slashes" << endl;
2585 destFileName = path.mid( pos + 1 );
2589 destFileName = displayName;
2595 if ( destFileName.isEmpty() )
2599 info.uDest.addPath( destFileName );
2603 if ( info.linkDest.isEmpty() && isDir && m_mode != Link )
2605 dirs.append( info );
2607 dirsToRemove.append( info.uSource );
2610 files.append( info );
2616 void CopyJob::skipSrc()
2618 m_dest = d->m_globalDest;
2619 destinationState = d->m_globalDestinationState;
2621 skip( m_currentSrcURL );
2625 void CopyJob::statNextSrc()
2631 m_dest = d->m_globalDest;
2632 destinationState = d->m_globalDestinationState;
2637 void CopyJob::statCurrentSrc()
2639 if ( m_currentStatSrc != m_srcList.end() )
2641 m_currentSrcURL = (*m_currentStatSrc);
2642 d->m_bURLDirty =
true;
2643 if ( m_mode == Link )
2646 m_currentDest = m_dest;
2647 struct CopyInfo info;
2648 info.permissions = -1;
2649 info.mtime = (time_t) -1;
2650 info.ctime = (time_t) -1;
2652 info.uSource = m_currentSrcURL;
2653 info.uDest = m_currentDest;
2655 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2658 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
2659 (m_currentSrcURL.host() == info.uDest.host()) &&
2660 (m_currentSrcURL.port() == info.uDest.port()) &&
2661 (m_currentSrcURL.user() == info.uDest.user()) &&
2662 (m_currentSrcURL.pass() == info.uDest.pass()) )
2665 info.uDest.addPath( m_currentSrcURL.fileName() );
2675 files.append( info );
2679 else if ( m_mode == Move && (
2681 KProtocolInfo::fileNameUsedForCopying( m_currentSrcURL ) == KProtocolInfo::FromURL ||
2682 destinationState != DEST_IS_DIR || m_asMethod )
2687 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
2688 (m_currentSrcURL.host() == m_dest.host()) &&
2689 (m_currentSrcURL.port() == m_dest.port()) &&
2690 (m_currentSrcURL.user() == m_dest.user()) &&
2691 (m_currentSrcURL.pass() == m_dest.pass()) )
2693 startRenameJob( m_currentSrcURL );
2698 startRenameJob( m_dest );
2703 startRenameJob( m_currentSrcURL );
2710 TQGuardedPtr<CopyJob> that =
this;
2712 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentSrcURL.prettyURL()));
2719 Job * job =
KIO::stat( m_currentSrcURL,
true, 2,
false );
2721 state = STATE_STATING;
2723 m_currentDestURL=m_dest;
2724 m_bOnlyRenames =
false;
2725 d->m_bURLDirty =
true;
2731 state = STATE_STATING;
2732 d->m_bURLDirty =
true;
2734 if (!dirs.isEmpty())
2736 if (!files.isEmpty())
2739 m_bSingleFileCopy = ( files.count() == 1 && dirs.isEmpty() );
2741 state = STATE_CREATING_DIRS;
2746 void CopyJob::startRenameJob(
const KURL& slave_url )
2750 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2751 dest.addPath( m_currentSrcURL.fileName() );
2752 kdDebug(7007) <<
"This seems to be a suitable case for trying to rename before stat+[list+]copy+del" << endl;
2753 state = STATE_RENAMING;
2755 struct CopyInfo info;
2756 info.permissions = -1;
2757 info.mtime = (time_t) -1;
2758 info.ctime = (time_t) -1;
2760 info.uSource = m_currentSrcURL;
2762 TQValueList<CopyInfo> files;
2766 KIO_ARGS << m_currentSrcURL << dest << (TQ_INT8)
false ;
2770 if ( m_currentSrcURL.directory() != dest.directory() )
2771 m_bOnlyRenames =
false;
2774 void CopyJob::startListing(
const KURL & src )
2776 state = STATE_LISTING;
2777 d->m_bURLDirty =
true;
2780 connect(newjob, TQT_SIGNAL(entries(
KIO::Job *,
2781 const KIO::UDSEntryList& )),
2783 const KIO::UDSEntryList& )));
2787 void CopyJob::skip(
const KURL & sourceUrl )
2792 KURL::List::Iterator sit = m_srcList.find( sourceUrl );
2793 if ( sit != m_srcList.end() )
2796 m_srcList.remove( sit );
2798 dirsToRemove.remove( sourceUrl );
2801 bool CopyJob::shouldOverwrite(
const TQString& path )
const
2803 if ( m_bOverwriteAll )
2805 TQStringList::ConstIterator sit = m_overwriteList.begin();
2806 for( ; sit != m_overwriteList.end(); ++sit )
2807 if ( path.startsWith( *sit ) )
2812 bool CopyJob::shouldSkip(
const TQString& path )
const
2814 TQStringList::ConstIterator sit = m_skipList.begin();
2815 for( ; sit != m_skipList.end(); ++sit )
2816 if ( path.startsWith( *sit ) )
2821 void CopyJob::slotResultCreatingDirs(
Job * job )
2824 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2828 m_conflictError = job->
error();
2829 if ( (m_conflictError == ERR_DIR_ALREADY_EXIST)
2830 || (m_conflictError == ERR_FILE_ALREADY_EXIST) )
2834 if ( m_bAutoSkip ) {
2836 m_skipList.append( oldURL.path( 1 ) );
2841 const TQString destFile = (*it).uDest.path();
2842 if ( shouldOverwrite( destFile ) ) {
2843 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
2851 assert( ((
SimpleJob*)job)->url().url() == (*it).uDest.url() );
2852 subjobs.remove( job );
2853 assert ( subjobs.isEmpty() );
2856 KURL existingDest( (*it).uDest );
2859 kdDebug(7007) <<
"KIO::stat for resolving conflict on " << existingDest << endl;
2860 state = STATE_CONFLICT_CREATING_DIRS;
2876 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
true,
false );
2877 d->m_directoriesCopied.append( *it );
2883 subjobs.remove( job );
2884 assert( subjobs.isEmpty() );
2888 void CopyJob::slotResultConflictCreatingDirs(
KIO::Job * job )
2893 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2895 time_t destmtime = (time_t)-1;
2896 time_t destctime = (time_t)-1;
2901 KIO::UDSEntry::ConstIterator it2 = entry.begin();
2902 for( ; it2 != entry.end(); it2++ ) {
2903 switch ((*it2).m_uds) {
2905 destmtime = (time_t)((*it2).m_long);
2908 destctime = (time_t)((*it2).m_long);
2911 destsize = (*it2).m_long;
2914 linkDest = (*it2).m_str;
2918 subjobs.remove( job );
2919 assert ( subjobs.isEmpty() );
2922 RenameDlg_Mode mode = (RenameDlg_Mode)( M_MULTI | M_SKIP );
2924 if ( m_conflictError == ERR_DIR_ALREADY_EXIST )
2926 if( (*it).uSource == (*it).uDest ||
2927 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
2928 (*it).uSource.path(-1) == linkDest) )
2929 mode = (RenameDlg_Mode)( mode | M_OVERWRITE_ITSELF);
2931 mode = (RenameDlg_Mode)( mode | M_OVERWRITE );
2934 TQString existingDest = (*it).uDest.path();
2937 m_reportTimer->stop();
2939 (*it).uSource.url(),
2942 (*it).size, destsize,
2943 (*it).ctime, destctime,
2944 (*it).mtime, destmtime );
2946 m_reportTimer->start(REPORT_TIMEOUT,
false);
2949 m_error = ERR_USER_CANCELED;
2954 TQString oldPath = (*it).uDest.path( 1 );
2955 KURL newUrl( (*it).uDest );
2956 newUrl.setPath( newPath );
2957 emit
renamed(
this, (*it).uDest, newUrl );
2960 (*it).uDest.setPath( newUrl.path( -1 ) );
2961 newPath = newUrl.path( 1 );
2962 TQValueList<CopyInfo>::Iterator renamedirit = it;
2965 for( ; renamedirit != dirs.end() ; ++renamedirit )
2967 TQString path = (*renamedirit).uDest.path();
2968 if ( path.left(oldPath.length()) == oldPath ) {
2970 n.replace( 0, oldPath.length(), newPath );
2971 kdDebug(7007) <<
"dirs list: " << (*renamedirit).uSource.path()
2972 <<
" was going to be " << path
2973 <<
", changed into " << n << endl;
2974 (*renamedirit).uDest.setPath( n );
2978 TQValueList<CopyInfo>::Iterator renamefileit = files.begin();
2979 for( ; renamefileit != files.end() ; ++renamefileit )
2981 TQString path = (*renamefileit).uDest.path();
2982 if ( path.left(oldPath.length()) == oldPath ) {
2984 n.replace( 0, oldPath.length(), newPath );
2985 kdDebug(7007) <<
"files list: " << (*renamefileit).uSource.path()
2986 <<
" was going to be " << path
2987 <<
", changed into " << n << endl;
2988 (*renamefileit).uDest.setPath( n );
2991 if (!dirs.isEmpty())
2993 if (!files.isEmpty())
3001 m_skipList.append( existingDest );
3002 skip( (*it).uSource );
3008 m_overwriteList.append( existingDest );
3009 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3014 case R_OVERWRITE_ALL:
3015 m_bOverwriteAll =
true;
3016 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3024 state = STATE_CREATING_DIRS;
3029 void CopyJob::createNextDir()
3032 if ( !dirs.isEmpty() )
3035 TQValueList<CopyInfo>::Iterator it = dirs.begin();
3037 while( it != dirs.end() && udir.isEmpty() )
3039 const TQString dir = (*it).uDest.path();
3040 if ( shouldSkip( dir ) ) {
3047 if ( !udir.isEmpty() )
3054 m_currentDestURL = udir;
3055 d->m_bURLDirty =
true;
3063 if (m_progressId)
Observer::self()->slotProcessedDirs(
this, m_processedDirs );
3065 state = STATE_COPYING_FILES;
3071 void CopyJob::slotResultCopyingFiles(
Job * job )
3074 TQValueList<CopyInfo>::Iterator it = files.begin();
3080 skip( (*it).uSource );
3081 m_fileProcessedSize = (*it).size;
3091 m_conflictError = job->
error();
3093 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3094 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3095 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3097 subjobs.remove( job );
3098 assert ( subjobs.isEmpty() );
3100 KURL existingFile( (*it).uDest );
3103 kdDebug(7007) <<
"KIO::stat for resolving conflict on " << existingFile << endl;
3104 state = STATE_CONFLICT_COPYING_FILES;
3110 if ( m_bCurrentOperationIsLink && ::tqqt_cast<KIO::DeleteJob*>( job ) )
3114 m_fileProcessedSize = (*it).size;
3118 slotResultConflictCopyingFiles( job );
3126 if ( m_bCurrentOperationIsLink && m_mode == Move
3127 && !::tqqt_cast<KIO::DeleteJob *>( job )
3130 subjobs.remove( job );
3131 assert ( subjobs.isEmpty() );
3139 if ( m_bCurrentOperationIsLink )
3141 TQString target = ( m_mode == Link ? (*it).uSource.path() : (*it).linkDest );
3147 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
false,
false );
3154 m_processedSize += m_fileProcessedSize;
3155 m_fileProcessedSize = 0;
3160 assert ( subjobs.isEmpty() );
3164 void CopyJob::slotResultConflictCopyingFiles(
KIO::Job * job )
3168 TQValueList<CopyInfo>::Iterator it = files.begin();
3174 m_reportTimer->stop();
3176 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3177 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3178 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3181 time_t destmtime = (time_t)-1;
3182 time_t destctime = (time_t)-1;
3186 KIO::UDSEntry::ConstIterator it2 = entry.begin();
3187 for( ; it2 != entry.end(); it2++ ) {
3188 switch ((*it2).m_uds) {
3190 destmtime = (time_t)((*it2).m_long);
3193 destctime = (time_t)((*it2).m_long);
3196 destsize = (*it2).m_long;
3199 linkDest = (*it2).m_str;
3206 RenameDlg_Mode mode;
3209 if( m_conflictError == ERR_DIR_ALREADY_EXIST )
3210 mode = (RenameDlg_Mode) 0;
3213 if ( (*it).uSource == (*it).uDest ||
3214 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
3215 (*it).uSource.path(-1) == linkDest) )
3216 mode = M_OVERWRITE_ITSELF;
3222 if ( m_bSingleFileCopy )
3223 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3225 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3228 i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3229 (*it).uSource.url(),
3232 (*it).size, destsize,
3233 (*it).ctime, destctime,
3234 (*it).mtime, destmtime );
3239 if ( job->
error() == ERR_USER_CANCELED )
3247 SkipDlg_Result skipResult =
Observer::self()->open_SkipDlg(
this, files.count() > 1,
3251 res = ( skipResult == S_SKIP ) ? R_SKIP :
3252 ( skipResult == S_AUTO_SKIP ) ? R_AUTO_SKIP :
3258 m_reportTimer->start(REPORT_TIMEOUT,
false);
3260 subjobs.remove( job );
3261 assert ( subjobs.isEmpty() );
3264 m_error = ERR_USER_CANCELED;
3269 KURL newUrl( (*it).uDest );
3270 newUrl.setPath( newPath );
3271 emit
renamed(
this, (*it).uDest, newUrl );
3272 (*it).uDest = newUrl;
3274 TQValueList<CopyInfo> files;
3284 skip( (*it).uSource );
3285 m_processedSize += (*it).size;
3289 case R_OVERWRITE_ALL:
3290 m_bOverwriteAll =
true;
3294 m_overwriteList.append( (*it).uDest.path() );
3299 state = STATE_COPYING_FILES;
3304 void CopyJob::copyNextFile()
3306 bool bCopyFile =
false;
3309 TQValueList<CopyInfo>::Iterator it = files.begin();
3311 while (it != files.end() && !bCopyFile)
3313 const TQString destFile = (*it).uDest.path();
3314 bCopyFile = !shouldSkip( destFile );
3325 const TQString destFile = (*it).uDest.path();
3326 kdDebug(7007) <<
"copying " << destFile << endl;
3327 if ( (*it).uDest == (*it).uSource )
3330 bOverwrite = shouldOverwrite( destFile );
3332 m_bCurrentOperationIsLink =
false;
3334 if ( m_mode == Link )
3338 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3339 ((*it).uSource.host() == (*it).uDest.host()) &&
3340 ((*it).uSource.port() == (*it).uDest.port()) &&
3341 ((*it).uSource.user() == (*it).uDest.user()) &&
3342 ((*it).uSource.pass() == (*it).uDest.pass()) )
3350 m_bCurrentOperationIsLink =
true;
3351 m_currentSrcURL=(*it).uSource;
3352 m_currentDestURL=(*it).uDest;
3353 d->m_bURLDirty =
true;
3357 if ( (*it).uDest.isLocalFile() )
3359 bool devicesOk=
false;
3362 if ((*it).uSource.protocol()==TQString::fromLatin1(
"devices"))
3367 TQDataStream streamout(param,IO_WriteOnly);
3368 streamout<<(*it).uSource;
3369 streamout<<(*it).uDest;
3370 if ( kapp && kapp->dcopClient()->call(
"kded",
3371 "mountwatcher",
"createLink(KURL, KURL)", param,retType,data,
false ) )
3373 TQDataStream streamin(data,IO_ReadOnly);
3374 streamin>>devicesOk;
3388 TQString path = (*it).uDest.path();
3391 if ( f.open( IO_ReadWrite ) )
3394 KSimpleConfig config( path );
3395 config.setDesktopGroup();
3396 KURL url = (*it).uSource;
3398 config.writePathEntry( TQString::fromLatin1(
"URL"), url.url() );
3399 config.writeEntry( TQString::fromLatin1(
"Name"), url.url() );
3400 config.writeEntry( TQString::fromLatin1(
"Type"), TQString::fromLatin1(
"Link") );
3401 TQString protocol = (*it).uSource.protocol();
3402 if ( protocol == TQString::fromLatin1(
"ftp") )
3403 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"ftp") );
3404 else if ( protocol == TQString::fromLatin1(
"http") )
3405 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"www") );
3406 else if ( protocol == TQString::fromLatin1(
"info") )
3407 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"info") );
3408 else if ( protocol == TQString::fromLatin1(
"mailto") )
3409 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"kmail") );
3411 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"unknown") );
3421 kdDebug(7007) <<
"CopyJob::copyNextFile ERR_CANNOT_OPEN_FOR_WRITING" << endl;
3422 m_error = ERR_CANNOT_OPEN_FOR_WRITING;
3423 m_errorText = (*it).uDest.path();
3430 m_error = ERR_CANNOT_SYMLINK;
3431 m_errorText = (*it).uDest.prettyURL();
3437 else if ( !(*it).linkDest.isEmpty() &&
3438 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3439 ((*it).uSource.host() == (*it).uDest.host()) &&
3440 ((*it).uSource.port() == (*it).uDest.port()) &&
3441 ((*it).uSource.user() == (*it).uDest.user()) &&
3442 ((*it).uSource.pass() == (*it).uDest.pass()))
3450 m_currentSrcURL=(*it).linkDest;
3451 m_currentDestURL=(*it).uDest;
3452 d->m_bURLDirty =
true;
3454 m_bCurrentOperationIsLink =
true;
3456 }
else if (m_mode == Move)
3463 m_currentSrcURL=(*it).uSource;
3464 m_currentDestURL=(*it).uDest;
3465 d->m_bURLDirty =
true;
3473 int permissions = (*it).permissions;
3474 if ( d->m_defaultPermissions || ( remoteSource && (*it).uDest.isLocalFile() ) )
3482 m_currentSrcURL=(*it).uSource;
3483 m_currentDestURL=(*it).uDest;
3484 d->m_bURLDirty =
true;
3500 void CopyJob::deleteNextDir()
3502 if ( m_mode == Move && !dirsToRemove.isEmpty() )
3504 state = STATE_DELETING_DIRS;
3505 d->m_bURLDirty =
true;
3507 KURL::List::Iterator it = dirsToRemove.fromLast();
3510 dirsToRemove.remove(it);
3516 setNextDirAttribute();
3520 void CopyJob::setNextDirAttribute()
3522 if ( !d->m_directoriesCopied.isEmpty() )
3524 state = STATE_SETTING_DIR_ATTRIBUTES;
3527 TQValueList<CopyInfo>::Iterator it = d->m_directoriesCopied.begin();
3528 for ( ; it != d->m_directoriesCopied.end() ; ++it ) {
3529 const KURL& url = (*it).uDest;
3530 if ( url.isLocalFile() && (*it).mtime != (time_t)-1 ) {
3531 const TQCString path = TQFile::encodeName( url.path() );
3532 KDE_struct_stat statbuf;
3533 if (KDE_lstat(path, &statbuf) == 0) {
3534 struct utimbuf utbuf;
3535 utbuf.actime = statbuf.st_atime;
3536 utbuf.modtime = (*it).mtime;
3537 utime( path, &utbuf );
3543 d->m_directoriesCopied.clear();
3550 if ( !m_bOnlyRenames )
3552 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
3553 KURL url( d->m_globalDest );
3554 if ( d->m_globalDestinationState != DEST_IS_DIR || m_asMethod )
3555 url.setPath( url.directory() );
3557 allDirNotify.FilesAdded( url );
3559 if ( m_mode == Move && !m_srcList.isEmpty() ) {
3561 allDirNotify.FilesRemoved( m_srcList );
3565 m_reportTimer->stop();
3576 m_fileProcessedSize = data_size;
3579 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
3581 m_totalSize = m_processedSize + m_fileProcessedSize;
3586 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
3587 emitPercent( m_processedSize + m_fileProcessedSize, m_totalSize );
3597 if ( m_bSingleFileCopy && size > m_totalSize)
3605 void CopyJob::slotResultDeletingDirs(
Job * job )
3613 subjobs.remove( job );
3614 assert ( subjobs.isEmpty() );
3619 void CopyJob::slotResultSettingDirAttributes(
Job * job )
3627 subjobs.remove( job );
3628 assert ( subjobs.isEmpty() );
3629 setNextDirAttribute();
3633 void CopyJob::slotResultRenaming(
Job* job )
3635 int err = job->
error();
3636 const TQString errText = job->
errorText();
3638 assert ( subjobs.isEmpty() );
3641 if ( destinationState == DEST_IS_DIR && !m_asMethod )
3642 dest.addPath( m_currentSrcURL.fileName() );
3648 if ( m_currentSrcURL.isLocalFile() && m_currentSrcURL.url(-1) != dest.url(-1) &&
3649 m_currentSrcURL.url(-1).lower() == dest.url(-1).lower() &&
3650 ( err == ERR_FILE_ALREADY_EXIST ||
3651 err == ERR_DIR_ALREADY_EXIST ||
3652 err == ERR_IDENTICAL_FILES ) )
3654 kdDebug(7007) <<
"Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls" << endl;
3655 TQCString _src( TQFile::encodeName(m_currentSrcURL.path()) );
3656 TQCString _dest( TQFile::encodeName(dest.path()) );
3657 KTempFile tmpFile( m_currentSrcURL.directory(
false) );
3658 TQCString _tmp( TQFile::encodeName(tmpFile.name()) );
3659 kdDebug(7007) <<
"CopyJob::slotResult KTempFile status:" << tmpFile.status() <<
" using " << _tmp <<
" as intermediary" << endl;
3661 if ( ::
rename( _src, _tmp ) == 0 )
3663 if ( !TQFile::exists( _dest ) && ::
rename( _tmp, _dest ) == 0 )
3665 kdDebug(7007) <<
"Success." << endl;
3671 if ( ::
rename( _tmp, _src ) != 0 ) {
3672 kdError(7007) <<
"Couldn't rename " << tmpFile.name() <<
" back to " << _src <<
" !" << endl;
3690 Q_ASSERT( m_currentSrcURL == *m_currentStatSrc );
3693 if ( ( err == ERR_DIR_ALREADY_EXIST ||
3694 err == ERR_FILE_ALREADY_EXIST ||
3695 err == ERR_IDENTICAL_FILES )
3699 m_reportTimer->stop();
3702 if ( m_bAutoSkip ) {
3706 }
else if ( m_bOverwriteAll ) {
3711 RenameDlg_Mode mode = (RenameDlg_Mode)
3712 ( ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE );
3714 if ( m_srcList.count() > 1 )
3715 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3717 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3724 time_t ctimeSrc = (time_t) -1;
3725 time_t ctimeDest = (time_t) -1;
3726 time_t mtimeSrc = (time_t) -1;
3727 time_t mtimeDest = (time_t) -1;
3729 KDE_struct_stat stat_buf;
3730 if ( m_currentSrcURL.isLocalFile() &&
3731 KDE_stat(TQFile::encodeName(m_currentSrcURL.path()), &stat_buf) == 0 ) {
3732 sizeSrc = stat_buf.st_size;
3733 ctimeSrc = stat_buf.st_ctime;
3734 mtimeSrc = stat_buf.st_mtime;
3736 if ( dest.isLocalFile() &&
3737 KDE_stat(TQFile::encodeName(dest.path()), &stat_buf) == 0 ) {
3738 sizeDest = stat_buf.st_size;
3739 ctimeDest = stat_buf.st_ctime;
3740 mtimeDest = stat_buf.st_mtime;
3745 err != ERR_DIR_ALREADY_EXIST ? i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3746 m_currentSrcURL.url(),
3750 ctimeSrc, ctimeDest,
3751 mtimeSrc, mtimeDest );
3753 m_reportTimer->start(REPORT_TIMEOUT,
false);
3759 m_error = ERR_USER_CANCELED;
3767 m_dest.setPath( newPath );
3769 state = STATE_STATING;
3770 destinationState = DEST_NOT_STATED;
3781 case R_OVERWRITE_ALL:
3782 m_bOverwriteAll =
true;
3790 kdDebug(7007) <<
"adding to overwrite list: " << dest.path() << endl;
3791 m_overwriteList.append( dest.path() );
3798 }
else if ( err != KIO::ERR_UNSUPPORTED_ACTION ) {
3799 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", aborting" << endl;
3801 m_errorText = errText;
3805 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", reverting to normal way, starting with stat" << endl;
3808 state = STATE_STATING;
3810 m_bOnlyRenames =
false;
3815 emit
copyingDone(
this, *m_currentStatSrc, dest,
true,
true );
3820 void CopyJob::slotResult(
Job *job )
3830 slotResultStating( job );
3832 case STATE_RENAMING:
3834 slotResultRenaming( job );
3846 subjobs.remove( job );
3847 assert ( subjobs.isEmpty() );
3851 case STATE_CREATING_DIRS:
3852 slotResultCreatingDirs( job );
3854 case STATE_CONFLICT_CREATING_DIRS:
3855 slotResultConflictCreatingDirs( job );
3857 case STATE_COPYING_FILES:
3858 slotResultCopyingFiles( job );
3860 case STATE_CONFLICT_COPYING_FILES:
3861 slotResultConflictCopyingFiles( job );
3863 case STATE_DELETING_DIRS:
3864 slotResultDeletingDirs( job );
3866 case STATE_SETTING_DIR_ATTRIBUTES:
3877 d->m_defaultPermissions = b;
3890 srcList.append( src );
3891 return new CopyJob( srcList, dest, CopyJob::Copy,
false, showProgressInfo );
3898 srcList.append( src );
3899 return new CopyJob( srcList, dest, CopyJob::Copy,
true, showProgressInfo );
3905 return new CopyJob( src, dest, CopyJob::Copy,
false, showProgressInfo );
3912 srcList.append( src );
3913 return new CopyJob( srcList, dest, CopyJob::Move,
false, showProgressInfo );
3920 srcList.append( src );
3921 return new CopyJob( srcList, dest, CopyJob::Move,
true, showProgressInfo );
3927 return new CopyJob( src, dest, CopyJob::Move,
false, showProgressInfo );
3933 srcList.append( src );
3934 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3939 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3945 srcList.append( src );
3946 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3952 srcList.append( src );
3953 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
3958 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
3964 :
Job(showProgressInfo), m_totalSize( 0 ), m_processedSize( 0 ), m_fileProcessedSize( 0 ),
3965 m_processedFiles( 0 ), m_processedDirs( 0 ), m_totalFilesDirs( 0 ),
3966 m_srcList(src), m_currentStat(m_srcList.begin()), m_reportTimer(0)
3968 if ( showProgressInfo ) {
3971 Observer::self(), TQT_SLOT( slotTotalFiles(
KIO::Job*,
unsigned long ) ) );
3974 Observer::self(), TQT_SLOT( slotTotalDirs(
KIO::Job*,
unsigned long ) ) );
3986 m_reportTimer=
new TQTimer(
this);
3987 connect(m_reportTimer,TQT_SIGNAL(timeout()),
this,TQT_SLOT(slotReport()));
3989 m_reportTimer->start(REPORT_TIMEOUT,
false);
3992 TQTimer::singleShot(0,
this, TQT_SLOT(slotStart()));
3995 void DeleteJob::slotStart()
4003 void DeleteJob::slotReport()
4005 if (m_progressId==0)
4010 emit
deleting(
this, m_currentURL );
4011 observer->slotDeleting(
this,m_currentURL);
4020 case STATE_DELETING_DIRS:
4022 observer->slotProcessedDirs(
this,m_processedDirs);
4023 emitPercent( m_processedFiles + m_processedDirs, m_totalFilesDirs );
4025 case STATE_DELETING_FILES:
4026 observer->slotProcessedFiles(
this,m_processedFiles);
4028 emitPercent( m_processedFiles, m_totalFilesDirs );
4034 void DeleteJob::slotEntries(
KIO::Job* job,
const UDSEntryList& list)
4036 UDSEntryListConstIterator it = list.begin();
4037 UDSEntryListConstIterator end = list.end();
4038 for (; it != end; ++it)
4040 UDSEntry::ConstIterator it2 = (*it).begin();
4043 TQString displayName;
4046 for( ; it2 != (*it).end(); it2++ )
4048 switch ((*it2).m_uds)
4051 bDir = S_ISDIR((*it2).m_long);
4055 displayName = (*it2).m_str;
4059 url = KURL((*it2).m_str);
4063 bLink = !(*it2).m_str.isEmpty();
4073 if (atomsFound==5)
break;
4075 assert(!displayName.isEmpty());
4076 if (displayName !=
".." && displayName !=
".")
4078 if( url.isEmpty() ) {
4080 url.addPath( displayName );
4084 symlinks.append( url );
4088 files.append( url );
4094 void DeleteJob::statNextSrc()
4097 if ( m_currentStat != m_srcList.end() )
4099 m_currentURL = (*m_currentStat);
4103 TQGuardedPtr<DeleteJob> that =
this;
4106 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentURL.prettyURL()));
4112 state = STATE_STATING;
4121 m_totalFilesDirs = files.count()+symlinks.count() + dirs.count();
4127 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4129 state = STATE_DELETING_FILES;
4134 void DeleteJob::deleteNextFile()
4137 if ( !files.isEmpty() || !symlinks.isEmpty() )
4142 KURL::List::Iterator it = files.begin();
4143 bool isLink =
false;
4144 if ( it == files.end() )
4146 it = symlinks.begin();
4151 if ( (*it).isLocalFile() && unlink( TQFile::encodeName((*it).path()) ) == 0 ) {
4155 if ( m_processedFiles % 300 == 0 || m_totalFilesDirs < 300) {
4166 symlinks.remove(it);
4174 }
while (!job && (!files.isEmpty() || !symlinks.isEmpty()));
4176 state = STATE_DELETING_DIRS;
4180 void DeleteJob::deleteNextDir()
4182 if ( !dirs.isEmpty() )
4186 KURL::List::Iterator it = dirs.fromLast();
4188 if ( (*it).isLocalFile() &&
::rmdir( TQFile::encodeName((*it).path()) ) == 0 ) {
4191 if ( m_processedDirs % 100 == 0 ) {
4197 if ( KProtocolInfo::canDeleteRecursive( *it ) ) {
4210 }
while ( !dirs.isEmpty() );
4214 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4218 if ( !m_srcList.isEmpty() )
4220 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
4222 allDirNotify.FilesRemoved( m_srcList );
4224 if (m_reportTimer!=0)
4225 m_reportTimer->stop();
4235 m_fileProcessedSize = data_size;
4240 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
4243 unsigned long ipercent = m_percent;
4245 if ( m_totalSize == 0 )
4248 m_percent = (
unsigned long)(( (
float)(m_processedSize + m_fileProcessedSize) / (
float)m_totalSize ) * 100.0);
4250 if ( m_percent > ipercent )
4252 emit
percent(
this, m_percent );
4258 void DeleteJob::slotResult(
Job *job )
4277 UDSEntry::ConstIterator it2 = entry.begin();
4279 for( ; it2 != entry.end(); it2++ )
4283 bDir = S_ISDIR( (mode_t)(*it2).m_long );
4288 bLink = !((*it2).m_str.isEmpty());
4291 else if ( ((*it2).m_uds) ==
UDS_SIZE )
4293 size = (*it2).m_long;
4296 if (atomsFound==3)
break;
4301 subjobs.remove( job );
4302 assert( subjobs.isEmpty() );
4308 if ( url.isLocalFile() && !m_parentDirs.contains( url.path(-1) ) )
4309 m_parentDirs.append( url.path(-1) );
4311 if ( !KProtocolInfo::canDeleteRecursive( url ) ) {
4314 state = STATE_LISTING;
4318 connect(newjob, TQT_SIGNAL(entries(
KIO::Job *,
4319 const KIO::UDSEntryList& )),
4321 const KIO::UDSEntryList& )));
4332 symlinks.append( url );
4335 files.append( url );
4337 if ( url.isLocalFile() && !m_parentDirs.contains( url.directory(
false) ) )
4338 m_parentDirs.append( url.directory(
false) );
4349 subjobs.remove( job );
4350 assert( subjobs.isEmpty() );
4354 case STATE_DELETING_FILES:
4360 subjobs.remove( job );
4361 assert( subjobs.isEmpty() );
4366 case STATE_DELETING_DIRS:
4372 subjobs.remove( job );
4373 assert( subjobs.isEmpty() );
4389 srcList.append( src );
4401 bool showProgressInfo)
4402 :
TransferJob(url, 0, TQByteArray(), TQByteArray(), showProgressInfo)
4404 m_waitQueue.setAutoDelete(
true);
4405 m_activeQueue.setAutoDelete(
true);
4411 GetRequest *entry =
new GetRequest(
id, url, metaData);
4412 entry->metaData[
"request-id"] = TQString(
"%1").arg(
id);
4413 m_waitQueue.append(entry);
4416 void MultiGetJob::flushQueue(TQPtrList<GetRequest> &queue)
4421 for(entry = m_waitQueue.first(); entry; )
4423 if ((m_url.protocol() == entry->url.protocol()) &&
4424 (m_url.host() == entry->url.host()) &&
4425 (m_url.port() == entry->url.port()) &&
4426 (m_url.user() == entry->url.user()))
4429 queue.append(entry);
4430 entry = m_waitQueue.current();
4434 entry = m_waitQueue.next();
4438 KIO_ARGS << (TQ_INT32) queue.count();
4439 for(entry = queue.first(); entry; entry = queue.next())
4441 stream << entry->url << entry->metaData;
4443 m_packedArgs = packedArgs;
4444 m_command = CMD_MULTI_GET;
4445 m_outgoingMetaData.clear();
4448 void MultiGetJob::start(
Slave *slave)
4451 GetRequest *entry = m_waitQueue.take(0);
4452 m_activeQueue.append(entry);
4456 if (!entry->url.protocol().startsWith(
"http"))
4459 KIO_ARGS << entry->url;
4460 m_packedArgs = packedArgs;
4461 m_outgoingMetaData = entry->metaData;
4462 m_command = CMD_GET;
4463 b_multiGetActive =
false;
4467 flushQueue(m_activeQueue);
4468 b_multiGetActive =
true;
4471 TransferJob::start(slave);
4474 bool MultiGetJob::findCurrentEntry()
4476 if (b_multiGetActive)
4478 long id = m_incomingMetaData[
"request-id"].toLong();
4479 for(GetRequest *entry = m_activeQueue.first(); entry; entry = m_activeQueue.next())
4481 if (entry->id ==
id)
4483 m_currentEntry = entry;
4492 m_currentEntry = m_activeQueue.first();
4493 return (m_currentEntry != 0);
4497 void MultiGetJob::slotRedirection(
const KURL &url)
4499 if (!findCurrentEntry())
return;
4500 if (kapp && !kapp->authorizeURLAction(
"redirect", m_url, url))
4502 kdWarning(7007) <<
"MultiGetJob: Redirection from " << m_currentEntry->url <<
" to " << url <<
" REJECTED!" << endl;
4505 m_redirectionURL =
url;
4506 if (m_currentEntry->url.hasUser() && !url.hasUser() && (m_currentEntry->url.host().lower() == url.host().lower()))
4507 m_redirectionURL.setUser(m_currentEntry->url.user());
4508 get(m_currentEntry->id, m_redirectionURL, m_currentEntry->metaData);
4512 void MultiGetJob::slotFinished()
4514 if (!findCurrentEntry())
return;
4515 if (m_redirectionURL.isEmpty())
4518 emit
result(m_currentEntry->id);
4520 m_redirectionURL = KURL();
4522 m_incomingMetaData.clear();
4523 m_activeQueue.removeRef(m_currentEntry);
4524 if (m_activeQueue.count() == 0)
4526 if (m_waitQueue.count() == 0)
4529 TransferJob::slotFinished();
4536 GetRequest *entry = m_waitQueue.at(0);
4544 void MultiGetJob::slotData(
const TQByteArray &_data)
4546 if(!m_currentEntry)
return;
4547 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
4548 emit
data(m_currentEntry->id, _data);
4551 void MultiGetJob::slotMimetype(
const TQString &_mimetype )
4553 if (b_multiGetActive)
4555 TQPtrList<GetRequest> newQueue;
4556 flushQueue(newQueue);
4557 if (!newQueue.isEmpty())
4559 while(!newQueue.isEmpty())
4560 m_activeQueue.append(newQueue.take(0));
4561 m_slave->
send( m_command, m_packedArgs );
4564 if (!findCurrentEntry())
return;
4565 emit
mimetype(m_currentEntry->id, _mimetype);
4571 job->
get(
id, url, metaData);
4577 CacheInfo::CacheInfo(
const KURL &url)
4582 TQString CacheInfo::cachedFileName()
4584 const TQChar separator =
'_';
4586 TQString CEF = m_url.path();
4588 int p = CEF.find(
'/');
4593 p = CEF.find(
'/', p);
4596 TQString host = m_url.host().lower();
4597 CEF = host + CEF +
'_';
4600 if (dir[dir.length()-1] !=
'/')
4603 int l = m_url.host().length();
4604 for(
int i = 0; i < l; i++)
4606 if (host[i].isLetter() && (host[i] !=
'w'))
4612 if (dir[dir.length()-1] ==
'/')
4615 unsigned long hash = 0x00000000;
4616 TQCString u = m_url.url().latin1();
4617 for(
int i = u.length(); i--;)
4619 hash = (hash * 12211 + u[i]) % 2147483563;
4622 TQString hashString;
4623 hashString.sprintf(
"%08lx", hash);
4625 CEF = CEF + hashString;
4627 CEF = dir +
"/" + CEF;
4632 TQFile *CacheInfo::cachedFile()
4635 const char *mode = (readWrite ?
"rb+" :
"rb");
4637 const char *mode = (readWrite ?
"r+" :
"r");
4640 FILE *fs = fopen(TQFile::encodeName(CEF), mode);
4648 if (ok && (!fgets(buffer, 400, fs)))
4650 if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
4654 time_t currentDate = time(0);
4657 if (ok && (!fgets(buffer, 400, fs)))
4661 int l = strlen(buffer);
4664 if (m_.url.url() != buffer)
4671 if (ok && (!fgets(buffer, 400, fs)))
4675 date = (time_t) strtoul(buffer, 0, 10);
4676 if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge))
4678 m_bMustRevalidate =
true;
4679 m_expireDate = currentDate;
4684 m_cacheExpireDateOffset = ftell(fs);
4685 if (ok && (!fgets(buffer, 400, fs)))
4691 date = (time_t) strtoul(buffer, 0, 10);
4693 if (!date || difftime(currentDate, date) >= 0)
4694 m_bMustRevalidate =
true;
4695 m_expireDate = date;
4700 if (ok && (!fgets(buffer, 400, fs)))
4704 m_etag = TQString(buffer).stripWhiteSpace();
4708 if (ok && (!fgets(buffer, 400, fs)))
4712 m_lastModified = TQString(buffer).stripWhiteSpace();
4720 unlink( TQFile::encodeName(CEF) );
4725 void CacheInfo::flush()
4727 cachedFile().remove();
4730 void CacheInfo::touch()
4734 void CacheInfo::setExpireDate(
int);
4735 void CacheInfo::setExpireTimeout(
int);
4738 int CacheInfo::creationDate();
4739 int CacheInfo::expireDate();
4740 int CacheInfo::expireTimeout();
4743 void Job::virtual_hook(
int,
void* )
4746 void SimpleJob::virtual_hook(
int id,
void* data )
4747 { KIO::Job::virtual_hook(
id, data ); }
4749 void MkdirJob::virtual_hook(
int id,
void* data )
4750 { SimpleJob::virtual_hook(
id, data ); }
4752 void StatJob::virtual_hook(
int id,
void* data )
4753 { SimpleJob::virtual_hook(
id, data ); }
4755 void TransferJob::virtual_hook(
int id,
void* data )
4756 { SimpleJob::virtual_hook(
id, data ); }
4758 void MultiGetJob::virtual_hook(
int id,
void* data )
4759 { TransferJob::virtual_hook(
id, data ); }
4761 void MimetypeJob::virtual_hook(
int id,
void* data )
4762 { TransferJob::virtual_hook(
id, data ); }
4764 void FileCopyJob::virtual_hook(
int id,
void* data )
4765 { Job::virtual_hook(
id, data ); }
4767 void ListJob::virtual_hook(
int id,
void* data )
4768 { SimpleJob::virtual_hook(
id, data ); }
4770 void CopyJob::virtual_hook(
int id,
void* data )
4771 { Job::virtual_hook(
id, data ); }
4773 void DeleteJob::virtual_hook(
int id,
void* data )
4774 { Job::virtual_hook(
id, data ); }
4777 #include "jobclasses.moc"