22 #include "tdeio/job.h"
26 #include <sys/types.h>
44 #include <tdeapplication.h>
45 #include <tdeglobal.h>
46 #include <tdelocale.h>
47 #include <ksimpleconfig.h>
50 #include <tdemessagebox.h>
51 #include <kdatastream.h>
52 #include <tdemainwindow.h>
57 #include "kmimetype.h"
59 #include "scheduler.h"
60 #include "kdirwatch.h"
61 #include "kmimemagic.h"
62 #include "kprotocolinfo.h"
63 #include "tdeprotocolmanager.h"
65 #include "tdeio/observer.h"
67 #include "kssl/ksslcsessioncache.h"
69 #include <kdirnotify_stub.h>
70 #include <tdetempfile.h>
71 #include <dcopclient.h>
81 using namespace TDEIO;
82 template class TQPtrList<TDEIO::Job>;
85 #define REPORT_TIMEOUT 200
87 #define TDEIO_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(
TDEIO::Job*,
unsigned long ) ),
123 connect(
this, TQT_SIGNAL( infoMessage(
TDEIO::Job*,
const TQString & ) ),
129 connect(
this, TQT_SIGNAL( speed(
TDEIO::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;
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 TDEIO_ARGS << m_outgoingMetaData;
556 slave->
send( CMD_META_DATA, packedArgs );
559 if (!m_subUrl.isEmpty())
561 TDEIO_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() )
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 TDEIO_ARGS << url << permissions;
755 return new MkdirJob(url, CMD_MKDIR, packedArgs,
false);
761 TDEIO_ARGS << url << TQ_INT8(
false);
762 return new SimpleJob(url, CMD_DEL, packedArgs,
false);
768 TDEIO_ARGS << url << permissions;
769 return new SimpleJob(url, CMD_CHMOD, packedArgs,
false);
775 TDEIO_ARGS << src << dest << (TQ_INT8) overwrite;
776 return new SimpleJob(src, CMD_RENAME, packedArgs,
false);
782 TDEIO_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 *
TDEIO::mount(
bool ro,
const char *fstype,
const TQString& dev,
const TQString& point,
bool showProgressInfo )
794 TDEIO_ARGS << int(1) << TQ_INT8( ro ? 1 : 0 )
795 << TQString::fromLatin1(fstype) << dev << point;
797 if ( showProgressInfo )
804 TDEIO_ARGS << int(2) << point;
806 if ( showProgressInfo )
813 const TQByteArray &packedArgs,
bool showProgressInfo )
814 :
SimpleJob(url, command, packedArgs, showProgressInfo)
819 void LocalURLJob::start(
Slave *slave)
821 connect( slave, TQT_SIGNAL(
localURL(
const KURL &,
bool) ),
822 TQT_SLOT( slotLocalURL(
const KURL &,
bool) ) );
824 SimpleJob::start(slave);
828 void LocalURLJob::slotLocalURL(
const KURL &url,
bool isLocal)
830 kdDebug(7007) <<
"LocalURLJob::slotLocalURL(" <<
url <<
")" << endl;
835 void LocalURLJob::slotFinished()
843 TDEIO_ARGS << remoteUrl;
844 return new LocalURLJob(remoteUrl, CMD_LOCALURL, packedArgs,
false);
851 const TQByteArray &packedArgs,
bool showProgressInfo )
852 :
SimpleJob(url, command, packedArgs, showProgressInfo),
853 m_bSource(true), m_details(2)
857 void StatJob::start(
Slave *slave)
859 m_outgoingMetaData.replace(
"statSide", m_bSource ?
"source" :
"dest" );
860 m_outgoingMetaData.replace(
"details", TQString::number(m_details) );
864 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
865 TQT_SLOT( slotRedirection(
const KURL &) ) );
867 SimpleJob::start(slave);
873 m_statResult = entry;
877 void StatJob::slotRedirection(
const KURL &url)
879 kdDebug(7007) <<
"StatJob::slotRedirection(" <<
url <<
")" << endl;
880 if (!kapp->authorizeURLAction(
"redirect", m_url,
url))
882 kdWarning(7007) <<
"StatJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
883 m_error = ERR_ACCESS_DENIED;
884 m_errorText =
url.prettyURL();
887 m_redirectionURL =
url;
888 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
889 m_redirectionURL.setUser(m_url.user());
894 void StatJob::slotFinished()
896 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
904 m_url = m_redirectionURL;
905 m_redirectionURL = KURL();
906 m_packedArgs.truncate(0);
907 TQDataStream stream( m_packedArgs, IO_WriteOnly );
918 storeSSLSessionFromJob(m_redirectionURL);
924 return stat( url,
true, 2, showProgressInfo );
929 kdDebug(7007) <<
"stat " << url << endl;
931 StatJob * job =
new StatJob(url, CMD_STAT, packedArgs, showProgressInfo );
934 if ( showProgressInfo )
941 assert( (url.protocol() ==
"http") || (url.protocol() ==
"https") );
943 TDEIO_ARGS << (int)2 << url << no_cache << expireDate;
952 const TQByteArray &packedArgs,
953 const TQByteArray &_staticData,
954 bool showProgressInfo)
955 :
SimpleJob(url, command, packedArgs, showProgressInfo), staticData( _staticData)
960 if ( showProgressInfo )
965 void TransferJob::slotData(
const TQByteArray &_data)
967 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
968 emit
data(
this, _data);
972 void TransferJob::slotRedirection(
const KURL &url)
974 kdDebug(7007) <<
"TransferJob::slotRedirection(" <<
url <<
")" << endl;
975 if (!kapp->authorizeURLAction(
"redirect", m_url,
url))
977 kdWarning(7007) <<
"TransferJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
984 if (m_redirectionList.contains(
url) > 5)
986 kdDebug(7007) <<
"TransferJob::slotRedirection: CYCLIC REDIRECTION!" << endl;
987 m_error = ERR_CYCLIC_LINK;
988 m_errorText = m_url.prettyURL();
992 m_redirectionURL =
url;
993 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
994 m_redirectionURL.setUser(m_url.user());
995 m_redirectionList.append(
url);
996 m_outgoingMetaData[
"ssl_was_in_use"] = m_incomingMetaData[
"ssl_in_use"];
1002 void TransferJob::slotFinished()
1005 if (m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
1015 staticData.truncate(0);
1016 m_incomingMetaData.clear();
1019 m_suspended =
false;
1020 m_url = m_redirectionURL;
1021 m_redirectionURL = KURL();
1025 TQDataStream istream( m_packedArgs, IO_ReadOnly );
1026 switch( m_command ) {
1028 m_packedArgs.truncate(0);
1029 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1035 TQ_INT8 iOverwrite, iResume;
1036 istream >> dummyUrl >> iOverwrite >> iResume >> permissions;
1037 m_packedArgs.truncate(0);
1038 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1039 stream << m_url << iOverwrite << iResume << permissions;
1044 istream >> specialcmd;
1045 if (specialcmd == 1)
1048 m_packedArgs.truncate(0);
1049 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1051 m_command = CMD_GET;
1066 extraFlags() |= EF_TransferJobAsync;
1068 extraFlags() &= ~EF_TransferJobAsync;
1073 if (extraFlags() & EF_TransferJobNeedData)
1075 m_slave->
send( MSG_DATA, dataForSlave );
1076 if (extraFlags() & EF_TransferJobDataSent)
1081 if ( size > m_totalSize ) {
1088 extraFlags() &= ~EF_TransferJobNeedData;
1094 extraFlags() |= EF_TransferJobDataSent;
1096 extraFlags() &= ~EF_TransferJobDataSent;
1101 return (extraFlags() & EF_TransferJobDataSent);
1106 void TransferJob::slotDataReq()
1108 TQByteArray dataForSlave;
1110 extraFlags() |= EF_TransferJobNeedData;
1112 if (!staticData.isEmpty())
1114 dataForSlave = staticData;
1115 staticData = TQByteArray();
1119 emit
dataReq(
this, dataForSlave);
1121 if (extraFlags() & EF_TransferJobAsync)
1125 static const size_t max_size = 14 * 1024 * 1024;
1126 if (dataForSlave.size() > max_size)
1128 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";
1129 staticData.duplicate(dataForSlave.data() + max_size , dataForSlave.size() - max_size);
1130 dataForSlave.truncate(max_size);
1143 void TransferJob::slotMimetype(
const TQString& type )
1159 m_suspended =
false;
1164 void TransferJob::start(
Slave *slave)
1167 connect( slave, TQT_SIGNAL(
data(
const TQByteArray & ) ),
1168 TQT_SLOT( slotData(
const TQByteArray & ) ) );
1170 connect( slave, TQT_SIGNAL(
dataReq() ),
1171 TQT_SLOT( slotDataReq() ) );
1173 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
1174 TQT_SLOT( slotRedirection(
const KURL &) ) );
1176 connect( slave, TQT_SIGNAL(mimeType(
const TQString& ) ),
1177 TQT_SLOT( slotMimetype(
const TQString& ) ) );
1179 connect( slave, TQT_SIGNAL(errorPage() ),
1180 TQT_SLOT( slotErrorPage() ) );
1182 connect( slave, TQT_SIGNAL( needSubURLData() ),
1183 TQT_SLOT( slotNeedSubURLData() ) );
1190 m_mimetype =
"unknown";
1195 SimpleJob::start(slave);
1200 void TransferJob::slotNeedSubURLData()
1203 m_subJob =
TDEIO::get( m_subUrl,
false,
false);
1205 connect(m_subJob, TQT_SIGNAL(
data(
TDEIO::Job*,
const TQByteArray &)),
1206 TQT_SLOT( slotSubURLData(
TDEIO::Job*,
const TQByteArray &)));
1210 void TransferJob::slotSubURLData(
TDEIO::Job*,
const TQByteArray &data)
1220 storeSSLSessionFromJob(m_redirectionURL);
1223 void TransferJob::slotErrorPage()
1230 emit canResume(
this, offset);
1236 assert(job == m_subJob);
1240 m_error = job->
error();
1247 if (job == m_subJob)
1269 PostErrorJob(
int _error,
const TQString& url,
const TQByteArray &packedArgs,
const TQByteArray &postData,
bool showProgressInfo)
1270 :
TransferJob(KURL(), CMD_SPECIAL, packedArgs, postData, showProgressInfo)
1283 static const int bad_ports[] = {
1345 for (
int cnt=0; bad_ports[cnt]; ++cnt)
1346 if (url.port() == bad_ports[cnt])
1348 _error = TDEIO::ERR_POST_DENIED;
1354 static bool override_loaded =
false;
1355 static TQValueList< int >* overriden_ports = NULL;
1356 if( !override_loaded )
1358 TDEConfig cfg(
"tdeio_httprc",
true );
1359 overriden_ports =
new TQValueList< int >;
1360 *overriden_ports = cfg.readIntListEntry(
"OverriddenPorts" );
1361 override_loaded =
true;
1363 for( TQValueList< int >::ConstIterator it = overriden_ports->begin();
1364 it != overriden_ports->end();
1366 if( overriden_ports->contains( url.port()))
1371 if ((url.protocol() !=
"http") && (url.protocol() !=
"https" ))
1372 _error = TDEIO::ERR_POST_DENIED;
1374 bool redirection =
false;
1376 if (_url.path().isEmpty())
1382 if (!_error && !kapp->authorizeURLAction(
"open", KURL(), _url))
1383 _error = TDEIO::ERR_ACCESS_DENIED;
1388 TDEIO_ARGS << (int)1 << url;
1389 TransferJob * job =
new PostErrorJob(_error, url.prettyURL(), packedArgs, postData, showProgressInfo);
1394 TDEIO_ARGS << (int)1 << _url;
1396 packedArgs, postData, showProgressInfo );
1399 TQTimer::singleShot(0, job, TQT_SLOT(slotPostRedirection()) );
1407 void TransferJob::slotPostRedirection()
1409 kdDebug(7007) <<
"TransferJob::slotPostRedirection(" << m_url <<
")" << endl;
1416 bool overwrite,
bool resume,
bool showProgressInfo )
1418 TDEIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1426 const TQByteArray &packedArgs,
1427 const TQByteArray &_staticData,
1428 bool showProgressInfo)
1429 :
TransferJob( url, command, packedArgs, _staticData, showProgressInfo ),
1432 connect(
this, TQT_SIGNAL(
data(
TDEIO::Job *,
const TQByteArray & ) ),
1433 TQT_SLOT( slotStoredData(
TDEIO::Job *,
const TQByteArray & ) ) );
1435 TQT_SLOT( slotStoredDataReq(
TDEIO::Job *, TQByteArray & ) ) );
1440 Q_ASSERT( m_data.isNull() );
1441 Q_ASSERT( m_uploadOffset == 0 );
1445 void StoredTransferJob::slotStoredData(
TDEIO::Job *,
const TQByteArray &data )
1448 if (
data.size() == 0 )
1450 unsigned int oldSize = m_data.size();
1451 m_data.resize( oldSize +
data.size(), TQGArray::SpeedOptim );
1452 memcpy( m_data.data() + oldSize,
data.data(),
data.size() );
1455 void StoredTransferJob::slotStoredDataReq(
TDEIO::Job *, TQByteArray &data )
1459 const int MAX_CHUNK_SIZE = 64*1024;
1460 int remainingBytes = m_data.size() - m_uploadOffset;
1461 if( remainingBytes > MAX_CHUNK_SIZE ) {
1463 data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
1464 m_uploadOffset += MAX_CHUNK_SIZE;
1469 data.duplicate( m_data.data() + m_uploadOffset, remainingBytes );
1470 m_data = TQByteArray();
1487 bool overwrite,
bool resume,
bool showProgressInfo )
1489 TDEIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1498 const TQByteArray &packedArgs,
bool showProgressInfo )
1499 :
TransferJob(url, command, packedArgs, TQByteArray(), showProgressInfo)
1503 void MimetypeJob::start(
Slave *slave)
1505 TransferJob::start(slave);
1509 void MimetypeJob::slotFinished( )
1512 if ( m_error == TDEIO::ERR_IS_DIRECTORY )
1517 kdDebug(7007) <<
"It is in fact a directory!" << endl;
1518 m_mimetype = TQString::fromLatin1(
"inode/directory");
1522 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error )
1525 TransferJob::slotFinished();
1530 staticData.truncate(0);
1531 m_suspended =
false;
1532 m_url = m_redirectionURL;
1533 m_redirectionURL = KURL();
1534 m_packedArgs.truncate(0);
1535 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1548 if ( showProgressInfo )
1555 DirectCopyJob::DirectCopyJob(
const KURL& url,
int command,
1556 const TQByteArray &packedArgs,
bool showProgressInfo )
1557 :
SimpleJob(url, command, packedArgs, showProgressInfo)
1561 void DirectCopyJob::start(
Slave* slave )
1565 SimpleJob::start(slave);
1570 emit canResume(
this, offset);
1576 class FileCopyJob::FileCopyJobPrivate
1580 time_t m_modificationTime;
1591 FileCopyJob::FileCopyJob(
const KURL& src,
const KURL& dest,
int permissions,
1592 bool move,
bool overwrite,
bool resume,
bool showProgressInfo)
1593 :
Job(showProgressInfo), m_src(src), m_dest(dest),
1594 m_permissions(permissions), m_move(
move), m_overwrite(overwrite), m_resume(resume),
1597 if (showProgressInfo && !
move)
1599 else if (showProgressInfo &&
move)
1607 d =
new FileCopyJobPrivate;
1610 d->m_modificationTime =
static_cast<time_t
>( -1 );
1611 TQTimer::singleShot(0,
this, TQT_SLOT(slotStart()));
1614 void FileCopyJob::slotStart()
1619 if ((m_src.protocol() == m_dest.protocol()) &&
1620 (m_src.host() == m_dest.host()) &&
1621 (m_src.port() == m_dest.port()) &&
1622 (m_src.user() == m_dest.user()) &&
1623 (m_src.pass() == m_dest.pass()) &&
1624 !m_src.hasSubURL() && !m_dest.hasSubURL())
1626 startRenameJob(m_src);
1629 else if (m_src.isLocalFile() && KProtocolInfo::canRenameFromFile(m_dest))
1631 startRenameJob(m_dest);
1634 else if (m_dest.isLocalFile() && KProtocolInfo::canRenameToFile(m_src))
1636 startRenameJob(m_src);
1641 startBestCopyMethod();
1644 void FileCopyJob::startBestCopyMethod()
1646 if ((m_src.protocol() == m_dest.protocol()) &&
1647 (m_src.host() == m_dest.host()) &&
1648 (m_src.port() == m_dest.port()) &&
1649 (m_src.user() == m_dest.user()) &&
1650 (m_src.pass() == m_dest.pass()) &&
1651 !m_src.hasSubURL() && !m_dest.hasSubURL())
1657 startCopyJob(m_dest);
1661 startCopyJob(m_src);
1669 FileCopyJob::~FileCopyJob()
1676 d->m_sourceSize = size;
1677 if (size != (off_t) -1)
1683 d->m_sourceSize = size;
1690 d->m_modificationTime = mtime;
1693 void FileCopyJob::startCopyJob()
1695 startCopyJob(m_src);
1698 void FileCopyJob::startCopyJob(
const KURL &slave_url)
1701 TDEIO_ARGS << m_src << m_dest << m_permissions << (TQ_INT8) m_overwrite;
1702 m_copyJob =
new DirectCopyJob(slave_url, CMD_COPY, packedArgs,
false);
1704 connectSubjob( m_copyJob );
1709 void FileCopyJob::startRenameJob(
const KURL &slave_url)
1711 TDEIO_ARGS << m_src << m_dest << (TQ_INT8) m_overwrite;
1712 m_moveJob =
new SimpleJob(slave_url, CMD_RENAME, packedArgs,
false);
1714 connectSubjob( m_moveJob );
1717 void FileCopyJob::connectSubjob(
SimpleJob * job )
1734 if ( size > m_totalSize ) {
1742 if (size > m_totalSize)
1751 if ( pct > m_percent )
1754 emit
percent(
this, m_percent );
1758 void FileCopyJob::startDataPump()
1762 m_canResume =
false;
1763 m_resumeAnswerSent =
false;
1765 m_putJob =
put( m_dest, m_permissions, m_overwrite, m_resume,
false );
1766 if ( d->m_modificationTime !=
static_cast<time_t
>( -1 ) ) {
1767 TQDateTime dt; dt.setTime_t( d->m_modificationTime );
1768 m_putJob->
addMetaData(
"modified", dt.toString( Qt::ISODate ) );
1776 connect( m_putJob, TQT_SIGNAL(dataReq(
TDEIO::Job *, TQByteArray&)),
1777 TQT_SLOT( slotDataReq(
TDEIO::Job *, TQByteArray&)));
1783 if ( job == m_putJob || job == m_copyJob )
1796 job, i18n(
"File Already Exists"),
1799 (RenameDlg_Mode) (M_OVERWRITE | M_RESUME | M_NORENAME), newPath,
1800 d->m_sourceSize, offset );
1803 if ( res == R_OVERWRITE || m_overwrite )
1805 else if ( res == R_CANCEL )
1807 if ( job == m_putJob )
1808 m_putJob->
kill(
true);
1810 m_copyJob->kill(
true);
1811 m_error = ERR_USER_CANCELED;
1817 m_resumeAnswerSent =
true;
1819 if ( job == m_putJob )
1821 m_getJob =
get( m_src,
false,
false );
1824 m_getJob->
addMetaData(
"AllowCompressedPage",
"false" );
1839 m_putJob->slave()->setOffset( offset );
1843 connectSubjob( m_getJob );
1846 connect( m_getJob, TQT_SIGNAL(data(
TDEIO::Job*,
const TQByteArray&)),
1847 TQT_SLOT( slotData(
TDEIO::Job*,
const TQByteArray&)) );
1849 TQT_SLOT(slotMimetype(
TDEIO::Job*,
const TQString&)) );
1853 m_copyJob->slave()->sendResumeAnswer( offset != 0 );
1856 else if ( job == m_getJob )
1862 m_getJob->slave()->setOffset( m_putJob->slave()->offset() );
1865 kdWarning(7007) <<
"FileCopyJob::slotCanResume from unknown job=" << job
1866 <<
" m_getJob=" << m_getJob <<
" m_putJob=" << m_putJob << endl;
1869 void FileCopyJob::slotData(
TDEIO::Job * ,
const TQByteArray &data)
1874 if (!m_putJob)
return;
1881 if (!m_resumeAnswerSent)
1883 m_resumeAnswerSent =
true;
1889 void FileCopyJob::slotDataReq(
TDEIO::Job * , TQByteArray &data)
1892 if (!m_resumeAnswerSent && !m_getJob)
1895 m_error = ERR_INTERNAL;
1896 m_errorText =
"'Put' job didn't send canResume or 'Get' job didn't send data!";
1897 m_putJob->
kill(
true);
1907 m_buffer = TQByteArray();
1910 void FileCopyJob::slotMimetype(
TDEIO::Job*,
const TQString& type )
1921 if ((job == m_moveJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1924 startBestCopyMethod();
1928 else if ((job == m_copyJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1935 else if (job == m_getJob)
1939 m_putJob->
kill(
true);
1941 else if (job == m_putJob)
1945 m_getJob->
kill(
true);
1947 m_error = job->
error();
1953 if (job == m_moveJob)
1958 if (job == m_copyJob)
1968 if (job == m_getJob)
1975 if (job == m_putJob)
1981 kdWarning(7007) <<
"WARNING ! Get still going on..." << endl;
1991 if (job == d->m_delJob)
1999 bool overwrite,
bool resume,
bool showProgressInfo)
2001 return new FileCopyJob( src, dest, permissions,
false, overwrite, resume, showProgressInfo );
2005 bool overwrite,
bool resume,
bool showProgressInfo)
2007 return new FileCopyJob( src, dest, permissions,
true, overwrite, resume, showProgressInfo );
2012 TDEIO_ARGS << src << TQ_INT8(
true);
2013 return new SimpleJob(src, CMD_DEL, packedArgs, showProgressInfo );
2019 ListJob::ListJob(
const KURL& u,
bool showProgressInfo,
bool _recursive, TQString _prefix,
bool _includeHidden) :
2020 SimpleJob(u, CMD_LISTDIR, TQByteArray(), showProgressInfo),
2021 recursive(_recursive), includeHidden(_includeHidden), prefix(_prefix), m_processedEntries(0)
2025 TQDataStream stream( m_packedArgs, IO_WriteOnly );
2029 void ListJob::slotListEntries(
const TDEIO::UDSEntryList& list )
2032 m_processedEntries += list.count();
2036 UDSEntryListConstIterator it = list.begin();
2037 UDSEntryListConstIterator end = list.end();
2039 for (; it != end; ++it) {
2041 bool isLink =
false;
2044 UDSEntry::ConstIterator it2 = (*it).begin();
2045 UDSEntry::ConstIterator end2 = (*it).end();
2046 for( ; it2 != end2; it2++ ) {
2047 switch( (*it2).m_uds ) {
2049 isDir = S_ISDIR((*it2).m_long);
2052 if( itemURL.isEmpty() ) {
2054 itemURL.addPath( (*it2).m_str );
2058 itemURL = (*it2).m_str;
2062 isLink = !(*it2).m_str.isEmpty();
2068 if (isDir && !isLink) {
2069 const TQString filename = itemURL.fileName();
2071 if (filename !=
".." && filename !=
"." && (includeHidden || filename[0] !=
'.')) {
2075 prefix + filename +
"/",
2079 const TDEIO::UDSEntryList& )),
2081 const TDEIO::UDSEntryList& )));
2091 if (prefix.isNull() && includeHidden) {
2095 UDSEntryList newlist;
2097 UDSEntryListConstIterator it = list.begin();
2098 UDSEntryListConstIterator end = list.end();
2099 for (; it != end; ++it) {
2102 UDSEntry::Iterator it2 = newone.begin();
2104 for( ; it2 != newone.end(); it2++ ) {
2106 filename = (*it2).m_str;
2107 (*it2).m_str = prefix + filename;
2112 if ( (prefix.isNull() || (filename !=
".." && filename !=
".") )
2113 && (includeHidden || (filename[0] !=
'.') ) )
2114 newlist.append(newone);
2121 void ListJob::gotEntries(
TDEIO::Job *,
const TDEIO::UDSEntryList& list )
2134 void ListJob::slotRedirection(
const KURL & url )
2136 if (!kapp->authorizeURLAction(
"redirect", m_url,
url))
2138 kdWarning(7007) <<
"ListJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
2141 m_redirectionURL =
url;
2142 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
2143 m_redirectionURL.setUser(m_url.user());
2147 void ListJob::slotFinished()
2150 if ( m_error == TDEIO::ERR_IS_FILE && m_url.isLocalFile() ) {
2153 TQString proto = ptr->property(
"X-TDE-LocalProtocol").toString();
2155 m_redirectionURL = m_url;
2156 m_redirectionURL.setProtocol( proto );
2162 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) {
2170 m_url = m_redirectionURL;
2171 m_redirectionURL = KURL();
2172 m_packedArgs.truncate(0);
2173 TQDataStream stream( m_packedArgs, IO_WriteOnly );
2184 storeSSLSessionFromJob(m_redirectionURL);
2189 ListJob * job =
new ListJob(url, showProgressInfo,
false,TQString::null,includeHidden);
2195 ListJob * job =
new ListJob(url, showProgressInfo,
true,TQString::null,includeHidden);
2202 extraFlags() |= EF_ListJobUnrestricted;
2204 extraFlags() &= ~EF_ListJobUnrestricted;
2207 void ListJob::start(
Slave *slave)
2209 if (kapp && !kapp->authorizeURLAction(
"list", m_url, m_url) && !(extraFlags() & EF_ListJobUnrestricted))
2211 m_error = ERR_ACCESS_DENIED;
2212 m_errorText = m_url.url();
2213 TQTimer::singleShot(0,
this, TQT_SLOT(slotFinished()) );
2216 connect( slave, TQT_SIGNAL( listEntries(
const TDEIO::UDSEntryList& )),
2217 TQT_SLOT( slotListEntries(
const TDEIO::UDSEntryList& )));
2220 connect( slave, TQT_SIGNAL(
redirection(
const KURL &) ),
2221 TQT_SLOT( slotRedirection(
const KURL &) ) );
2223 SimpleJob::start(slave);
2226 class CopyJob::CopyJobPrivate
2230 m_defaultPermissions =
false;
2231 m_bURLDirty =
false;
2239 CopyJob::DestinationState m_globalDestinationState;
2241 bool m_defaultPermissions;
2246 TQValueList<CopyInfo> m_directoriesCopied;
2250 :
Job(showProgressInfo), m_mode(mode), m_asMethod(asMethod),
2251 destinationState(DEST_NOT_STATED), state(STATE_STATING),
2252 m_totalSize(0), m_processedSize(0), m_fileProcessedSize(0),
2253 m_processedFiles(0), m_processedDirs(0),
2254 m_srcList(src), m_currentStatSrc(m_srcList.begin()),
2255 m_bCurrentOperationIsLink(false), m_bSingleFileCopy(false), m_bOnlyRenames(mode==Move),
2256 m_dest(dest), m_bAutoSkip( false ), m_bOverwriteAll( false ),
2257 m_conflictError(0), m_reportTimer(0)
2259 d =
new CopyJobPrivate;
2260 d->m_globalDest = dest;
2261 d->m_globalDestinationState = destinationState;
2263 if ( showProgressInfo ) {
2270 TQTimer::singleShot(0,
this, TQT_SLOT(
slotStart()));
2299 m_reportTimer =
new TQTimer(
this);
2301 connect(m_reportTimer,TQT_SIGNAL(timeout()),
this,TQT_SLOT(slotReport()));
2302 m_reportTimer->start(REPORT_TIMEOUT,
false);
2311 TDEIO_EXPORT
bool tdeio_resolve_local_urls =
true;
2313 void CopyJob::slotResultStating(
Job *job )
2317 if (job->
error() && destinationState != DEST_NOT_STATED )
2320 if ( !srcurl.isLocalFile() )
2325 kdDebug(7007) <<
"Error while stating source. Activating hack" << endl;
2326 subjobs.remove( job );
2327 assert ( subjobs.isEmpty() );
2328 struct CopyInfo info;
2329 info.permissions = (mode_t) -1;
2330 info.mtime = (time_t) -1;
2331 info.ctime = (time_t) -1;
2333 info.uSource = srcurl;
2334 info.uDest = m_dest;
2336 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2337 info.uDest.addPath( srcurl.fileName() );
2339 files.append( info );
2353 TQString sLocalPath;
2354 UDSEntry::ConstIterator it2 = entry.begin();
2355 for( ; it2 != entry.end(); it2++ ) {
2357 bDir = S_ISDIR( (mode_t)(*it2).m_long );
2359 bLink = !((*it2).m_str.isEmpty());
2360 else if ( ((*it2).m_uds) ==
UDS_NAME )
2361 sName = (*it2).m_str;
2363 sLocalPath = (*it2).m_str;
2366 if ( destinationState == DEST_NOT_STATED )
2370 destinationState = DEST_DOESNT_EXIST;
2373 destinationState = bDir ? DEST_IS_DIR : DEST_IS_FILE;
2376 const bool isGlobalDest = m_dest == d->m_globalDest;
2378 d->m_globalDestinationState = destinationState;
2380 if ( !sLocalPath.isEmpty() && tdeio_resolve_local_urls ) {
2382 m_dest.setPath(sLocalPath);
2384 d->m_globalDest = m_dest;
2387 subjobs.remove( job );
2388 assert ( subjobs.isEmpty() );
2395 m_currentDest = m_dest;
2412 m_bCurrentSrcIsDir =
false;
2413 slotEntries(job, lst);
2416 if (!sLocalPath.isEmpty())
2417 srcurl.setPath(sLocalPath);
2421 subjobs.remove( job );
2422 assert ( subjobs.isEmpty() );
2430 m_bCurrentSrcIsDir =
true;
2431 if ( destinationState == DEST_IS_DIR )
2436 TQString directory = srcurl.fileName();
2437 if ( !sName.isEmpty() && KProtocolInfo::fileNameUsedForCopying( srcurl ) == KProtocolInfo::Name )
2441 m_currentDest.addPath( directory );
2444 else if ( destinationState == DEST_IS_FILE )
2446 m_error = ERR_IS_FILE;
2447 m_errorText = m_dest.prettyURL();
2457 destinationState = DEST_IS_DIR;
2458 if ( m_dest == d->m_globalDest )
2459 d->m_globalDestinationState = destinationState;
2462 startListing( srcurl );
2471 void CopyJob::slotReport()
2476 case STATE_COPYING_FILES:
2478 if (observer) observer->slotProcessedFiles(
this, m_processedFiles);
2482 d->m_bURLDirty =
false;
2485 if (observer) observer->slotMoving(
this, m_currentSrcURL, m_currentDestURL);
2486 emit
moving(
this, m_currentSrcURL, m_currentDestURL);
2488 else if (m_mode==Link)
2490 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2491 emit
linking(
this, m_currentSrcURL.path(), m_currentDestURL );
2495 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2496 emit
copying(
this, m_currentSrcURL, m_currentDestURL );
2501 case STATE_CREATING_DIRS:
2502 if (observer) observer->slotProcessedDirs(
this, m_processedDirs );
2506 d->m_bURLDirty =
false;
2508 if (observer) observer->slotCreatingDir(
this, m_currentDestURL);
2516 d->m_bURLDirty =
false;
2517 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2529 void CopyJob::slotEntries(
TDEIO::Job* job,
const UDSEntryList& list)
2531 UDSEntryListConstIterator it = list.begin();
2532 UDSEntryListConstIterator end = list.end();
2533 for (; it != end; ++it) {
2534 UDSEntry::ConstIterator it2 = (*it).begin();
2535 struct CopyInfo info;
2536 info.permissions = -1;
2537 info.mtime = (time_t) -1;
2538 info.ctime = (time_t) -1;
2540 TQString displayName;
2544 for( ; it2 != (*it).end(); it2++ ) {
2545 switch ((*it2).m_uds) {
2548 isDir = S_ISDIR( (mode_t)((*it2).m_long) );
2551 displayName = (*it2).m_str;
2554 url = KURL((*it2).m_str);
2557 localPath = (*it2).m_str;
2560 info.linkDest = (*it2).m_str;
2563 info.permissions = ((*it2).m_long);
2567 m_totalSize += info.size;
2570 info.mtime = (time_t)((*it2).m_long);
2573 info.ctime = (time_t)((*it2).m_long);
2578 if (displayName !=
".." && displayName !=
".")
2580 bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
2581 if( !hasCustomURL ) {
2584 if ( m_bCurrentSrcIsDir ) {
2586 url.addPath( displayName );
2590 if (!localPath.isEmpty() && tdeio_resolve_local_urls) {
2592 url.setPath(localPath);
2596 info.uDest = m_currentDest;
2599 if ( destinationState == DEST_IS_DIR &&
2602 ( ! ( m_asMethod && state == STATE_STATING ) ) )
2604 TQString destFileName;
2605 if ( hasCustomURL &&
2606 KProtocolInfo::fileNameUsedForCopying( url ) == KProtocolInfo::FromURL ) {
2609 int numberOfSlashes = displayName.contains(
'/' );
2610 TQString path = url.path();
2612 for (
int n = 0; n < numberOfSlashes + 1; ++n ) {
2613 pos = path.findRev(
'/', pos - 1 );
2615 kdWarning(7007) <<
"tdeioslave bug: not enough slashes in UDS_URL " << path <<
" - looking for " << numberOfSlashes <<
" slashes" << endl;
2620 destFileName = path.mid( pos + 1 );
2624 destFileName = displayName;
2630 if ( destFileName.isEmpty() )
2634 info.uDest.addPath( destFileName );
2638 if ( info.linkDest.isEmpty() && isDir && m_mode != Link )
2640 dirs.append( info );
2642 dirsToRemove.append( info.uSource );
2645 files.append( info );
2651 void CopyJob::skipSrc()
2653 m_dest = d->m_globalDest;
2654 destinationState = d->m_globalDestinationState;
2656 skip( m_currentSrcURL );
2660 void CopyJob::statNextSrc()
2666 m_dest = d->m_globalDest;
2667 destinationState = d->m_globalDestinationState;
2672 void CopyJob::statCurrentSrc()
2674 if ( m_currentStatSrc != m_srcList.end() )
2676 m_currentSrcURL = (*m_currentStatSrc);
2677 d->m_bURLDirty =
true;
2678 if ( m_mode == Link )
2681 m_currentDest = m_dest;
2682 struct CopyInfo info;
2683 info.permissions = -1;
2684 info.mtime = (time_t) -1;
2685 info.ctime = (time_t) -1;
2687 info.uSource = m_currentSrcURL;
2688 info.uDest = m_currentDest;
2690 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2693 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
2694 (m_currentSrcURL.host() == info.uDest.host()) &&
2695 (m_currentSrcURL.port() == info.uDest.port()) &&
2696 (m_currentSrcURL.user() == info.uDest.user()) &&
2697 (m_currentSrcURL.pass() == info.uDest.pass()) )
2700 info.uDest.addPath( m_currentSrcURL.fileName() );
2710 files.append( info );
2714 else if ( m_mode == Move && (
2716 KProtocolInfo::fileNameUsedForCopying( m_currentSrcURL ) == KProtocolInfo::FromURL ||
2717 destinationState != DEST_IS_DIR || m_asMethod )
2722 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
2723 (m_currentSrcURL.host() == m_dest.host()) &&
2724 (m_currentSrcURL.port() == m_dest.port()) &&
2725 (m_currentSrcURL.user() == m_dest.user()) &&
2726 (m_currentSrcURL.pass() == m_dest.pass()) )
2728 startRenameJob( m_currentSrcURL );
2731 else if ( m_currentSrcURL.isLocalFile() && KProtocolInfo::canRenameFromFile( m_dest ) )
2733 startRenameJob( m_dest );
2736 else if ( m_dest.isLocalFile() && KProtocolInfo::canRenameToFile( m_currentSrcURL ) )
2738 startRenameJob( m_currentSrcURL );
2745 TQGuardedPtr<CopyJob> that =
this;
2747 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentSrcURL.prettyURL()));
2756 state = STATE_STATING;
2758 m_currentDestURL=m_dest;
2759 m_bOnlyRenames =
false;
2760 d->m_bURLDirty =
true;
2766 state = STATE_STATING;
2767 d->m_bURLDirty =
true;
2769 if (!dirs.isEmpty())
2771 if (!files.isEmpty())
2774 m_bSingleFileCopy = ( files.count() == 1 && dirs.isEmpty() );
2776 state = STATE_CREATING_DIRS;
2781 void CopyJob::startRenameJob(
const KURL& slave_url )
2785 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2786 dest.addPath( m_currentSrcURL.fileName() );
2787 kdDebug(7007) <<
"This seems to be a suitable case for trying to rename before stat+[list+]copy+del" << endl;
2788 state = STATE_RENAMING;
2790 struct CopyInfo info;
2791 info.permissions = -1;
2792 info.mtime = (time_t) -1;
2793 info.ctime = (time_t) -1;
2795 info.uSource = m_currentSrcURL;
2797 TQValueList<CopyInfo> files;
2801 TDEIO_ARGS << m_currentSrcURL << dest << (TQ_INT8)
false ;
2805 if ( m_currentSrcURL.directory() != dest.directory() )
2806 m_bOnlyRenames =
false;
2809 void CopyJob::startListing(
const KURL & src )
2811 state = STATE_LISTING;
2812 d->m_bURLDirty =
true;
2815 connect(newjob, TQT_SIGNAL(entries(
TDEIO::Job *,
2816 const TDEIO::UDSEntryList& )),
2818 const TDEIO::UDSEntryList& )));
2822 void CopyJob::skip(
const KURL & sourceUrl )
2827 KURL::List::Iterator sit = m_srcList.find( sourceUrl );
2828 if ( sit != m_srcList.end() )
2831 m_srcList.remove( sit );
2833 dirsToRemove.remove( sourceUrl );
2836 bool CopyJob::shouldOverwrite(
const TQString& path )
const
2838 if ( m_bOverwriteAll )
2840 TQStringList::ConstIterator sit = m_overwriteList.begin();
2841 for( ; sit != m_overwriteList.end(); ++sit )
2842 if ( path.startsWith( *sit ) )
2847 bool CopyJob::shouldSkip(
const TQString& path )
const
2849 TQStringList::ConstIterator sit = m_skipList.begin();
2850 for( ; sit != m_skipList.end(); ++sit )
2851 if ( path.startsWith( *sit ) )
2856 void CopyJob::slotResultCreatingDirs(
Job * job )
2859 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2863 m_conflictError = job->
error();
2864 if ( (m_conflictError == ERR_DIR_ALREADY_EXIST)
2865 || (m_conflictError == ERR_FILE_ALREADY_EXIST) )
2869 if ( m_bAutoSkip ) {
2871 m_skipList.append( oldURL.path( 1 ) );
2876 const TQString destFile = (*it).uDest.path();
2877 if ( shouldOverwrite( destFile ) ) {
2878 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
2886 assert( ((
SimpleJob*)job)->url().url() == (*it).uDest.url() );
2887 subjobs.remove( job );
2888 assert ( subjobs.isEmpty() );
2891 KURL existingDest( (*it).uDest );
2894 kdDebug(7007) <<
"TDEIO::stat for resolving conflict on " << existingDest << endl;
2895 state = STATE_CONFLICT_CREATING_DIRS;
2911 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
true,
false );
2912 d->m_directoriesCopied.append( *it );
2918 subjobs.remove( job );
2919 assert( subjobs.isEmpty() );
2923 void CopyJob::slotResultConflictCreatingDirs(
TDEIO::Job * job )
2928 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2930 time_t destmtime = (time_t)-1;
2931 time_t destctime = (time_t)-1;
2936 TDEIO::UDSEntry::ConstIterator it2 = entry.begin();
2937 for( ; it2 != entry.end(); it2++ ) {
2938 switch ((*it2).m_uds) {
2940 destmtime = (time_t)((*it2).m_long);
2943 destctime = (time_t)((*it2).m_long);
2946 destsize = (*it2).m_long;
2949 linkDest = (*it2).m_str;
2953 subjobs.remove( job );
2954 assert ( subjobs.isEmpty() );
2957 RenameDlg_Mode mode = (RenameDlg_Mode)( M_MULTI | M_SKIP );
2959 if ( m_conflictError == ERR_DIR_ALREADY_EXIST )
2961 if( (*it).uSource == (*it).uDest ||
2962 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
2963 (*it).uSource.path(-1) == linkDest) )
2964 mode = (RenameDlg_Mode)( mode | M_OVERWRITE_ITSELF);
2966 mode = (RenameDlg_Mode)( mode | M_OVERWRITE );
2969 TQString existingDest = (*it).uDest.path();
2972 m_reportTimer->stop();
2974 (*it).uSource.url(),
2977 (*it).size, destsize,
2978 (*it).ctime, destctime,
2979 (*it).mtime, destmtime );
2981 m_reportTimer->start(REPORT_TIMEOUT,
false);
2984 m_error = ERR_USER_CANCELED;
2989 TQString oldPath = (*it).uDest.path( 1 );
2990 KURL newUrl( (*it).uDest );
2991 newUrl.setPath( newPath );
2992 emit
renamed(
this, (*it).uDest, newUrl );
2995 (*it).uDest.setPath( newUrl.path( -1 ) );
2996 newPath = newUrl.path( 1 );
2997 TQValueList<CopyInfo>::Iterator renamedirit = it;
3000 for( ; renamedirit != dirs.end() ; ++renamedirit )
3002 TQString path = (*renamedirit).uDest.path();
3003 if ( path.left(oldPath.length()) == oldPath ) {
3005 n.replace( 0, oldPath.length(), newPath );
3006 kdDebug(7007) <<
"dirs list: " << (*renamedirit).uSource.path()
3007 <<
" was going to be " << path
3008 <<
", changed into " << n << endl;
3009 (*renamedirit).uDest.setPath( n );
3013 TQValueList<CopyInfo>::Iterator renamefileit = files.begin();
3014 for( ; renamefileit != files.end() ; ++renamefileit )
3016 TQString path = (*renamefileit).uDest.path();
3017 if ( path.left(oldPath.length()) == oldPath ) {
3019 n.replace( 0, oldPath.length(), newPath );
3020 kdDebug(7007) <<
"files list: " << (*renamefileit).uSource.path()
3021 <<
" was going to be " << path
3022 <<
", changed into " << n << endl;
3023 (*renamefileit).uDest.setPath( n );
3026 if (!dirs.isEmpty())
3028 if (!files.isEmpty())
3036 m_skipList.append( existingDest );
3037 skip( (*it).uSource );
3043 m_overwriteList.append( existingDest );
3044 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3049 case R_OVERWRITE_ALL:
3050 m_bOverwriteAll =
true;
3051 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3059 state = STATE_CREATING_DIRS;
3064 void CopyJob::createNextDir()
3067 if ( !dirs.isEmpty() )
3070 TQValueList<CopyInfo>::Iterator it = dirs.begin();
3072 while( it != dirs.end() && udir.isEmpty() )
3074 const TQString dir = (*it).uDest.path();
3075 if ( shouldSkip( dir ) ) {
3082 if ( !udir.isEmpty() )
3089 m_currentDestURL = udir;
3090 d->m_bURLDirty =
true;
3098 if (m_progressId)
Observer::self()->slotProcessedDirs(
this, m_processedDirs );
3100 state = STATE_COPYING_FILES;
3106 void CopyJob::slotResultCopyingFiles(
Job * job )
3109 TQValueList<CopyInfo>::Iterator it = files.begin();
3115 skip( (*it).uSource );
3116 m_fileProcessedSize = (*it).size;
3126 m_conflictError = job->
error();
3128 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3129 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3130 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3132 subjobs.remove( job );
3133 assert ( subjobs.isEmpty() );
3135 KURL existingFile( (*it).uDest );
3138 kdDebug(7007) <<
"TDEIO::stat for resolving conflict on " << existingFile << endl;
3139 state = STATE_CONFLICT_COPYING_FILES;
3145 if ( m_bCurrentOperationIsLink && ::tqqt_cast<TDEIO::DeleteJob*>( job ) )
3149 m_fileProcessedSize = (*it).size;
3153 slotResultConflictCopyingFiles( job );
3161 if ( m_bCurrentOperationIsLink && m_mode == Move
3162 && !::tqqt_cast<TDEIO::DeleteJob *>( job )
3165 subjobs.remove( job );
3166 assert ( subjobs.isEmpty() );
3174 if ( m_bCurrentOperationIsLink )
3176 TQString target = ( m_mode == Link ? (*it).uSource.path() : (*it).linkDest );
3182 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
false,
false );
3189 m_processedSize += m_fileProcessedSize;
3190 m_fileProcessedSize = 0;
3195 assert ( subjobs.isEmpty() );
3199 void CopyJob::slotResultConflictCopyingFiles(
TDEIO::Job * job )
3203 TQValueList<CopyInfo>::Iterator it = files.begin();
3209 m_reportTimer->stop();
3211 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3212 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3213 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3216 time_t destmtime = (time_t)-1;
3217 time_t destctime = (time_t)-1;
3221 TDEIO::UDSEntry::ConstIterator it2 = entry.begin();
3222 for( ; it2 != entry.end(); it2++ ) {
3223 switch ((*it2).m_uds) {
3225 destmtime = (time_t)((*it2).m_long);
3228 destctime = (time_t)((*it2).m_long);
3231 destsize = (*it2).m_long;
3234 linkDest = (*it2).m_str;
3241 RenameDlg_Mode mode;
3244 if( m_conflictError == ERR_DIR_ALREADY_EXIST )
3245 mode = (RenameDlg_Mode) 0;
3248 if ( (*it).uSource == (*it).uDest ||
3249 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
3250 (*it).uSource.path(-1) == linkDest) )
3251 mode = M_OVERWRITE_ITSELF;
3257 if ( m_bSingleFileCopy )
3258 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3260 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3263 i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3264 (*it).uSource.url(),
3267 (*it).size, destsize,
3268 (*it).ctime, destctime,
3269 (*it).mtime, destmtime );
3274 if ( job->
error() == ERR_USER_CANCELED )
3282 SkipDlg_Result skipResult =
Observer::self()->open_SkipDlg(
this, files.count() > 1,
3286 res = ( skipResult == S_SKIP ) ? R_SKIP :
3287 ( skipResult == S_AUTO_SKIP ) ? R_AUTO_SKIP :
3293 m_reportTimer->start(REPORT_TIMEOUT,
false);
3295 subjobs.remove( job );
3296 assert ( subjobs.isEmpty() );
3299 m_error = ERR_USER_CANCELED;
3304 KURL newUrl( (*it).uDest );
3305 newUrl.setPath( newPath );
3306 emit
renamed(
this, (*it).uDest, newUrl );
3307 (*it).uDest = newUrl;
3309 TQValueList<CopyInfo> files;
3319 skip( (*it).uSource );
3320 m_processedSize += (*it).size;
3324 case R_OVERWRITE_ALL:
3325 m_bOverwriteAll =
true;
3329 m_overwriteList.append( (*it).uDest.path() );
3334 state = STATE_COPYING_FILES;
3339 void CopyJob::copyNextFile()
3341 bool bCopyFile =
false;
3344 TQValueList<CopyInfo>::Iterator it = files.begin();
3346 while (it != files.end() && !bCopyFile)
3348 const TQString destFile = (*it).uDest.path();
3349 bCopyFile = !shouldSkip( destFile );
3360 const TQString destFile = (*it).uDest.path();
3361 kdDebug(7007) <<
"copying " << destFile << endl;
3362 if ( (*it).uDest == (*it).uSource )
3365 bOverwrite = shouldOverwrite( destFile );
3367 m_bCurrentOperationIsLink =
false;
3369 if ( m_mode == Link )
3373 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3374 ((*it).uSource.host() == (*it).uDest.host()) &&
3375 ((*it).uSource.port() == (*it).uDest.port()) &&
3376 ((*it).uSource.user() == (*it).uDest.user()) &&
3377 ((*it).uSource.pass() == (*it).uDest.pass()) )
3385 m_bCurrentOperationIsLink =
true;
3386 m_currentSrcURL=(*it).uSource;
3387 m_currentDestURL=(*it).uDest;
3388 d->m_bURLDirty =
true;
3392 if ( (*it).uDest.isLocalFile() )
3394 bool devicesOk=
false;
3397 if ((*it).uSource.protocol()==TQString::fromLatin1(
"devices"))
3402 TQDataStream streamout(param,IO_WriteOnly);
3403 streamout<<(*it).uSource;
3404 streamout<<(*it).uDest;
3405 if ( kapp && kapp->dcopClient()->call(
"kded",
3406 "mountwatcher",
"createLink(KURL, KURL)", param,retType,data,
false ) )
3408 TQDataStream streamin(data,IO_ReadOnly);
3409 streamin>>devicesOk;
3423 TQString path = (*it).uDest.path();
3426 if ( f.open( IO_ReadWrite ) )
3429 KSimpleConfig config( path );
3430 config.setDesktopGroup();
3431 KURL url = (*it).uSource;
3433 config.writePathEntry( TQString::fromLatin1(
"URL"), url.url() );
3434 config.writeEntry( TQString::fromLatin1(
"Name"), url.url() );
3435 config.writeEntry( TQString::fromLatin1(
"Type"), TQString::fromLatin1(
"Link") );
3436 TQString protocol = (*it).uSource.protocol();
3437 if ( protocol == TQString::fromLatin1(
"ftp") )
3438 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"ftp") );
3439 else if ( protocol == TQString::fromLatin1(
"http") )
3440 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"www") );
3441 else if ( protocol == TQString::fromLatin1(
"info") )
3442 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"application-vnd.tde.info") );
3443 else if ( protocol == TQString::fromLatin1(
"mailto") )
3444 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"kmail") );
3446 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"unknown") );
3456 kdDebug(7007) <<
"CopyJob::copyNextFile ERR_CANNOT_OPEN_FOR_WRITING" << endl;
3457 m_error = ERR_CANNOT_OPEN_FOR_WRITING;
3458 m_errorText = (*it).uDest.path();
3465 m_error = ERR_CANNOT_SYMLINK;
3466 m_errorText = (*it).uDest.prettyURL();
3472 else if ( !(*it).linkDest.isEmpty() &&
3473 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3474 ((*it).uSource.host() == (*it).uDest.host()) &&
3475 ((*it).uSource.port() == (*it).uDest.port()) &&
3476 ((*it).uSource.user() == (*it).uDest.user()) &&
3477 ((*it).uSource.pass() == (*it).uDest.pass()))
3485 m_currentSrcURL=(*it).linkDest;
3486 m_currentDestURL=(*it).uDest;
3487 d->m_bURLDirty =
true;
3489 m_bCurrentOperationIsLink =
true;
3491 }
else if (m_mode == Move)
3498 m_currentSrcURL=(*it).uSource;
3499 m_currentDestURL=(*it).uDest;
3500 d->m_bURLDirty =
true;
3508 int permissions = (*it).permissions;
3509 if ( d->m_defaultPermissions || ( remoteSource && (*it).uDest.isLocalFile() ) )
3517 m_currentSrcURL=(*it).uSource;
3518 m_currentDestURL=(*it).uDest;
3519 d->m_bURLDirty =
true;
3535 void CopyJob::deleteNextDir()
3537 if ( m_mode == Move && !dirsToRemove.isEmpty() )
3539 state = STATE_DELETING_DIRS;
3540 d->m_bURLDirty =
true;
3542 KURL::List::Iterator it = dirsToRemove.fromLast();
3545 dirsToRemove.remove(it);
3551 setNextDirAttribute();
3555 void CopyJob::setNextDirAttribute()
3557 if ( !d->m_directoriesCopied.isEmpty() )
3559 state = STATE_SETTING_DIR_ATTRIBUTES;
3562 TQValueList<CopyInfo>::Iterator it = d->m_directoriesCopied.begin();
3563 for ( ; it != d->m_directoriesCopied.end() ; ++it ) {
3564 const KURL& url = (*it).uDest;
3565 if ( url.isLocalFile() && (*it).mtime != (time_t)-1 ) {
3566 const TQCString path = TQFile::encodeName( url.path() );
3567 KDE_struct_stat statbuf;
3568 if (KDE_lstat(path, &statbuf) == 0) {
3569 struct utimbuf utbuf;
3570 utbuf.actime = statbuf.st_atime;
3571 utbuf.modtime = (*it).mtime;
3572 utime( path, &utbuf );
3578 d->m_directoriesCopied.clear();
3585 if ( !m_bOnlyRenames )
3587 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
3588 KURL url( d->m_globalDest );
3589 if ( d->m_globalDestinationState != DEST_IS_DIR || m_asMethod )
3590 url.setPath( url.directory() );
3592 allDirNotify.FilesAdded( url );
3594 if ( m_mode == Move && !m_srcList.isEmpty() ) {
3596 allDirNotify.FilesRemoved( m_srcList );
3600 m_reportTimer->stop();
3611 m_fileProcessedSize = data_size;
3614 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
3616 m_totalSize = m_processedSize + m_fileProcessedSize;
3621 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
3622 emitPercent( m_processedSize + m_fileProcessedSize, m_totalSize );
3632 if ( m_bSingleFileCopy && size > m_totalSize)
3640 void CopyJob::slotResultDeletingDirs(
Job * job )
3648 subjobs.remove( job );
3649 assert ( subjobs.isEmpty() );
3654 void CopyJob::slotResultSettingDirAttributes(
Job * job )
3662 subjobs.remove( job );
3663 assert ( subjobs.isEmpty() );
3664 setNextDirAttribute();
3668 void CopyJob::slotResultRenaming(
Job* job )
3670 int err = job->
error();
3671 const TQString errText = job->
errorText();
3673 assert ( subjobs.isEmpty() );
3676 if ( destinationState == DEST_IS_DIR && !m_asMethod )
3677 dest.addPath( m_currentSrcURL.fileName() );
3683 if ( m_currentSrcURL.isLocalFile() && m_currentSrcURL.url(-1) != dest.url(-1) &&
3684 m_currentSrcURL.url(-1).lower() == dest.url(-1).lower() &&
3685 ( err == ERR_FILE_ALREADY_EXIST ||
3686 err == ERR_DIR_ALREADY_EXIST ||
3687 err == ERR_IDENTICAL_FILES ) )
3689 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;
3690 TQCString _src( TQFile::encodeName(m_currentSrcURL.path()) );
3691 TQCString _dest( TQFile::encodeName(dest.path()) );
3692 KTempFile tmpFile( m_currentSrcURL.directory(
false) );
3693 TQCString _tmp( TQFile::encodeName(tmpFile.name()) );
3694 kdDebug(7007) <<
"CopyJob::slotResult KTempFile status:" << tmpFile.status() <<
" using " << _tmp <<
" as intermediary" << endl;
3696 if ( ::
rename( _src, _tmp ) == 0 )
3698 if ( !TQFile::exists( _dest ) && ::
rename( _tmp, _dest ) == 0 )
3700 kdDebug(7007) <<
"Success." << endl;
3706 if ( ::
rename( _tmp, _src ) != 0 ) {
3707 kdError(7007) <<
"Couldn't rename " << tmpFile.name() <<
" back to " << _src <<
" !" << endl;
3725 Q_ASSERT( m_currentSrcURL == *m_currentStatSrc );
3728 if ( ( err == ERR_DIR_ALREADY_EXIST ||
3729 err == ERR_FILE_ALREADY_EXIST ||
3730 err == ERR_IDENTICAL_FILES )
3734 m_reportTimer->stop();
3737 if ( m_bAutoSkip ) {
3741 }
else if ( m_bOverwriteAll ) {
3746 RenameDlg_Mode mode = (RenameDlg_Mode)
3747 ( ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE );
3749 if ( m_srcList.count() > 1 )
3750 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3752 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3759 time_t ctimeSrc = (time_t) -1;
3760 time_t ctimeDest = (time_t) -1;
3761 time_t mtimeSrc = (time_t) -1;
3762 time_t mtimeDest = (time_t) -1;
3764 KDE_struct_stat stat_buf;
3765 if ( m_currentSrcURL.isLocalFile() &&
3766 KDE_stat(TQFile::encodeName(m_currentSrcURL.path()), &stat_buf) == 0 ) {
3767 sizeSrc = stat_buf.st_size;
3768 ctimeSrc = stat_buf.st_ctime;
3769 mtimeSrc = stat_buf.st_mtime;
3771 if ( dest.isLocalFile() &&
3772 KDE_stat(TQFile::encodeName(dest.path()), &stat_buf) == 0 ) {
3773 sizeDest = stat_buf.st_size;
3774 ctimeDest = stat_buf.st_ctime;
3775 mtimeDest = stat_buf.st_mtime;
3780 err != ERR_DIR_ALREADY_EXIST ? i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3781 m_currentSrcURL.url(),
3785 ctimeSrc, ctimeDest,
3786 mtimeSrc, mtimeDest );
3788 m_reportTimer->start(REPORT_TIMEOUT,
false);
3794 m_error = ERR_USER_CANCELED;
3802 m_dest.setPath( newPath );
3804 state = STATE_STATING;
3805 destinationState = DEST_NOT_STATED;
3816 case R_OVERWRITE_ALL:
3817 m_bOverwriteAll =
true;
3825 kdDebug(7007) <<
"adding to overwrite list: " << dest.path() << endl;
3826 m_overwriteList.append( dest.path() );
3833 }
else if ( err != TDEIO::ERR_UNSUPPORTED_ACTION ) {
3834 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", aborting" << endl;
3836 m_errorText = errText;
3840 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", reverting to normal way, starting with stat" << endl;
3843 state = STATE_STATING;
3845 m_bOnlyRenames =
false;
3850 emit
copyingDone(
this, *m_currentStatSrc, dest,
true,
true );
3855 void CopyJob::slotResult(
Job *job )
3865 slotResultStating( job );
3867 case STATE_RENAMING:
3869 slotResultRenaming( job );
3881 subjobs.remove( job );
3882 assert ( subjobs.isEmpty() );
3886 case STATE_CREATING_DIRS:
3887 slotResultCreatingDirs( job );
3889 case STATE_CONFLICT_CREATING_DIRS:
3890 slotResultConflictCreatingDirs( job );
3892 case STATE_COPYING_FILES:
3893 slotResultCopyingFiles( job );
3895 case STATE_CONFLICT_COPYING_FILES:
3896 slotResultConflictCopyingFiles( job );
3898 case STATE_DELETING_DIRS:
3899 slotResultDeletingDirs( job );
3901 case STATE_SETTING_DIR_ATTRIBUTES:
3912 d->m_defaultPermissions = b;
3925 srcList.append( src );
3926 return new CopyJob( srcList, dest, CopyJob::Copy,
false, showProgressInfo );
3933 srcList.append( src );
3934 return new CopyJob( srcList, dest, CopyJob::Copy,
true, showProgressInfo );
3940 return new CopyJob( src, dest, CopyJob::Copy,
false, showProgressInfo );
3947 srcList.append( src );
3948 return new CopyJob( srcList, dest, CopyJob::Move,
false, showProgressInfo );
3955 srcList.append( src );
3956 return new CopyJob( srcList, dest, CopyJob::Move,
true, showProgressInfo );
3962 return new CopyJob( src, dest, CopyJob::Move,
false, showProgressInfo );
3968 srcList.append( src );
3969 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3974 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3980 srcList.append( src );
3981 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
3987 srcList.append( src );
3988 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
3993 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
3999 :
Job(showProgressInfo), m_totalSize( 0 ), m_processedSize( 0 ), m_fileProcessedSize( 0 ),
4000 m_processedFiles( 0 ), m_processedDirs( 0 ), m_totalFilesDirs( 0 ),
4001 m_srcList(src), m_currentStat(m_srcList.begin()), m_reportTimer(0)
4003 if ( showProgressInfo ) {
4021 m_reportTimer=
new TQTimer(
this);
4022 connect(m_reportTimer,TQT_SIGNAL(timeout()),
this,TQT_SLOT(slotReport()));
4024 m_reportTimer->start(REPORT_TIMEOUT,
false);
4027 TQTimer::singleShot(0,
this, TQT_SLOT(slotStart()));
4030 void DeleteJob::slotStart()
4038 void DeleteJob::slotReport()
4040 if (m_progressId==0)
4045 emit
deleting(
this, m_currentURL );
4046 observer->slotDeleting(
this,m_currentURL);
4055 case STATE_DELETING_DIRS:
4057 observer->slotProcessedDirs(
this,m_processedDirs);
4058 emitPercent( m_processedFiles + m_processedDirs, m_totalFilesDirs );
4060 case STATE_DELETING_FILES:
4061 observer->slotProcessedFiles(
this,m_processedFiles);
4063 emitPercent( m_processedFiles, m_totalFilesDirs );
4069 void DeleteJob::slotEntries(
TDEIO::Job* job,
const UDSEntryList& list)
4071 UDSEntryListConstIterator it = list.begin();
4072 UDSEntryListConstIterator end = list.end();
4073 for (; it != end; ++it)
4075 UDSEntry::ConstIterator it2 = (*it).begin();
4078 TQString displayName;
4081 for( ; it2 != (*it).end(); it2++ )
4083 switch ((*it2).m_uds)
4086 bDir = S_ISDIR((*it2).m_long);
4090 displayName = (*it2).m_str;
4094 url = KURL((*it2).m_str);
4098 bLink = !(*it2).m_str.isEmpty();
4108 if (atomsFound==5)
break;
4110 assert(!displayName.isEmpty());
4111 if (displayName !=
".." && displayName !=
".")
4113 if( url.isEmpty() ) {
4115 url.addPath( displayName );
4119 symlinks.append( url );
4123 files.append( url );
4129 void DeleteJob::statNextSrc()
4132 if ( m_currentStat != m_srcList.end() )
4134 m_currentURL = (*m_currentStat);
4138 TQGuardedPtr<DeleteJob> that =
this;
4141 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentURL.prettyURL()));
4147 state = STATE_STATING;
4156 m_totalFilesDirs = files.count()+symlinks.count() + dirs.count();
4162 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4164 state = STATE_DELETING_FILES;
4169 void DeleteJob::deleteNextFile()
4172 if ( !files.isEmpty() || !symlinks.isEmpty() )
4177 KURL::List::Iterator it = files.begin();
4178 bool isLink =
false;
4179 if ( it == files.end() )
4181 it = symlinks.begin();
4186 if ( (*it).isLocalFile() && unlink( TQFile::encodeName((*it).path()) ) == 0 ) {
4190 if ( m_processedFiles % 300 == 0 || m_totalFilesDirs < 300) {
4201 symlinks.remove(it);
4209 }
while (!job && (!files.isEmpty() || !symlinks.isEmpty()));
4211 state = STATE_DELETING_DIRS;
4215 void DeleteJob::deleteNextDir()
4217 if ( !dirs.isEmpty() )
4221 KURL::List::Iterator it = dirs.fromLast();
4223 if ( (*it).isLocalFile() && ::
rmdir( TQFile::encodeName((*it).path()) ) == 0 ) {
4226 if ( m_processedDirs % 100 == 0 ) {
4232 if ( KProtocolInfo::canDeleteRecursive( *it ) ) {
4245 }
while ( !dirs.isEmpty() );
4249 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4253 if ( !m_srcList.isEmpty() )
4255 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
4257 allDirNotify.FilesRemoved( m_srcList );
4259 if (m_reportTimer!=0)
4260 m_reportTimer->stop();
4270 m_fileProcessedSize = data_size;
4275 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
4278 unsigned long ipercent = m_percent;
4280 if ( m_totalSize == 0 )
4283 m_percent = (
unsigned long)(( (
float)(m_processedSize + m_fileProcessedSize) / (
float)m_totalSize ) * 100.0);
4285 if ( m_percent > ipercent )
4287 emit
percent(
this, m_percent );
4293 void DeleteJob::slotResult(
Job *job )
4312 UDSEntry::ConstIterator it2 = entry.begin();
4314 for( ; it2 != entry.end(); it2++ )
4318 bDir = S_ISDIR( (mode_t)(*it2).m_long );
4323 bLink = !((*it2).m_str.isEmpty());
4326 else if ( ((*it2).m_uds) ==
UDS_SIZE )
4331 if (atomsFound==3)
break;
4336 subjobs.remove( job );
4337 assert( subjobs.isEmpty() );
4343 if ( url.isLocalFile() && !m_parentDirs.contains( url.path(-1) ) )
4344 m_parentDirs.append( url.path(-1) );
4346 if ( !KProtocolInfo::canDeleteRecursive( url ) ) {
4349 state = STATE_LISTING;
4353 connect(newjob, TQT_SIGNAL(entries(
TDEIO::Job *,
4354 const TDEIO::UDSEntryList& )),
4356 const TDEIO::UDSEntryList& )));
4367 symlinks.append( url );
4370 files.append( url );
4372 if ( url.isLocalFile() && !m_parentDirs.contains( url.directory(
false) ) )
4373 m_parentDirs.append( url.directory(
false) );
4384 subjobs.remove( job );
4385 assert( subjobs.isEmpty() );
4389 case STATE_DELETING_FILES:
4395 subjobs.remove( job );
4396 assert( subjobs.isEmpty() );
4401 case STATE_DELETING_DIRS:
4407 subjobs.remove( job );
4408 assert( subjobs.isEmpty() );
4424 srcList.append( src );
4436 bool showProgressInfo)
4437 :
TransferJob(url, 0, TQByteArray(), TQByteArray(), showProgressInfo)
4439 m_waitQueue.setAutoDelete(
true);
4440 m_activeQueue.setAutoDelete(
true);
4446 GetRequest *entry =
new GetRequest(
id,
url,
metaData);
4447 entry->metaData[
"request-id"] = TQString(
"%1").arg(
id);
4448 m_waitQueue.append(entry);
4451 void MultiGetJob::flushQueue(TQPtrList<GetRequest> &queue)
4456 for(entry = m_waitQueue.first(); entry; )
4458 if ((m_url.protocol() == entry->url.protocol()) &&
4459 (m_url.host() == entry->url.host()) &&
4460 (m_url.port() == entry->url.port()) &&
4461 (m_url.user() == entry->url.user()))
4464 queue.append(entry);
4465 entry = m_waitQueue.current();
4469 entry = m_waitQueue.next();
4473 TDEIO_ARGS << (TQ_INT32) queue.count();
4474 for(entry = queue.first(); entry; entry = queue.next())
4476 stream << entry->url << entry->metaData;
4478 m_packedArgs = packedArgs;
4479 m_command = CMD_MULTI_GET;
4480 m_outgoingMetaData.clear();
4483 void MultiGetJob::start(
Slave *slave)
4486 GetRequest *entry = m_waitQueue.take(0);
4487 m_activeQueue.append(entry);
4491 if (!entry->url.protocol().startsWith(
"http"))
4494 TDEIO_ARGS << entry->url;
4495 m_packedArgs = packedArgs;
4496 m_outgoingMetaData = entry->metaData;
4497 m_command = CMD_GET;
4498 b_multiGetActive =
false;
4502 flushQueue(m_activeQueue);
4503 b_multiGetActive =
true;
4506 TransferJob::start(slave);
4509 bool MultiGetJob::findCurrentEntry()
4511 if (b_multiGetActive)
4513 long id = m_incomingMetaData[
"request-id"].toLong();
4514 for(GetRequest *entry = m_activeQueue.first(); entry; entry = m_activeQueue.next())
4516 if (entry->id ==
id)
4518 m_currentEntry = entry;
4527 m_currentEntry = m_activeQueue.first();
4528 return (m_currentEntry != 0);
4532 void MultiGetJob::slotRedirection(
const KURL &url)
4534 if (!findCurrentEntry())
return;
4535 if (kapp && !kapp->authorizeURLAction(
"redirect", m_url,
url))
4537 kdWarning(7007) <<
"MultiGetJob: Redirection from " << m_currentEntry->url <<
" to " <<
url <<
" REJECTED!" << endl;
4540 m_redirectionURL =
url;
4541 if (m_currentEntry->url.hasUser() && !
url.hasUser() && (m_currentEntry->url.host().lower() ==
url.host().lower()))
4542 m_redirectionURL.setUser(m_currentEntry->url.user());
4543 get(m_currentEntry->id, m_redirectionURL, m_currentEntry->metaData);
4547 void MultiGetJob::slotFinished()
4549 if (!findCurrentEntry())
return;
4550 if (m_redirectionURL.isEmpty())
4553 emit
result(m_currentEntry->id);
4555 m_redirectionURL = KURL();
4557 m_incomingMetaData.clear();
4558 m_activeQueue.removeRef(m_currentEntry);
4559 if (m_activeQueue.count() == 0)
4561 if (m_waitQueue.count() == 0)
4564 TransferJob::slotFinished();
4571 GetRequest *entry = m_waitQueue.at(0);
4579 void MultiGetJob::slotData(
const TQByteArray &_data)
4581 if(!m_currentEntry)
return;
4582 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
4583 emit
data(m_currentEntry->id, _data);
4586 void MultiGetJob::slotMimetype(
const TQString &_mimetype )
4588 if (b_multiGetActive)
4590 TQPtrList<GetRequest> newQueue;
4591 flushQueue(newQueue);
4592 if (!newQueue.isEmpty())
4594 while(!newQueue.isEmpty())
4595 m_activeQueue.append(newQueue.take(0));
4596 m_slave->
send( m_command, m_packedArgs );
4599 if (!findCurrentEntry())
return;
4600 emit
mimetype(m_currentEntry->id, _mimetype);
4606 job->
get(
id, url, metaData);
4612 CacheInfo::CacheInfo(
const KURL &url)
4617 TQString CacheInfo::cachedFileName()
4619 const TQChar separator =
'_';
4621 TQString CEF = m_url.path();
4623 int p = CEF.find(
'/');
4628 p = CEF.find(
'/', p);
4631 TQString host = m_url.host().lower();
4632 CEF = host + CEF +
'_';
4635 if (dir[dir.length()-1] !=
'/')
4638 int l = m_url.host().length();
4639 for(
int i = 0; i < l; i++)
4641 if (host[i].isLetter() && (host[i] !=
'w'))
4647 if (dir[dir.length()-1] ==
'/')
4650 unsigned long hash = 0x00000000;
4651 TQCString u = m_url.url().latin1();
4652 for(
int i = u.length(); i--;)
4654 hash = (hash * 12211 + u[i]) % 2147483563;
4657 TQString hashString;
4658 hashString.sprintf(
"%08lx", hash);
4660 CEF = CEF + hashString;
4662 CEF = dir +
"/" + CEF;
4667 TQFile *CacheInfo::cachedFile()
4670 const char *mode = (readWrite ?
"rb+" :
"rb");
4672 const char *mode = (readWrite ?
"r+" :
"r");
4675 FILE *fs = fopen(TQFile::encodeName(CEF), mode);
4683 if (ok && (!fgets(buffer, 400, fs)))
4685 if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
4689 time_t currentDate = time(0);
4692 if (ok && (!fgets(buffer, 400, fs)))
4696 int l = strlen(buffer);
4699 if (m_.url.url() != buffer)
4706 if (ok && (!fgets(buffer, 400, fs)))
4710 date = (time_t) strtoul(buffer, 0, 10);
4711 if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge))
4713 m_bMustRevalidate =
true;
4714 m_expireDate = currentDate;
4719 m_cacheExpireDateOffset = ftell(fs);
4720 if (ok && (!fgets(buffer, 400, fs)))
4726 date = (time_t) strtoul(buffer, 0, 10);
4728 if (!date || difftime(currentDate, date) >= 0)
4729 m_bMustRevalidate =
true;
4730 m_expireDate = date;
4735 if (ok && (!fgets(buffer, 400, fs)))
4739 m_etag = TQString(buffer).stripWhiteSpace();
4743 if (ok && (!fgets(buffer, 400, fs)))
4747 m_lastModified = TQString(buffer).stripWhiteSpace();
4755 unlink( TQFile::encodeName(CEF) );
4760 void CacheInfo::flush()
4762 cachedFile().remove();
4765 void CacheInfo::touch()
4769 void CacheInfo::setExpireDate(
int);
4770 void CacheInfo::setExpireTimeout(
int);
4773 int CacheInfo::creationDate();
4774 int CacheInfo::expireDate();
4775 int CacheInfo::expireTimeout();
4778 void Job::virtual_hook(
int,
void* )
4781 void SimpleJob::virtual_hook(
int id,
void* data )
4782 { TDEIO::Job::virtual_hook(
id, data ); }
4784 void MkdirJob::virtual_hook(
int id,
void* data )
4785 { SimpleJob::virtual_hook(
id, data ); }
4787 void StatJob::virtual_hook(
int id,
void* data )
4788 { SimpleJob::virtual_hook(
id, data ); }
4790 void TransferJob::virtual_hook(
int id,
void* data )
4791 { SimpleJob::virtual_hook(
id,
data ); }
4793 void MultiGetJob::virtual_hook(
int id,
void* data )
4794 { TransferJob::virtual_hook(
id,
data ); }
4796 void MimetypeJob::virtual_hook(
int id,
void* data )
4797 { TransferJob::virtual_hook(
id,
data ); }
4799 void FileCopyJob::virtual_hook(
int id,
void* data )
4800 { Job::virtual_hook(
id, data ); }
4802 void ListJob::virtual_hook(
int id,
void* data )
4803 { SimpleJob::virtual_hook(
id, data ); }
4805 void CopyJob::virtual_hook(
int id,
void* data )
4806 { Job::virtual_hook(
id, data ); }
4808 void DeleteJob::virtual_hook(
int id,
void* data )
4809 { Job::virtual_hook(
id, data ); }
4811 void LocalURLJob::virtual_hook(
int id,
void* data )
4812 { Job::virtual_hook(
id, data ); }
4815 #include "jobclasses.moc"