22 #include "tdeio/job.h"
26 #include <sys/types.h>
44 #include <tdeapplication.h>
45 #include <tdeglobal.h>
46 #include <tdelocale.h>
47 #include <tdesimpleconfig.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_errorParentWidgetGP(0), m_parentJob(0L),
94 m_extraFlags(0), m_processedSize(0), m_userTimestamp(0)
99 if (m_errorParentWidgetGP)
101 delete m_errorParentWidgetGP;
105 bool m_autoErrorHandling;
106 bool m_autoWarningHandling;
108 TQGuardedPtr<TQWidget> *m_errorParentWidgetGP;
114 unsigned long m_userTimestamp;
117 static TQObject *__job_root_obj =
nullptr;
119 static TQObject* __getJobRoot()
123 __job_root_obj =
new TQObject(0,
"jobroot");
125 return __job_root_obj;
128 Job::Job(
bool showProgressInfo) : TQObject(__getJobRoot(),
"job"), m_error(0), m_percent(0)
129 , m_progressId(0), m_speedTimer(0), d( new JobPrivate )
134 if ( showProgressInfo )
137 addMetaData(
"progress-id", TQString::number(m_progressId));
140 connect(
this, TQ_SIGNAL( percent(
TDEIO::Job*,
unsigned long ) ),
142 connect(
this, TQ_SIGNAL( infoMessage(
TDEIO::Job*,
const TQString & ) ),
148 connect(
this, TQ_SIGNAL( speed(
TDEIO::Job*,
unsigned long ) ),
155 updateUserTimestamp( tdeApp->userTimestamp());
168 int& Job::extraFlags()
170 return d->m_extraFlags;
175 d->m_processedSize = size;
180 return d->m_processedSize;
215 m_incomingMetaData += job->
metaData();
217 if ( subjobs.isEmpty() && emitResultIfLast )
224 unsigned long ipercent = m_percent;
231 if ( m_percent != ipercent || m_percent == 100 ) {
232 emit
percent(
this, m_percent );
242 m_speedTimer =
new TQTimer();
243 connect( m_speedTimer, TQ_SIGNAL( timeout() ), TQ_SLOT(
slotSpeedTimeout() ) );
245 emit
speed(
this, bytes_per_second );
246 m_speedTimer->start( 5000 );
254 if ( m_error && d->m_interactive && d->m_autoErrorHandling )
255 showErrorDialog( d->m_errorParentWidgetGP ? *d->m_errorParentWidgetGP :
nullptr);
262 kdDebug(7007) <<
"Job::kill this=" <<
this <<
" " << className() <<
" m_progressId=" << m_progressId <<
" quietly=" << quietly << endl;
264 TQPtrListIterator<Job> it( subjobs );
265 for ( ; it.current() ; ++it )
270 m_error = ERR_USER_CANCELED;
284 if ( job->
error() && !m_error )
287 m_error = job->
error();
309 emit
speed(
this, 0 );
310 m_speedTimer->stop();
318 tdeApp->enableStyles();
320 if ( (m_error != ERR_USER_CANCELED) && (m_error != ERR_NO_CONTENT) ) {
324 KMessageBox::queuedMessageBox( parent, KMessageBox::Error,
errorString() );
328 TQString caption, err, detail;
329 TQStringList::const_iterator it = errors.begin();
330 if ( it != errors.end() )
332 if ( it != errors.end() )
334 if ( it != errors.end() )
336 KMessageBox::queuedDetailedError( parent, err, detail, caption );
342 void Job::setAutoErrorHandlingEnabled(
bool enable, TQWidget *parentWidget )
344 if (d->m_errorParentWidgetGP && (TQWidget*)(*d->m_errorParentWidgetGP) != parentWidget)
346 delete d->m_errorParentWidgetGP;
347 d->m_errorParentWidgetGP =
nullptr;
349 d->m_autoErrorHandling = enable;
350 if (enable && parentWidget && !d->m_errorParentWidgetGP)
352 d->m_errorParentWidgetGP =
new TQGuardedPtr<TQWidget>(parentWidget);
358 return d->m_autoErrorHandling;
363 d->m_autoWarningHandling = enable;
368 return d->m_autoWarningHandling;
373 d->m_interactive = enable;
378 return d->m_interactive;
394 #if defined TQ_WS_X11
395 if( d->m_userTimestamp == 0 || NET::timestampCompare( time, d->m_userTimestamp ) > 0 )
396 d->m_userTimestamp = time;
400 unsigned long Job::userTimestamp()
const
402 return d->m_userTimestamp;
407 Q_ASSERT(d->m_parentJob == 0L);
409 d->m_parentJob = job;
414 return d->m_parentJob;
419 return m_incomingMetaData;
424 if (!m_incomingMetaData.contains(key))
425 return TQString::null;
426 return m_incomingMetaData[key];
431 m_outgoingMetaData = _metaData;
436 m_outgoingMetaData.insert(key, value);
441 TQMapConstIterator<TQString,TQString> it = values.begin();
442 for(;it != values.end(); ++it)
443 m_outgoingMetaData.insert(it.key(), it.data());
448 TQMapConstIterator<TQString,TQString> it = values.begin();
449 for(;it != values.end(); ++it)
450 m_outgoingMetaData.insert(it.key(), it.data(),
false);
453 MetaData Job::outgoingMetaData()
const
455 return m_outgoingMetaData;
460 bool showProgressInfo )
461 :
Job(showProgressInfo), m_slave(0), m_packedArgs(packedArgs),
462 m_url(url), m_command(command), m_totalSize(0)
464 if (m_url.hasSubURL())
466 KURL::List list = KURL::split(m_url);
467 KURL::List::Iterator it = list.fromLast();
469 m_subUrl = KURL::join(list);
476 if (!m_url.isValid())
478 kdDebug() <<
"ERR_MALFORMED_URL" << endl;
479 m_error = ERR_MALFORMED_URL;
480 m_errorText = m_url.url();
509 SimpleJob::~SimpleJob()
513 kdDebug(7007) <<
"SimpleJob::~SimpleJob: Killing running job in destructor!" << endl;
523 void SimpleJob::start(
Slave *slave)
527 connect( m_slave, TQ_SIGNAL(
error(
int ,
const TQString & ) ),
528 TQ_SLOT( slotError(
int ,
const TQString & ) ) );
530 connect( m_slave, TQ_SIGNAL(
warning(
const TQString & ) ),
531 TQ_SLOT( slotWarning(
const TQString & ) ) );
533 connect( m_slave, TQ_SIGNAL(
infoMessage(
const TQString & ) ),
536 connect( m_slave, TQ_SIGNAL(
connected() ),
539 connect( m_slave, TQ_SIGNAL( finished() ),
542 if ((extraFlags() & EF_TransferJobDataSent) == 0)
550 connect( m_slave, TQ_SIGNAL(
speed(
unsigned long ) ),
554 connect( slave, TQ_SIGNAL( needProgressId() ),
555 TQ_SLOT( slotNeedProgressId() ) );
563 addMetaData(
"window-id",
id.setNum((ulong)m_window->winId()));
568 addMetaData(
"user-timestamp",
id.setNum(userTimestamp()));
571 TQString sslSession = KSSLCSessionCache::getSessionForURL(m_url);
572 if ( !sslSession.isNull() )
582 if (!m_outgoingMetaData.isEmpty())
584 TDEIO_ARGS << m_outgoingMetaData;
585 slave->
send( CMD_META_DATA, packedArgs );
588 if (!m_subUrl.isEmpty())
590 TDEIO_ARGS << m_subUrl;
591 m_slave->
send( CMD_SUBURL, packedArgs );
594 m_slave->
send( m_command, m_packedArgs );
597 void SimpleJob::slaveDone()
599 if (!m_slave)
return;
610 if (subjobs.isEmpty())
612 if ( !m_error && (m_command == CMD_MKDIR || m_command == CMD_RENAME ) )
614 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*" );
615 if ( m_command == CMD_MKDIR )
617 KURL urlDir(
url() );
618 urlDir.setPath( urlDir.directory() );
619 allDirNotify.FilesAdded( urlDir );
624 TQDataStream str( m_packedArgs, IO_ReadOnly );
626 if ( src.directory() == dst.directory() )
627 allDirNotify.FileRenamed( src, dst );
634 void SimpleJob::slotError(
int error,
const TQString & errorText )
638 if ((m_error == ERR_UNKNOWN_HOST) && m_url.host().isEmpty())
639 m_errorText = TQString::null;
644 void SimpleJob::slotWarning(
const TQString & errorText )
646 TQGuardedPtr<SimpleJob> guard(
this );
649 static uint msgBoxDisplayed = 0;
650 if ( msgBoxDisplayed == 0 )
653 KMessageBox::information( 0L,
errorText );
659 if ( !guard.isNull() )
673 void SimpleJob::slotNeedProgressId()
677 m_slave->setProgressId( m_progressId );
682 if (size > m_totalSize)
694 if ( size > m_totalSize ) {
708 m_incomingMetaData += _metaData;
711 void SimpleJob::storeSSLSessionFromJob(
const KURL &m_redirectionURL) {
714 if ( !sslSession.isNull() ) {
715 const KURL &queryURL = m_redirectionURL.isEmpty()?m_url:m_redirectionURL;
716 KSSLCSessionCache::putSessionForURL(queryURL, sslSession);
722 const TQByteArray &packedArgs,
bool showProgressInfo )
723 :
SimpleJob(url, command, packedArgs, showProgressInfo)
727 void MkdirJob::start(
Slave *slave)
729 connect( slave, TQ_SIGNAL(
redirection(
const KURL &) ),
730 TQ_SLOT( slotRedirection(
const KURL &) ) );
732 SimpleJob::start(slave);
736 void MkdirJob::slotRedirection(
const KURL &url)
738 kdDebug(7007) <<
"MkdirJob::slotRedirection(" <<
url <<
")" << endl;
739 if (!tdeApp->authorizeURLAction(
"redirect", m_url,
url))
741 kdWarning(7007) <<
"MkdirJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
742 m_error = ERR_ACCESS_DENIED;
743 m_errorText =
url.prettyURL();
746 m_redirectionURL =
url;
747 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
748 m_redirectionURL.setUser(m_url.user());
753 void MkdirJob::slotFinished()
755 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
765 TQDataStream istream( m_packedArgs, IO_ReadOnly );
766 istream >> dummyUrl >> permissions;
768 m_url = m_redirectionURL;
769 m_redirectionURL = KURL();
770 m_packedArgs.truncate(0);
771 TQDataStream stream( m_packedArgs, IO_WriteOnly );
772 stream << m_url << permissions;
783 TDEIO_ARGS << url << permissions;
784 return new MkdirJob(url, CMD_MKDIR, packedArgs,
false);
790 TDEIO_ARGS << url << TQ_INT8(
false);
791 return new SimpleJob(url, CMD_DEL, packedArgs,
false);
797 TDEIO_ARGS << url << permissions;
798 return new SimpleJob(url, CMD_CHMOD, packedArgs,
false);
804 TDEIO_ARGS << src << dest << (TQ_INT8) overwrite;
805 return new SimpleJob(src, CMD_RENAME, packedArgs,
false);
811 TDEIO_ARGS << target << dest << (TQ_INT8) overwrite;
812 return new SimpleJob(dest, CMD_SYMLINK, packedArgs, showProgressInfo);
818 return new SimpleJob(url, CMD_SPECIAL, data, showProgressInfo);
821 SimpleJob *
TDEIO::mount(
bool ro,
const char *fstype,
const TQString& dev,
const TQString& point,
bool showProgressInfo )
823 TDEIO_ARGS << int(1) << TQ_INT8( ro ? 1 : 0 )
824 << TQString::fromLatin1(fstype) << dev << point;
826 if ( showProgressInfo )
833 TDEIO_ARGS << int(2) << point;
835 if ( showProgressInfo )
842 const TQByteArray &packedArgs,
bool showProgressInfo )
843 :
SimpleJob(url, command, packedArgs, showProgressInfo)
848 void LocalURLJob::start(
Slave *slave)
850 connect( slave, TQ_SIGNAL(
localURL(
const KURL &,
bool) ),
851 TQ_SLOT( slotLocalURL(
const KURL &,
bool) ) );
853 SimpleJob::start(slave);
857 void LocalURLJob::slotLocalURL(
const KURL &url,
bool isLocal)
859 kdDebug(7007) <<
"LocalURLJob::slotLocalURL(" <<
url <<
")" << endl;
864 void LocalURLJob::slotFinished()
872 TDEIO_ARGS << remoteUrl;
873 return new LocalURLJob(remoteUrl, CMD_LOCALURL, packedArgs,
false);
880 const TQByteArray &packedArgs,
bool showProgressInfo )
881 :
SimpleJob(url, command, packedArgs, showProgressInfo),
882 m_bSource(true), m_details(2)
886 void StatJob::start(
Slave *slave)
888 m_outgoingMetaData.replace(
"statSide", m_bSource ?
"source" :
"dest" );
889 m_outgoingMetaData.replace(
"details", TQString::number(m_details) );
893 connect( slave, TQ_SIGNAL(
redirection(
const KURL &) ),
894 TQ_SLOT( slotRedirection(
const KURL &) ) );
896 SimpleJob::start(slave);
902 m_statResult = entry;
906 void StatJob::slotRedirection(
const KURL &url)
908 kdDebug(7007) <<
"StatJob::slotRedirection(" <<
url <<
")" << endl;
909 if (!tdeApp->authorizeURLAction(
"redirect", m_url,
url))
911 kdWarning(7007) <<
"StatJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
912 m_error = ERR_ACCESS_DENIED;
913 m_errorText =
url.prettyURL();
916 m_redirectionURL =
url;
917 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
918 m_redirectionURL.setUser(m_url.user());
923 void StatJob::slotFinished()
925 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
933 m_url = m_redirectionURL;
934 m_redirectionURL = KURL();
935 m_packedArgs.truncate(0);
936 TQDataStream stream( m_packedArgs, IO_WriteOnly );
947 storeSSLSessionFromJob(m_redirectionURL);
953 return stat( url,
true, 2, showProgressInfo );
958 kdDebug(7007) <<
"stat " << url << endl;
960 StatJob * job =
new StatJob(url, CMD_STAT, packedArgs, showProgressInfo );
963 if ( showProgressInfo )
970 assert( (url.protocol() ==
"http") || (url.protocol() ==
"https") );
972 TDEIO_ARGS << (int)2 << url << no_cache << expireDate;
981 const TQByteArray &packedArgs,
982 const TQByteArray &_staticData,
983 bool showProgressInfo)
984 :
SimpleJob(url, command, packedArgs, showProgressInfo), staticData( _staticData)
989 if ( showProgressInfo )
994 void TransferJob::slotData(
const TQByteArray &_data)
996 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
997 emit
data(
this, _data);
1001 void TransferJob::slotRedirection(
const KURL &url)
1003 kdDebug(7007) <<
"TransferJob::slotRedirection(" <<
url <<
")" << endl;
1004 if (!tdeApp->authorizeURLAction(
"redirect", m_url,
url))
1006 kdWarning(7007) <<
"TransferJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
1013 if (m_redirectionList.contains(
url) > 5)
1015 kdDebug(7007) <<
"TransferJob::slotRedirection: CYCLIC REDIRECTION!" << endl;
1016 m_error = ERR_CYCLIC_LINK;
1017 m_errorText = m_url.prettyURL();
1021 m_redirectionURL =
url;
1022 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
1023 m_redirectionURL.setUser(m_url.user());
1024 m_redirectionList.append(
url);
1025 m_outgoingMetaData[
"ssl_was_in_use"] = m_incomingMetaData[
"ssl_in_use"];
1031 void TransferJob::slotFinished()
1034 if (m_redirectionURL.isEmpty() || !m_redirectionURL.isValid())
1044 staticData.truncate(0);
1045 m_incomingMetaData.clear();
1048 m_suspended =
false;
1049 m_url = m_redirectionURL;
1050 m_redirectionURL = KURL();
1054 TQDataStream istream( m_packedArgs, IO_ReadOnly );
1055 switch( m_command ) {
1057 m_packedArgs.truncate(0);
1058 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1064 TQ_INT8 iOverwrite, iResume;
1065 istream >> dummyUrl >> iOverwrite >> iResume >> permissions;
1066 m_packedArgs.truncate(0);
1067 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1068 stream << m_url << iOverwrite << iResume << permissions;
1073 istream >> specialcmd;
1074 if (specialcmd == 1)
1077 m_packedArgs.truncate(0);
1078 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1080 m_command = CMD_GET;
1095 extraFlags() |= EF_TransferJobAsync;
1097 extraFlags() &= ~EF_TransferJobAsync;
1102 if (extraFlags() & EF_TransferJobNeedData)
1104 m_slave->
send( MSG_DATA, dataForSlave );
1105 if (extraFlags() & EF_TransferJobDataSent)
1110 if ( size > m_totalSize ) {
1117 extraFlags() &= ~EF_TransferJobNeedData;
1123 extraFlags() |= EF_TransferJobDataSent;
1125 extraFlags() &= ~EF_TransferJobDataSent;
1130 return (extraFlags() & EF_TransferJobDataSent);
1135 void TransferJob::slotDataReq()
1137 TQByteArray dataForSlave;
1139 extraFlags() |= EF_TransferJobNeedData;
1141 if (!staticData.isEmpty())
1143 dataForSlave = staticData;
1144 staticData = TQByteArray();
1148 emit
dataReq(
this, dataForSlave);
1150 if (extraFlags() & EF_TransferJobAsync)
1154 static const size_t max_size = 14 * 1024 * 1024;
1155 if (dataForSlave.size() > max_size)
1157 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";
1158 staticData.duplicate(dataForSlave.data() + max_size , dataForSlave.size() - max_size);
1159 dataForSlave.truncate(max_size);
1172 void TransferJob::slotMimetype(
const TQString& type )
1188 m_suspended =
false;
1193 void TransferJob::start(
Slave *slave)
1196 connect( slave, TQ_SIGNAL(
data(
const TQByteArray & ) ),
1197 TQ_SLOT( slotData(
const TQByteArray & ) ) );
1199 connect( slave, TQ_SIGNAL(
dataReq() ),
1200 TQ_SLOT( slotDataReq() ) );
1202 connect( slave, TQ_SIGNAL(
redirection(
const KURL &) ),
1203 TQ_SLOT( slotRedirection(
const KURL &) ) );
1205 connect( slave, TQ_SIGNAL(mimeType(
const TQString& ) ),
1206 TQ_SLOT( slotMimetype(
const TQString& ) ) );
1208 connect( slave, TQ_SIGNAL(errorPage() ),
1209 TQ_SLOT( slotErrorPage() ) );
1211 connect( slave, TQ_SIGNAL( needSubURLData() ),
1212 TQ_SLOT( slotNeedSubURLData() ) );
1219 m_mimetype =
"unknown";
1224 SimpleJob::start(slave);
1229 void TransferJob::slotNeedSubURLData()
1232 m_subJob =
TDEIO::get( m_subUrl,
false,
false);
1234 connect(m_subJob, TQ_SIGNAL(
data(
TDEIO::Job*,
const TQByteArray &)),
1235 TQ_SLOT( slotSubURLData(
TDEIO::Job*,
const TQByteArray &)));
1239 void TransferJob::slotSubURLData(
TDEIO::Job*,
const TQByteArray &data)
1249 storeSSLSessionFromJob(m_redirectionURL);
1252 void TransferJob::slotErrorPage()
1259 emit canResume(
this, offset);
1265 assert(job == m_subJob);
1269 m_error = job->
error();
1276 if (job == m_subJob)
1298 PostErrorJob(
int _error,
const TQString& url,
const TQByteArray &packedArgs,
const TQByteArray &postData,
bool showProgressInfo)
1299 :
TransferJob(KURL(), CMD_SPECIAL, packedArgs, postData, showProgressInfo)
1312 static const int bad_ports[] = {
1374 for (
int cnt=0; bad_ports[cnt]; ++cnt)
1375 if (url.port() == bad_ports[cnt])
1377 _error = TDEIO::ERR_POST_DENIED;
1383 static bool override_loaded =
false;
1384 static TQValueList< int >* overriden_ports = NULL;
1385 if( !override_loaded )
1387 TDEConfig cfg(
"tdeio_httprc",
true );
1388 overriden_ports =
new TQValueList< int >;
1389 *overriden_ports = cfg.readIntListEntry(
"OverriddenPorts" );
1390 override_loaded =
true;
1392 for( TQValueList< int >::ConstIterator it = overriden_ports->begin();
1393 it != overriden_ports->end();
1395 if( overriden_ports->contains( url.port()))
1400 if ((url.protocol() !=
"http") && (url.protocol() !=
"https" ))
1401 _error = TDEIO::ERR_POST_DENIED;
1403 bool redirection =
false;
1405 if (_url.path().isEmpty())
1411 if (!_error && !tdeApp->authorizeURLAction(
"open", KURL(), _url))
1412 _error = TDEIO::ERR_ACCESS_DENIED;
1417 TDEIO_ARGS << (int)1 << url;
1418 TransferJob * job =
new PostErrorJob(_error, url.prettyURL(), packedArgs, postData, showProgressInfo);
1423 TDEIO_ARGS << (int)1 << _url;
1425 packedArgs, postData, showProgressInfo );
1428 TQTimer::singleShot(0, job, TQ_SLOT(slotPostRedirection()) );
1436 void TransferJob::slotPostRedirection()
1438 kdDebug(7007) <<
"TransferJob::slotPostRedirection(" << m_url <<
")" << endl;
1445 bool overwrite,
bool resume,
bool showProgressInfo )
1447 TDEIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1455 const TQByteArray &packedArgs,
1456 const TQByteArray &_staticData,
1457 bool showProgressInfo)
1458 :
TransferJob( url, command, packedArgs, _staticData, showProgressInfo ),
1461 connect(
this, TQ_SIGNAL(
data(
TDEIO::Job *,
const TQByteArray & ) ),
1462 TQ_SLOT( slotStoredData(
TDEIO::Job *,
const TQByteArray & ) ) );
1464 TQ_SLOT( slotStoredDataReq(
TDEIO::Job *, TQByteArray & ) ) );
1469 Q_ASSERT( m_data.isNull() );
1470 Q_ASSERT( m_uploadOffset == 0 );
1474 void StoredTransferJob::slotStoredData(
TDEIO::Job *,
const TQByteArray &data )
1477 if (
data.size() == 0 )
1479 unsigned int oldSize = m_data.size();
1480 m_data.resize( oldSize +
data.size(), TQGArray::SpeedOptim );
1481 memcpy( m_data.data() + oldSize,
data.data(),
data.size() );
1484 void StoredTransferJob::slotStoredDataReq(
TDEIO::Job *, TQByteArray &data )
1488 const int MAX_CHUNK_SIZE = 64*1024;
1489 int remainingBytes = m_data.size() - m_uploadOffset;
1490 if( remainingBytes > MAX_CHUNK_SIZE ) {
1492 data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
1493 m_uploadOffset += MAX_CHUNK_SIZE;
1498 data.duplicate( m_data.data() + m_uploadOffset, remainingBytes );
1499 m_data = TQByteArray();
1516 bool overwrite,
bool resume,
bool showProgressInfo )
1518 TDEIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions;
1527 const TQByteArray &packedArgs,
bool showProgressInfo )
1528 :
TransferJob(url, command, packedArgs, TQByteArray(), showProgressInfo)
1532 void MimetypeJob::start(
Slave *slave)
1534 TransferJob::start(slave);
1538 void MimetypeJob::slotFinished( )
1541 if ( m_error == TDEIO::ERR_IS_DIRECTORY )
1546 kdDebug(7007) <<
"It is in fact a directory!" << endl;
1547 m_mimetype = TQString::fromLatin1(
"inode/directory");
1551 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error )
1554 TransferJob::slotFinished();
1559 staticData.truncate(0);
1560 m_suspended =
false;
1561 m_url = m_redirectionURL;
1562 m_redirectionURL = KURL();
1563 m_packedArgs.truncate(0);
1564 TQDataStream stream( m_packedArgs, IO_WriteOnly );
1577 if ( showProgressInfo )
1584 DirectCopyJob::DirectCopyJob(
const KURL& url,
int command,
1585 const TQByteArray &packedArgs,
bool showProgressInfo )
1586 :
SimpleJob(url, command, packedArgs, showProgressInfo)
1590 void DirectCopyJob::start(
Slave* slave )
1594 SimpleJob::start(slave);
1599 emit canResume(
this, offset);
1605 class FileCopyJob::FileCopyJobPrivate
1609 time_t m_modificationTime;
1620 FileCopyJob::FileCopyJob(
const KURL& src,
const KURL& dest,
int permissions,
1621 bool move,
bool overwrite,
bool resume,
bool showProgressInfo)
1622 :
Job(showProgressInfo), m_src(src), m_dest(dest),
1623 m_permissions(permissions), m_move(
move), m_overwrite(overwrite), m_resume(resume),
1626 if (showProgressInfo && !
move)
1628 else if (showProgressInfo &&
move)
1636 d =
new FileCopyJobPrivate;
1639 d->m_modificationTime =
static_cast<time_t
>( -1 );
1640 TQTimer::singleShot(0,
this, TQ_SLOT(slotStart()));
1643 void FileCopyJob::slotStart()
1648 if ((m_src.protocol() == m_dest.protocol()) &&
1649 (m_src.host() == m_dest.host()) &&
1650 (m_src.port() == m_dest.port()) &&
1651 (m_src.user() == m_dest.user()) &&
1652 (m_src.pass() == m_dest.pass()) &&
1653 !m_src.hasSubURL() && !m_dest.hasSubURL())
1655 startRenameJob(m_src);
1658 else if (m_src.isLocalFile() && KProtocolInfo::canRenameFromFile(m_dest))
1660 startRenameJob(m_dest);
1663 else if (m_dest.isLocalFile() && KProtocolInfo::canRenameToFile(m_src))
1665 startRenameJob(m_src);
1670 startBestCopyMethod();
1673 void FileCopyJob::startBestCopyMethod()
1675 if ((m_src.protocol() == m_dest.protocol()) &&
1676 (m_src.host() == m_dest.host()) &&
1677 (m_src.port() == m_dest.port()) &&
1678 (m_src.user() == m_dest.user()) &&
1679 (m_src.pass() == m_dest.pass()) &&
1680 !m_src.hasSubURL() && !m_dest.hasSubURL())
1686 startCopyJob(m_dest);
1690 startCopyJob(m_src);
1698 FileCopyJob::~FileCopyJob()
1705 d->m_sourceSize = size;
1706 if (size != (off_t) -1)
1712 d->m_sourceSize = size;
1719 d->m_modificationTime = mtime;
1722 void FileCopyJob::startCopyJob()
1724 startCopyJob(m_src);
1727 void FileCopyJob::startCopyJob(
const KURL &slave_url)
1730 TDEIO_ARGS << m_src << m_dest << m_permissions << (TQ_INT8) m_overwrite;
1731 m_copyJob =
new DirectCopyJob(slave_url, CMD_COPY, packedArgs,
false);
1733 connectSubjob( m_copyJob );
1738 void FileCopyJob::startRenameJob(
const KURL &slave_url)
1740 TDEIO_ARGS << m_src << m_dest << (TQ_INT8) m_overwrite;
1741 m_moveJob =
new SimpleJob(slave_url, CMD_RENAME, packedArgs,
false);
1743 connectSubjob( m_moveJob );
1746 void FileCopyJob::connectSubjob(
SimpleJob * job )
1763 if ( size > m_totalSize ) {
1771 if (size > m_totalSize)
1780 if ( pct > m_percent )
1783 emit
percent(
this, m_percent );
1787 void FileCopyJob::startDataPump()
1791 m_canResume =
false;
1792 m_resumeAnswerSent =
false;
1794 m_putJob =
put( m_dest, m_permissions, m_overwrite, m_resume,
false );
1795 if ( d->m_modificationTime !=
static_cast<time_t
>( -1 ) ) {
1796 TQDateTime dt; dt.setTime_t( d->m_modificationTime );
1797 m_putJob->
addMetaData(
"modified", dt.toString( TQt::ISODate ) );
1805 connect( m_putJob, TQ_SIGNAL(dataReq(
TDEIO::Job *, TQByteArray&)),
1806 TQ_SLOT( slotDataReq(
TDEIO::Job *, TQByteArray&)));
1812 if ( job == m_putJob || job == m_copyJob )
1825 job, i18n(
"File Already Exists"),
1828 (RenameDlg_Mode) (M_OVERWRITE | M_RESUME | M_NORENAME), newPath,
1829 d->m_sourceSize, offset );
1832 if ( res == R_OVERWRITE || m_overwrite )
1834 else if ( res == R_CANCEL )
1836 if ( job == m_putJob )
1837 m_putJob->
kill(
true);
1839 m_copyJob->kill(
true);
1840 m_error = ERR_USER_CANCELED;
1846 m_resumeAnswerSent =
true;
1848 if ( job == m_putJob )
1850 m_getJob =
get( m_src,
false,
false );
1853 m_getJob->
addMetaData(
"AllowCompressedPage",
"false" );
1868 m_putJob->slave()->setOffset( offset );
1872 connectSubjob( m_getJob );
1875 connect( m_getJob, TQ_SIGNAL(data(
TDEIO::Job*,
const TQByteArray&)),
1876 TQ_SLOT( slotData(
TDEIO::Job*,
const TQByteArray&)) );
1878 TQ_SLOT(slotMimetype(
TDEIO::Job*,
const TQString&)) );
1882 m_copyJob->slave()->sendResumeAnswer( offset != 0 );
1885 else if ( job == m_getJob )
1891 m_getJob->slave()->setOffset( m_putJob->slave()->offset() );
1894 kdWarning(7007) <<
"FileCopyJob::slotCanResume from unknown job=" << job
1895 <<
" m_getJob=" << m_getJob <<
" m_putJob=" << m_putJob << endl;
1898 void FileCopyJob::slotData(
TDEIO::Job * ,
const TQByteArray &data)
1903 if (!m_putJob)
return;
1910 if (!m_resumeAnswerSent)
1912 m_resumeAnswerSent =
true;
1918 void FileCopyJob::slotDataReq(
TDEIO::Job * , TQByteArray &data)
1921 if (!m_resumeAnswerSent && !m_getJob)
1924 m_error = ERR_INTERNAL;
1925 m_errorText =
"'Put' job didn't send canResume or 'Get' job didn't send data!";
1926 m_putJob->
kill(
true);
1936 m_buffer = TQByteArray();
1939 void FileCopyJob::slotMimetype(
TDEIO::Job*,
const TQString& type )
1950 if ((job == m_moveJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1953 startBestCopyMethod();
1957 else if ((job == m_copyJob) && (job->
error() == ERR_UNSUPPORTED_ACTION))
1964 else if (job == m_getJob)
1968 m_putJob->
kill(
true);
1970 else if (job == m_putJob)
1974 m_getJob->
kill(
true);
1976 m_error = job->
error();
1982 if (job == m_moveJob)
1987 if (job == m_copyJob)
1997 if (job == m_getJob)
2004 if (job == m_putJob)
2010 kdWarning(7007) <<
"WARNING ! Get still going on..." << endl;
2020 if (job == d->m_delJob)
2028 bool overwrite,
bool resume,
bool showProgressInfo)
2030 return new FileCopyJob( src, dest, permissions,
false, overwrite, resume, showProgressInfo );
2034 bool overwrite,
bool resume,
bool showProgressInfo)
2036 return new FileCopyJob( src, dest, permissions,
true, overwrite, resume, showProgressInfo );
2041 TDEIO_ARGS << src << TQ_INT8(
true);
2042 return new SimpleJob(src, CMD_DEL, packedArgs, showProgressInfo );
2048 ListJob::ListJob(
const KURL& u,
bool showProgressInfo,
bool _recursive, TQString _prefix,
bool _includeHidden) :
2049 SimpleJob(u, CMD_LISTDIR, TQByteArray(), showProgressInfo),
2050 recursive(_recursive), includeHidden(_includeHidden), prefix(_prefix), m_processedEntries(0)
2054 TQDataStream stream( m_packedArgs, IO_WriteOnly );
2058 void ListJob::slotListEntries(
const TDEIO::UDSEntryList& list )
2061 m_processedEntries += list.count();
2065 UDSEntryListConstIterator it = list.begin();
2066 UDSEntryListConstIterator end = list.end();
2068 for (; it != end; ++it) {
2070 bool isLink =
false;
2073 UDSEntry::ConstIterator it2 = (*it).begin();
2074 UDSEntry::ConstIterator end2 = (*it).end();
2075 for( ; it2 != end2; it2++ ) {
2076 switch( (*it2).m_uds ) {
2078 isDir = S_ISDIR((*it2).m_long);
2081 if( itemURL.isEmpty() ) {
2083 itemURL.addPath( (*it2).m_str );
2087 itemURL = (*it2).m_str;
2091 isLink = !(*it2).m_str.isEmpty();
2097 if (isDir && !isLink) {
2098 const TQString filename = itemURL.fileName();
2100 if (filename !=
".." && filename !=
"." && (includeHidden || filename[0] !=
'.')) {
2104 prefix + filename +
"/",
2108 const TDEIO::UDSEntryList& )),
2110 const TDEIO::UDSEntryList& )));
2120 if (prefix.isNull() && includeHidden) {
2124 UDSEntryList newlist;
2126 UDSEntryListConstIterator it = list.begin();
2127 UDSEntryListConstIterator end = list.end();
2128 for (; it != end; ++it) {
2131 UDSEntry::Iterator it2 = newone.begin();
2133 for( ; it2 != newone.end(); it2++ ) {
2135 filename = (*it2).m_str;
2136 (*it2).m_str = prefix + filename;
2141 if ( (prefix.isNull() || (filename !=
".." && filename !=
".") )
2142 && (includeHidden || (filename[0] !=
'.') ) )
2143 newlist.append(newone);
2150 void ListJob::gotEntries(
TDEIO::Job *,
const TDEIO::UDSEntryList& list )
2163 void ListJob::slotRedirection(
const KURL & url )
2165 if (!tdeApp->authorizeURLAction(
"redirect", m_url,
url))
2167 kdWarning(7007) <<
"ListJob: Redirection from " << m_url <<
" to " <<
url <<
" REJECTED!" << endl;
2170 m_redirectionURL =
url;
2171 if (m_url.hasUser() && !
url.hasUser() && (m_url.host().lower() ==
url.host().lower()))
2172 m_redirectionURL.setUser(m_url.user());
2176 void ListJob::slotFinished()
2179 if ( m_error == TDEIO::ERR_IS_FILE && m_url.isLocalFile() ) {
2182 TQString proto = ptr->property(
"X-TDE-LocalProtocol").toString();
2184 m_redirectionURL = m_url;
2185 m_redirectionURL.setProtocol( proto );
2191 if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) {
2199 m_url = m_redirectionURL;
2200 m_redirectionURL = KURL();
2201 m_packedArgs.truncate(0);
2202 TQDataStream stream( m_packedArgs, IO_WriteOnly );
2213 storeSSLSessionFromJob(m_redirectionURL);
2218 ListJob * job =
new ListJob(url, showProgressInfo,
false,TQString::null,includeHidden);
2224 ListJob * job =
new ListJob(url, showProgressInfo,
true,TQString::null,includeHidden);
2231 extraFlags() |= EF_ListJobUnrestricted;
2233 extraFlags() &= ~EF_ListJobUnrestricted;
2236 void ListJob::start(
Slave *slave)
2238 if (tdeApp && !tdeApp->authorizeURLAction(
"list", m_url, m_url) && !(extraFlags() & EF_ListJobUnrestricted))
2240 m_error = ERR_ACCESS_DENIED;
2241 m_errorText = m_url.url();
2242 TQTimer::singleShot(0,
this, TQ_SLOT(slotFinished()) );
2245 connect( slave, TQ_SIGNAL( listEntries(
const TDEIO::UDSEntryList& )),
2246 TQ_SLOT( slotListEntries(
const TDEIO::UDSEntryList& )));
2249 connect( slave, TQ_SIGNAL(
redirection(
const KURL &) ),
2250 TQ_SLOT( slotRedirection(
const KURL &) ) );
2252 SimpleJob::start(slave);
2255 class CopyJob::CopyJobPrivate
2259 m_defaultPermissions =
false;
2260 m_bURLDirty =
false;
2268 CopyJob::DestinationState m_globalDestinationState;
2270 bool m_defaultPermissions;
2275 TQValueList<CopyInfo> m_directoriesCopied;
2279 :
Job(showProgressInfo), m_mode(mode), m_asMethod(asMethod),
2280 destinationState(DEST_NOT_STATED), state(STATE_STATING),
2281 m_totalSize(0), m_processedSize(0), m_fileProcessedSize(0),
2282 m_processedFiles(0), m_processedDirs(0),
2283 m_srcList(src), m_currentStatSrc(m_srcList.begin()),
2284 m_bCurrentOperationIsLink(false), m_bSingleFileCopy(false), m_bOnlyRenames(mode==Move),
2285 m_dest(dest), m_bAutoSkip( false ), m_bOverwriteAll( false ),
2286 m_conflictError(0), m_reportTimer(0)
2288 d =
new CopyJobPrivate;
2289 d->m_globalDest = dest;
2290 d->m_globalDestinationState = destinationState;
2292 if ( showProgressInfo ) {
2299 TQTimer::singleShot(0,
this, TQ_SLOT(
slotStart()));
2328 m_reportTimer =
new TQTimer(
this);
2330 connect(m_reportTimer,TQ_SIGNAL(timeout()),
this,TQ_SLOT(slotReport()));
2331 m_reportTimer->start(REPORT_TIMEOUT,
false);
2340 TDEIO_EXPORT
bool tdeio_resolve_local_urls =
true;
2342 void CopyJob::slotResultStating(
Job *job )
2346 if (job->
error() && destinationState != DEST_NOT_STATED )
2349 if ( !srcurl.isLocalFile() )
2354 kdDebug(7007) <<
"Error while stating source. Activating hack" << endl;
2355 subjobs.remove( job );
2356 assert ( subjobs.isEmpty() );
2357 struct CopyInfo info;
2358 info.permissions = (mode_t) -1;
2359 info.mtime = (time_t) -1;
2360 info.ctime = (time_t) -1;
2362 info.uSource = srcurl;
2363 info.uDest = m_dest;
2365 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2366 info.uDest.addPath( srcurl.fileName() );
2368 files.append( info );
2382 TQString sLocalPath;
2383 UDSEntry::ConstIterator it2 = entry.begin();
2384 for( ; it2 != entry.end(); it2++ ) {
2386 bDir = S_ISDIR( (mode_t)(*it2).m_long );
2388 bLink = !((*it2).m_str.isEmpty());
2389 else if ( ((*it2).m_uds) ==
UDS_NAME )
2390 sName = (*it2).m_str;
2392 sLocalPath = (*it2).m_str;
2395 if ( destinationState == DEST_NOT_STATED )
2399 destinationState = DEST_DOESNT_EXIST;
2402 destinationState = bDir ? DEST_IS_DIR : DEST_IS_FILE;
2405 const bool isGlobalDest = m_dest == d->m_globalDest;
2407 d->m_globalDestinationState = destinationState;
2409 if ( !sLocalPath.isEmpty() && tdeio_resolve_local_urls ) {
2411 m_dest.setPath(sLocalPath);
2413 d->m_globalDest = m_dest;
2416 subjobs.remove( job );
2417 assert ( subjobs.isEmpty() );
2424 m_currentDest = m_dest;
2441 m_bCurrentSrcIsDir =
false;
2442 slotEntries(job, lst);
2445 if (!sLocalPath.isEmpty())
2446 srcurl.setPath(sLocalPath);
2450 subjobs.remove( job );
2451 assert ( subjobs.isEmpty() );
2459 m_bCurrentSrcIsDir =
true;
2460 if ( destinationState == DEST_IS_DIR )
2465 TQString directory = srcurl.fileName();
2466 if ( !sName.isEmpty() && KProtocolInfo::fileNameUsedForCopying( srcurl ) == KProtocolInfo::Name )
2470 m_currentDest.addPath( directory );
2473 else if ( destinationState == DEST_IS_FILE )
2475 m_error = ERR_IS_FILE;
2476 m_errorText = m_dest.prettyURL();
2486 destinationState = DEST_IS_DIR;
2487 if ( m_dest == d->m_globalDest )
2488 d->m_globalDestinationState = destinationState;
2491 startListing( srcurl );
2500 void CopyJob::slotReport()
2505 case STATE_COPYING_FILES:
2507 if (observer) observer->slotProcessedFiles(
this, m_processedFiles);
2511 d->m_bURLDirty =
false;
2514 if (observer) observer->slotMoving(
this, m_currentSrcURL, m_currentDestURL);
2515 emit
moving(
this, m_currentSrcURL, m_currentDestURL);
2517 else if (m_mode==Link)
2519 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2520 emit
linking(
this, m_currentSrcURL.path(), m_currentDestURL );
2524 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2525 emit
copying(
this, m_currentSrcURL, m_currentDestURL );
2530 case STATE_CREATING_DIRS:
2531 if (observer) observer->slotProcessedDirs(
this, m_processedDirs );
2535 d->m_bURLDirty =
false;
2537 if (observer) observer->slotCreatingDir(
this, m_currentDestURL);
2545 d->m_bURLDirty =
false;
2546 if (observer) observer->slotCopying(
this, m_currentSrcURL, m_currentDestURL );
2558 void CopyJob::slotEntries(
TDEIO::Job* job,
const UDSEntryList& list)
2560 UDSEntryListConstIterator it = list.begin();
2561 UDSEntryListConstIterator end = list.end();
2562 for (; it != end; ++it) {
2563 UDSEntry::ConstIterator it2 = (*it).begin();
2564 struct CopyInfo info;
2565 info.permissions = -1;
2566 info.mtime = (time_t) -1;
2567 info.ctime = (time_t) -1;
2569 TQString displayName;
2573 for( ; it2 != (*it).end(); it2++ ) {
2574 switch ((*it2).m_uds) {
2577 isDir = S_ISDIR( (mode_t)((*it2).m_long) );
2580 displayName = (*it2).m_str;
2583 url = KURL((*it2).m_str);
2586 localPath = (*it2).m_str;
2589 info.linkDest = (*it2).m_str;
2592 info.permissions = ((*it2).m_long);
2596 m_totalSize += info.size;
2599 info.mtime = (time_t)((*it2).m_long);
2602 info.ctime = (time_t)((*it2).m_long);
2607 if (displayName !=
".." && displayName !=
".")
2609 bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
2610 if( !hasCustomURL ) {
2613 if ( m_bCurrentSrcIsDir ) {
2615 url.addPath( displayName );
2619 if (!localPath.isEmpty() && tdeio_resolve_local_urls) {
2621 url.setPath(localPath);
2625 info.uDest = m_currentDest;
2628 if ( destinationState == DEST_IS_DIR &&
2631 ( ! ( m_asMethod && state == STATE_STATING ) ) )
2633 TQString destFileName;
2634 if ( hasCustomURL &&
2635 KProtocolInfo::fileNameUsedForCopying( url ) == KProtocolInfo::FromURL ) {
2638 int numberOfSlashes = displayName.contains(
'/' );
2639 TQString path = url.path();
2641 for (
int n = 0; n < numberOfSlashes + 1; ++n ) {
2642 pos = path.findRev(
'/', pos - 1 );
2644 kdWarning(7007) <<
"tdeioslave bug: not enough slashes in UDS_URL " << path <<
" - looking for " << numberOfSlashes <<
" slashes" << endl;
2649 destFileName = path.mid( pos + 1 );
2653 destFileName = displayName;
2659 if ( destFileName.isEmpty() )
2663 info.uDest.addPath( destFileName );
2667 if ( info.linkDest.isEmpty() && isDir && m_mode != Link )
2669 dirs.append( info );
2671 dirsToRemove.append( info.uSource );
2674 files.append( info );
2680 void CopyJob::skipSrc()
2682 m_dest = d->m_globalDest;
2683 destinationState = d->m_globalDestinationState;
2685 skip( m_currentSrcURL );
2689 void CopyJob::statNextSrc()
2695 m_dest = d->m_globalDest;
2696 destinationState = d->m_globalDestinationState;
2701 void CopyJob::statCurrentSrc()
2703 if ( m_currentStatSrc != m_srcList.end() )
2705 m_currentSrcURL = (*m_currentStatSrc);
2706 d->m_bURLDirty =
true;
2707 if ( m_mode == Link )
2710 m_currentDest = m_dest;
2711 struct CopyInfo info;
2712 info.permissions = -1;
2713 info.mtime = (time_t) -1;
2714 info.ctime = (time_t) -1;
2716 info.uSource = m_currentSrcURL;
2717 info.uDest = m_currentDest;
2719 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2722 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
2723 (m_currentSrcURL.host() == info.uDest.host()) &&
2724 (m_currentSrcURL.port() == info.uDest.port()) &&
2725 (m_currentSrcURL.user() == info.uDest.user()) &&
2726 (m_currentSrcURL.pass() == info.uDest.pass()) )
2729 info.uDest.addPath( m_currentSrcURL.fileName() );
2739 files.append( info );
2743 else if ( m_mode == Move && (
2745 KProtocolInfo::fileNameUsedForCopying( m_currentSrcURL ) == KProtocolInfo::FromURL ||
2746 destinationState != DEST_IS_DIR || m_asMethod )
2751 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
2752 (m_currentSrcURL.host() == m_dest.host()) &&
2753 (m_currentSrcURL.port() == m_dest.port()) &&
2754 (m_currentSrcURL.user() == m_dest.user()) &&
2755 (m_currentSrcURL.pass() == m_dest.pass()) )
2757 startRenameJob( m_currentSrcURL );
2760 else if ( m_currentSrcURL.isLocalFile() && KProtocolInfo::canRenameFromFile( m_dest ) )
2762 startRenameJob( m_dest );
2765 else if ( m_dest.isLocalFile() && KProtocolInfo::canRenameToFile( m_currentSrcURL ) )
2767 startRenameJob( m_currentSrcURL );
2774 TQGuardedPtr<CopyJob> that =
this;
2776 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentSrcURL.prettyURL()));
2785 state = STATE_STATING;
2787 m_currentDestURL=m_dest;
2788 m_bOnlyRenames =
false;
2789 d->m_bURLDirty =
true;
2795 state = STATE_STATING;
2796 d->m_bURLDirty =
true;
2798 if (!dirs.isEmpty())
2800 if (!files.isEmpty())
2803 m_bSingleFileCopy = ( files.count() == 1 && dirs.isEmpty() );
2805 state = STATE_CREATING_DIRS;
2810 void CopyJob::startRenameJob(
const KURL& slave_url )
2814 if ( destinationState == DEST_IS_DIR && !m_asMethod )
2815 dest.addPath( m_currentSrcURL.fileName() );
2816 kdDebug(7007) <<
"This seems to be a suitable case for trying to rename before stat+[list+]copy+del" << endl;
2817 state = STATE_RENAMING;
2819 struct CopyInfo info;
2820 info.permissions = -1;
2821 info.mtime = (time_t) -1;
2822 info.ctime = (time_t) -1;
2824 info.uSource = m_currentSrcURL;
2826 TQValueList<CopyInfo> files;
2830 TDEIO_ARGS << m_currentSrcURL << dest << (TQ_INT8)
false ;
2834 if ( m_currentSrcURL.directory() != dest.directory() )
2835 m_bOnlyRenames =
false;
2838 void CopyJob::startListing(
const KURL & src )
2840 state = STATE_LISTING;
2841 d->m_bURLDirty =
true;
2844 connect(newjob, TQ_SIGNAL(entries(
TDEIO::Job *,
2845 const TDEIO::UDSEntryList& )),
2847 const TDEIO::UDSEntryList& )));
2851 void CopyJob::skip(
const KURL & sourceUrl )
2856 KURL::List::Iterator sit = m_srcList.find( sourceUrl );
2857 if ( sit != m_srcList.end() )
2860 m_srcList.remove( sit );
2862 dirsToRemove.remove( sourceUrl );
2865 bool CopyJob::shouldOverwrite(
const TQString& path )
const
2867 if ( m_bOverwriteAll )
2869 TQStringList::ConstIterator sit = m_overwriteList.begin();
2870 for( ; sit != m_overwriteList.end(); ++sit )
2871 if ( path.startsWith( *sit ) )
2876 bool CopyJob::shouldSkip(
const TQString& path )
const
2878 TQStringList::ConstIterator sit = m_skipList.begin();
2879 for( ; sit != m_skipList.end(); ++sit )
2880 if ( path.startsWith( *sit ) )
2885 void CopyJob::slotResultCreatingDirs(
Job * job )
2888 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2892 m_conflictError = job->
error();
2893 if ( (m_conflictError == ERR_DIR_ALREADY_EXIST)
2894 || (m_conflictError == ERR_FILE_ALREADY_EXIST) )
2898 if ( m_bAutoSkip ) {
2900 m_skipList.append( oldURL.path( 1 ) );
2905 const TQString destFile = (*it).uDest.path();
2906 if ( shouldOverwrite( destFile ) ) {
2907 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
2915 assert( ((
SimpleJob*)job)->url().url() == (*it).uDest.url() );
2916 subjobs.remove( job );
2917 assert ( subjobs.isEmpty() );
2920 KURL existingDest( (*it).uDest );
2923 kdDebug(7007) <<
"TDEIO::stat for resolving conflict on " << existingDest << endl;
2924 state = STATE_CONFLICT_CREATING_DIRS;
2940 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
true,
false );
2941 d->m_directoriesCopied.append( *it );
2947 subjobs.remove( job );
2948 assert( subjobs.isEmpty() );
2952 void CopyJob::slotResultConflictCreatingDirs(
TDEIO::Job * job )
2957 TQValueList<CopyInfo>::Iterator it = dirs.begin();
2959 time_t destmtime = (time_t)-1;
2960 time_t destctime = (time_t)-1;
2965 TDEIO::UDSEntry::ConstIterator it2 = entry.begin();
2966 for( ; it2 != entry.end(); it2++ ) {
2967 switch ((*it2).m_uds) {
2969 destmtime = (time_t)((*it2).m_long);
2972 destctime = (time_t)((*it2).m_long);
2975 destsize = (*it2).m_long;
2978 linkDest = (*it2).m_str;
2982 subjobs.remove( job );
2983 assert ( subjobs.isEmpty() );
2986 RenameDlg_Mode mode = (RenameDlg_Mode)( M_MULTI | M_SKIP );
2988 if ( m_conflictError == ERR_DIR_ALREADY_EXIST )
2990 if( (*it).uSource == (*it).uDest ||
2991 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
2992 (*it).uSource.path(-1) == linkDest) )
2993 mode = (RenameDlg_Mode)( mode | M_OVERWRITE_ITSELF);
2995 mode = (RenameDlg_Mode)( mode | M_OVERWRITE );
2998 TQString existingDest = (*it).uDest.path();
3001 m_reportTimer->stop();
3003 (*it).uSource.url(),
3006 (*it).size, destsize,
3007 (*it).ctime, destctime,
3008 (*it).mtime, destmtime );
3010 m_reportTimer->start(REPORT_TIMEOUT,
false);
3013 m_error = ERR_USER_CANCELED;
3018 TQString oldPath = (*it).uDest.path( 1 );
3019 KURL newUrl( (*it).uDest );
3020 newUrl.setPath( newPath );
3021 emit
renamed(
this, (*it).uDest, newUrl );
3024 (*it).uDest.setPath( newUrl.path( -1 ) );
3025 newPath = newUrl.path( 1 );
3026 TQValueList<CopyInfo>::Iterator renamedirit = it;
3029 for( ; renamedirit != dirs.end() ; ++renamedirit )
3031 TQString path = (*renamedirit).uDest.path();
3032 if ( path.left(oldPath.length()) == oldPath ) {
3034 n.replace( 0, oldPath.length(), newPath );
3035 kdDebug(7007) <<
"dirs list: " << (*renamedirit).uSource.path()
3036 <<
" was going to be " << path
3037 <<
", changed into " << n << endl;
3038 (*renamedirit).uDest.setPath( n );
3042 TQValueList<CopyInfo>::Iterator renamefileit = files.begin();
3043 for( ; renamefileit != files.end() ; ++renamefileit )
3045 TQString path = (*renamefileit).uDest.path();
3046 if ( path.left(oldPath.length()) == oldPath ) {
3048 n.replace( 0, oldPath.length(), newPath );
3049 kdDebug(7007) <<
"files list: " << (*renamefileit).uSource.path()
3050 <<
" was going to be " << path
3051 <<
", changed into " << n << endl;
3052 (*renamefileit).uDest.setPath( n );
3055 if (!dirs.isEmpty())
3057 if (!files.isEmpty())
3065 m_skipList.append( existingDest );
3066 skip( (*it).uSource );
3072 m_overwriteList.append( existingDest );
3073 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3078 case R_OVERWRITE_ALL:
3079 m_bOverwriteAll =
true;
3080 emit
copyingDone(
this, ( *it ).uSource, ( *it ).uDest,
true ,
false );
3088 state = STATE_CREATING_DIRS;
3093 void CopyJob::createNextDir()
3096 if ( !dirs.isEmpty() )
3099 TQValueList<CopyInfo>::Iterator it = dirs.begin();
3101 while( it != dirs.end() && udir.isEmpty() )
3103 const TQString dir = (*it).uDest.path();
3104 if ( shouldSkip( dir ) ) {
3111 if ( !udir.isEmpty() )
3118 m_currentDestURL = udir;
3119 d->m_bURLDirty =
true;
3127 if (m_progressId)
Observer::self()->slotProcessedDirs(
this, m_processedDirs );
3129 state = STATE_COPYING_FILES;
3135 void CopyJob::slotResultCopyingFiles(
Job * job )
3138 TQValueList<CopyInfo>::Iterator it = files.begin();
3144 skip( (*it).uSource );
3145 m_fileProcessedSize = (*it).size;
3155 m_conflictError = job->
error();
3157 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3158 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3159 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3161 subjobs.remove( job );
3162 assert ( subjobs.isEmpty() );
3164 KURL existingFile( (*it).uDest );
3167 kdDebug(7007) <<
"TDEIO::stat for resolving conflict on " << existingFile << endl;
3168 state = STATE_CONFLICT_COPYING_FILES;
3174 if ( m_bCurrentOperationIsLink && ::tqt_cast<TDEIO::DeleteJob*>( job ) )
3178 m_fileProcessedSize = (*it).size;
3182 slotResultConflictCopyingFiles( job );
3190 if ( m_bCurrentOperationIsLink && m_mode == Move
3191 && !::tqt_cast<TDEIO::DeleteJob *>( job )
3194 subjobs.remove( job );
3195 assert ( subjobs.isEmpty() );
3203 if ( m_bCurrentOperationIsLink )
3205 TQString target = ( m_mode == Link ? (*it).uSource.path() : (*it).linkDest );
3211 emit
copyingDone(
this, (*it).uSource, (*it).uDest,
false,
false );
3218 m_processedSize += m_fileProcessedSize;
3219 m_fileProcessedSize = 0;
3224 assert ( subjobs.isEmpty() );
3228 void CopyJob::slotResultConflictCopyingFiles(
TDEIO::Job * job )
3232 TQValueList<CopyInfo>::Iterator it = files.begin();
3238 m_reportTimer->stop();
3240 if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST )
3241 || ( m_conflictError == ERR_DIR_ALREADY_EXIST )
3242 || ( m_conflictError == ERR_IDENTICAL_FILES ) )
3245 time_t destmtime = (time_t)-1;
3246 time_t destctime = (time_t)-1;
3250 TDEIO::UDSEntry::ConstIterator it2 = entry.begin();
3251 for( ; it2 != entry.end(); it2++ ) {
3252 switch ((*it2).m_uds) {
3254 destmtime = (time_t)((*it2).m_long);
3257 destctime = (time_t)((*it2).m_long);
3260 destsize = (*it2).m_long;
3263 linkDest = (*it2).m_str;
3270 RenameDlg_Mode mode;
3273 if( m_conflictError == ERR_DIR_ALREADY_EXIST )
3274 mode = (RenameDlg_Mode) 0;
3277 if ( (*it).uSource == (*it).uDest ||
3278 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
3279 (*it).uSource.path(-1) == linkDest) )
3280 mode = M_OVERWRITE_ITSELF;
3286 if ( m_bSingleFileCopy )
3287 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3289 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3292 i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3293 (*it).uSource.url(),
3296 (*it).size, destsize,
3297 (*it).ctime, destctime,
3298 (*it).mtime, destmtime );
3303 if ( job->
error() == ERR_USER_CANCELED )
3311 SkipDlg_Result skipResult =
Observer::self()->open_SkipDlg(
this, files.count() > 1,
3315 res = ( skipResult == S_SKIP ) ? R_SKIP :
3316 ( skipResult == S_AUTO_SKIP ) ? R_AUTO_SKIP :
3322 m_reportTimer->start(REPORT_TIMEOUT,
false);
3324 subjobs.remove( job );
3325 assert ( subjobs.isEmpty() );
3328 m_error = ERR_USER_CANCELED;
3333 KURL newUrl( (*it).uDest );
3334 newUrl.setPath( newPath );
3335 emit
renamed(
this, (*it).uDest, newUrl );
3336 (*it).uDest = newUrl;
3338 TQValueList<CopyInfo> files;
3348 skip( (*it).uSource );
3349 m_processedSize += (*it).size;
3353 case R_OVERWRITE_ALL:
3354 m_bOverwriteAll =
true;
3358 m_overwriteList.append( (*it).uDest.path() );
3363 state = STATE_COPYING_FILES;
3368 void CopyJob::copyNextFile()
3370 bool bCopyFile =
false;
3373 TQValueList<CopyInfo>::Iterator it = files.begin();
3375 while (it != files.end() && !bCopyFile)
3377 const TQString destFile = (*it).uDest.path();
3378 bCopyFile = !shouldSkip( destFile );
3389 const TQString destFile = (*it).uDest.path();
3390 kdDebug(7007) <<
"copying " << destFile << endl;
3391 if ( (*it).uDest == (*it).uSource )
3394 bOverwrite = shouldOverwrite( destFile );
3396 m_bCurrentOperationIsLink =
false;
3398 if ( m_mode == Link )
3402 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3403 ((*it).uSource.host() == (*it).uDest.host()) &&
3404 ((*it).uSource.port() == (*it).uDest.port()) &&
3405 ((*it).uSource.user() == (*it).uDest.user()) &&
3406 ((*it).uSource.pass() == (*it).uDest.pass()) )
3414 m_bCurrentOperationIsLink =
true;
3415 m_currentSrcURL=(*it).uSource;
3416 m_currentDestURL=(*it).uDest;
3417 d->m_bURLDirty =
true;
3421 if ( (*it).uDest.isLocalFile() )
3423 bool devicesOk=
false;
3426 if ((*it).uSource.protocol()==TQString::fromLatin1(
"devices"))
3431 TQDataStream streamout(param,IO_WriteOnly);
3432 streamout<<(*it).uSource;
3433 streamout<<(*it).uDest;
3434 if ( tdeApp && tdeApp->dcopClient()->call(
"kded",
3435 "mountwatcher",
"createLink(KURL, KURL)", param,retType,data,
false ) )
3437 TQDataStream streamin(data,IO_ReadOnly);
3438 streamin>>devicesOk;
3452 TQString path = (*it).uDest.path();
3455 if ( f.open( IO_ReadWrite ) )
3458 TDESimpleConfig config( path );
3459 config.setDesktopGroup();
3460 KURL url = (*it).uSource;
3462 config.writePathEntry( TQString::fromLatin1(
"URL"), url.url() );
3463 config.writeEntry( TQString::fromLatin1(
"Name"), url.url() );
3464 config.writeEntry( TQString::fromLatin1(
"Type"), TQString::fromLatin1(
"Link") );
3465 TQString protocol = (*it).uSource.protocol();
3466 if ( protocol == TQString::fromLatin1(
"ftp") )
3467 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"ftp") );
3468 else if ( protocol == TQString::fromLatin1(
"http") )
3469 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"www") );
3470 else if ( protocol == TQString::fromLatin1(
"info") )
3471 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"application-vnd.tde.info") );
3472 else if ( protocol == TQString::fromLatin1(
"mailto") )
3473 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"kmail") );
3475 config.writeEntry( TQString::fromLatin1(
"Icon"), TQString::fromLatin1(
"unknown") );
3485 kdDebug(7007) <<
"CopyJob::copyNextFile ERR_CANNOT_OPEN_FOR_WRITING" << endl;
3486 m_error = ERR_CANNOT_OPEN_FOR_WRITING;
3487 m_errorText = (*it).uDest.path();
3494 m_error = ERR_CANNOT_SYMLINK;
3495 m_errorText = (*it).uDest.prettyURL();
3501 else if ( !(*it).linkDest.isEmpty() &&
3502 ((*it).uSource.protocol() == (*it).uDest.protocol()) &&
3503 ((*it).uSource.host() == (*it).uDest.host()) &&
3504 ((*it).uSource.port() == (*it).uDest.port()) &&
3505 ((*it).uSource.user() == (*it).uDest.user()) &&
3506 ((*it).uSource.pass() == (*it).uDest.pass()))
3514 m_currentSrcURL=(*it).linkDest;
3515 m_currentDestURL=(*it).uDest;
3516 d->m_bURLDirty =
true;
3518 m_bCurrentOperationIsLink =
true;
3520 }
else if (m_mode == Move)
3527 m_currentSrcURL=(*it).uSource;
3528 m_currentDestURL=(*it).uDest;
3529 d->m_bURLDirty =
true;
3537 int permissions = (*it).permissions;
3538 if ( d->m_defaultPermissions || ( remoteSource && (*it).uDest.isLocalFile() ) )
3546 m_currentSrcURL=(*it).uSource;
3547 m_currentDestURL=(*it).uDest;
3548 d->m_bURLDirty =
true;
3564 void CopyJob::deleteNextDir()
3566 if ( m_mode == Move && !dirsToRemove.isEmpty() )
3568 state = STATE_DELETING_DIRS;
3569 d->m_bURLDirty =
true;
3571 KURL::List::Iterator it = dirsToRemove.fromLast();
3574 dirsToRemove.remove(it);
3580 setNextDirAttribute();
3584 void CopyJob::setNextDirAttribute()
3586 if ( !d->m_directoriesCopied.isEmpty() )
3588 state = STATE_SETTING_DIR_ATTRIBUTES;
3591 TQValueList<CopyInfo>::Iterator it = d->m_directoriesCopied.begin();
3592 for ( ; it != d->m_directoriesCopied.end() ; ++it ) {
3593 const KURL& url = (*it).uDest;
3594 if ( url.isLocalFile() && (*it).mtime != (time_t)-1 ) {
3595 const TQCString path = TQFile::encodeName( url.path() );
3596 KDE_struct_stat statbuf;
3597 if (KDE_lstat(path, &statbuf) == 0) {
3598 struct utimbuf utbuf;
3599 utbuf.actime = statbuf.st_atime;
3600 utbuf.modtime = (*it).mtime;
3601 utime( path, &utbuf );
3607 d->m_directoriesCopied.clear();
3614 if ( !m_bOnlyRenames )
3616 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
3617 KURL url( d->m_globalDest );
3618 if ( d->m_globalDestinationState != DEST_IS_DIR || m_asMethod )
3619 url.setPath( url.directory() );
3621 allDirNotify.FilesAdded( url );
3623 if ( m_mode == Move && !m_srcList.isEmpty() ) {
3625 allDirNotify.FilesRemoved( m_srcList );
3629 m_reportTimer->stop();
3640 m_fileProcessedSize = data_size;
3643 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
3645 m_totalSize = m_processedSize + m_fileProcessedSize;
3650 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
3651 emitPercent( m_processedSize + m_fileProcessedSize, m_totalSize );
3661 if ( m_bSingleFileCopy && size > m_totalSize)
3669 void CopyJob::slotResultDeletingDirs(
Job * job )
3677 subjobs.remove( job );
3678 assert ( subjobs.isEmpty() );
3683 void CopyJob::slotResultSettingDirAttributes(
Job * job )
3691 subjobs.remove( job );
3692 assert ( subjobs.isEmpty() );
3693 setNextDirAttribute();
3697 void CopyJob::slotResultRenaming(
Job* job )
3699 int err = job->
error();
3700 const TQString errText = job->
errorText();
3702 assert ( subjobs.isEmpty() );
3705 if ( destinationState == DEST_IS_DIR && !m_asMethod )
3706 dest.addPath( m_currentSrcURL.fileName() );
3712 if ( m_currentSrcURL.isLocalFile() && m_currentSrcURL.url(-1) != dest.url(-1) &&
3713 m_currentSrcURL.url(-1).lower() == dest.url(-1).lower() &&
3714 ( err == ERR_FILE_ALREADY_EXIST ||
3715 err == ERR_DIR_ALREADY_EXIST ||
3716 err == ERR_IDENTICAL_FILES ) )
3718 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;
3719 TQCString _src( TQFile::encodeName(m_currentSrcURL.path()) );
3720 TQCString _dest( TQFile::encodeName(dest.path()) );
3721 KTempFile tmpFile( m_currentSrcURL.directory(
false) );
3722 TQCString _tmp( TQFile::encodeName(tmpFile.name()) );
3723 kdDebug(7007) <<
"CopyJob::slotResult KTempFile status:" << tmpFile.status() <<
" using " << _tmp <<
" as intermediary" << endl;
3725 if ( ::
rename( _src, _tmp ) == 0 )
3727 if ( !TQFile::exists( _dest ) && ::
rename( _tmp, _dest ) == 0 )
3729 kdDebug(7007) <<
"Success." << endl;
3735 if ( ::
rename( _tmp, _src ) != 0 ) {
3736 kdError(7007) <<
"Couldn't rename " << tmpFile.name() <<
" back to " << _src <<
" !" << endl;
3754 Q_ASSERT( m_currentSrcURL == *m_currentStatSrc );
3757 if ( ( err == ERR_DIR_ALREADY_EXIST ||
3758 err == ERR_FILE_ALREADY_EXIST ||
3759 err == ERR_IDENTICAL_FILES )
3763 m_reportTimer->stop();
3766 if ( m_bAutoSkip ) {
3770 }
else if ( m_bOverwriteAll ) {
3775 RenameDlg_Mode mode = (RenameDlg_Mode)
3776 ( ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE );
3778 if ( m_srcList.count() > 1 )
3779 mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP );
3781 mode = (RenameDlg_Mode) ( mode | M_SINGLE );
3788 time_t ctimeSrc = (time_t) -1;
3789 time_t ctimeDest = (time_t) -1;
3790 time_t mtimeSrc = (time_t) -1;
3791 time_t mtimeDest = (time_t) -1;
3793 KDE_struct_stat stat_buf;
3794 if ( m_currentSrcURL.isLocalFile() &&
3795 KDE_stat(TQFile::encodeName(m_currentSrcURL.path()), &stat_buf) == 0 ) {
3796 sizeSrc = stat_buf.st_size;
3797 ctimeSrc = stat_buf.st_ctime;
3798 mtimeSrc = stat_buf.st_mtime;
3800 if ( dest.isLocalFile() &&
3801 KDE_stat(TQFile::encodeName(dest.path()), &stat_buf) == 0 ) {
3802 sizeDest = stat_buf.st_size;
3803 ctimeDest = stat_buf.st_ctime;
3804 mtimeDest = stat_buf.st_mtime;
3809 err != ERR_DIR_ALREADY_EXIST ? i18n(
"File Already Exists") : i18n(
"Already Exists as Folder"),
3810 m_currentSrcURL.url(),
3814 ctimeSrc, ctimeDest,
3815 mtimeSrc, mtimeDest );
3817 m_reportTimer->start(REPORT_TIMEOUT,
false);
3823 m_error = ERR_USER_CANCELED;
3831 m_dest.setPath( newPath );
3833 state = STATE_STATING;
3834 destinationState = DEST_NOT_STATED;
3845 case R_OVERWRITE_ALL:
3846 m_bOverwriteAll =
true;
3854 kdDebug(7007) <<
"adding to overwrite list: " << dest.path() << endl;
3855 m_overwriteList.append( dest.path() );
3862 }
else if ( err != TDEIO::ERR_UNSUPPORTED_ACTION ) {
3863 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", aborting" << endl;
3865 m_errorText = errText;
3869 kdDebug(7007) <<
"Couldn't rename " << m_currentSrcURL <<
" to " << dest <<
", reverting to normal way, starting with stat" << endl;
3872 state = STATE_STATING;
3874 m_bOnlyRenames =
false;
3879 emit
copyingDone(
this, *m_currentStatSrc, dest,
true,
true );
3884 void CopyJob::slotResult(
Job *job )
3894 slotResultStating( job );
3896 case STATE_RENAMING:
3898 slotResultRenaming( job );
3910 subjobs.remove( job );
3911 assert ( subjobs.isEmpty() );
3915 case STATE_CREATING_DIRS:
3916 slotResultCreatingDirs( job );
3918 case STATE_CONFLICT_CREATING_DIRS:
3919 slotResultConflictCreatingDirs( job );
3921 case STATE_COPYING_FILES:
3922 slotResultCopyingFiles( job );
3924 case STATE_CONFLICT_COPYING_FILES:
3925 slotResultConflictCopyingFiles( job );
3927 case STATE_DELETING_DIRS:
3928 slotResultDeletingDirs( job );
3930 case STATE_SETTING_DIR_ATTRIBUTES:
3941 d->m_defaultPermissions = b;
3954 srcList.append( src );
3955 return new CopyJob( srcList, dest, CopyJob::Copy,
false, showProgressInfo );
3962 srcList.append( src );
3963 return new CopyJob( srcList, dest, CopyJob::Copy,
true, showProgressInfo );
3969 return new CopyJob( src, dest, CopyJob::Copy,
false, showProgressInfo );
3976 srcList.append( src );
3977 return new CopyJob( srcList, dest, CopyJob::Move,
false, showProgressInfo );
3984 srcList.append( src );
3985 return new CopyJob( srcList, dest, CopyJob::Move,
true, showProgressInfo );
3991 return new CopyJob( src, dest, CopyJob::Move,
false, showProgressInfo );
3997 srcList.append( src );
3998 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
4003 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
4009 srcList.append( src );
4010 return new CopyJob( srcList, destDir, CopyJob::Link,
false, showProgressInfo );
4016 srcList.append( src );
4017 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
4022 return new CopyJob( srcList, KURL(
"trash:/" ), CopyJob::Move,
false, showProgressInfo );
4028 :
Job(showProgressInfo), m_totalSize( 0 ), m_processedSize( 0 ), m_fileProcessedSize( 0 ),
4029 m_processedFiles( 0 ), m_processedDirs( 0 ), m_totalFilesDirs( 0 ),
4030 m_srcList(src), m_currentStat(m_srcList.begin()), m_reportTimer(0)
4032 if ( showProgressInfo ) {
4050 m_reportTimer=
new TQTimer(
this);
4051 connect(m_reportTimer,TQ_SIGNAL(timeout()),
this,TQ_SLOT(slotReport()));
4053 m_reportTimer->start(REPORT_TIMEOUT,
false);
4056 TQTimer::singleShot(0,
this, TQ_SLOT(slotStart()));
4059 void DeleteJob::slotStart()
4067 void DeleteJob::slotReport()
4069 if (m_progressId==0)
4074 emit
deleting(
this, m_currentURL );
4075 observer->slotDeleting(
this,m_currentURL);
4084 case STATE_DELETING_DIRS:
4086 observer->slotProcessedDirs(
this,m_processedDirs);
4087 emitPercent( m_processedFiles + m_processedDirs, m_totalFilesDirs );
4089 case STATE_DELETING_FILES:
4090 observer->slotProcessedFiles(
this,m_processedFiles);
4092 emitPercent( m_processedFiles, m_totalFilesDirs );
4098 void DeleteJob::slotEntries(
TDEIO::Job* job,
const UDSEntryList& list)
4100 UDSEntryListConstIterator it = list.begin();
4101 UDSEntryListConstIterator end = list.end();
4102 for (; it != end; ++it)
4104 UDSEntry::ConstIterator it2 = (*it).begin();
4107 TQString displayName;
4110 for( ; it2 != (*it).end(); it2++ )
4112 switch ((*it2).m_uds)
4115 bDir = S_ISDIR((*it2).m_long);
4119 displayName = (*it2).m_str;
4123 url = KURL((*it2).m_str);
4127 bLink = !(*it2).m_str.isEmpty();
4137 if (atomsFound==5)
break;
4139 assert(!displayName.isEmpty());
4140 if (displayName !=
".." && displayName !=
".")
4142 if( url.isEmpty() ) {
4144 url.addPath( displayName );
4148 symlinks.append( url );
4152 files.append( url );
4158 void DeleteJob::statNextSrc()
4161 if ( m_currentStat != m_srcList.end() )
4163 m_currentURL = (*m_currentStat);
4167 TQGuardedPtr<DeleteJob> that =
this;
4170 KMessageBox::information( 0,
buildErrorString(ERR_CANNOT_DELETE, m_currentURL.prettyURL()));
4176 state = STATE_STATING;
4185 m_totalFilesDirs = files.count()+symlinks.count() + dirs.count();
4191 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4193 state = STATE_DELETING_FILES;
4198 void DeleteJob::deleteNextFile()
4201 if ( !files.isEmpty() || !symlinks.isEmpty() )
4206 KURL::List::Iterator it = files.begin();
4207 bool isLink =
false;
4208 if ( it == files.end() )
4210 it = symlinks.begin();
4215 if ( (*it).isLocalFile() && unlink( TQFile::encodeName((*it).path()) ) == 0 ) {
4219 if ( m_processedFiles % 300 == 0 || m_totalFilesDirs < 300) {
4230 symlinks.remove(it);
4238 }
while (!job && (!files.isEmpty() || !symlinks.isEmpty()));
4240 state = STATE_DELETING_DIRS;
4244 void DeleteJob::deleteNextDir()
4246 if ( !dirs.isEmpty() )
4250 KURL::List::Iterator it = dirs.fromLast();
4252 if ( (*it).isLocalFile() && ::
rmdir( TQFile::encodeName((*it).path()) ) == 0 ) {
4255 if ( m_processedDirs % 100 == 0 ) {
4261 if ( KProtocolInfo::canDeleteRecursive( *it ) ) {
4274 }
while ( !dirs.isEmpty() );
4278 for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it )
4282 if ( !m_srcList.isEmpty() )
4284 KDirNotify_stub allDirNotify(
"*",
"KDirNotify*");
4286 allDirNotify.FilesRemoved( m_srcList );
4288 if (m_reportTimer!=0)
4289 m_reportTimer->stop();
4299 m_fileProcessedSize = data_size;
4304 emit
processedSize(
this, m_processedSize + m_fileProcessedSize );
4307 unsigned long ipercent = m_percent;
4309 if ( m_totalSize == 0 )
4312 m_percent = (
unsigned long)(( (
float)(m_processedSize + m_fileProcessedSize) / (
float)m_totalSize ) * 100.0);
4314 if ( m_percent > ipercent )
4316 emit
percent(
this, m_percent );
4322 void DeleteJob::slotResult(
Job *job )
4341 UDSEntry::ConstIterator it2 = entry.begin();
4343 for( ; it2 != entry.end(); it2++ )
4347 bDir = S_ISDIR( (mode_t)(*it2).m_long );
4352 bLink = !((*it2).m_str.isEmpty());
4355 else if ( ((*it2).m_uds) ==
UDS_SIZE )
4360 if (atomsFound==3)
break;
4365 subjobs.remove( job );
4366 assert( subjobs.isEmpty() );
4372 if ( url.isLocalFile() && !m_parentDirs.contains( url.path(-1) ) )
4373 m_parentDirs.append( url.path(-1) );
4375 if ( !KProtocolInfo::canDeleteRecursive( url ) ) {
4378 state = STATE_LISTING;
4382 connect(newjob, TQ_SIGNAL(entries(
TDEIO::Job *,
4383 const TDEIO::UDSEntryList& )),
4385 const TDEIO::UDSEntryList& )));
4396 symlinks.append( url );
4399 files.append( url );
4401 if ( url.isLocalFile() && !m_parentDirs.contains( url.directory(
false) ) )
4402 m_parentDirs.append( url.directory(
false) );
4413 subjobs.remove( job );
4414 assert( subjobs.isEmpty() );
4418 case STATE_DELETING_FILES:
4424 subjobs.remove( job );
4425 assert( subjobs.isEmpty() );
4430 case STATE_DELETING_DIRS:
4436 subjobs.remove( job );
4437 assert( subjobs.isEmpty() );
4453 srcList.append( src );
4465 bool showProgressInfo)
4466 :
TransferJob(url, 0, TQByteArray(), TQByteArray(), showProgressInfo)
4468 m_waitQueue.setAutoDelete(
true);
4469 m_activeQueue.setAutoDelete(
true);
4475 GetRequest *entry =
new GetRequest(
id,
url,
metaData);
4476 entry->metaData[
"request-id"] = TQString(
"%1").arg(
id);
4477 m_waitQueue.append(entry);
4480 void MultiGetJob::flushQueue(TQPtrList<GetRequest> &queue)
4485 for(entry = m_waitQueue.first(); entry; )
4487 if ((m_url.protocol() == entry->url.protocol()) &&
4488 (m_url.host() == entry->url.host()) &&
4489 (m_url.port() == entry->url.port()) &&
4490 (m_url.user() == entry->url.user()))
4493 queue.append(entry);
4494 entry = m_waitQueue.current();
4498 entry = m_waitQueue.next();
4502 TDEIO_ARGS << (TQ_INT32) queue.count();
4503 for(entry = queue.first(); entry; entry = queue.next())
4505 stream << entry->url << entry->metaData;
4507 m_packedArgs = packedArgs;
4508 m_command = CMD_MULTI_GET;
4509 m_outgoingMetaData.clear();
4512 void MultiGetJob::start(
Slave *slave)
4515 GetRequest *entry = m_waitQueue.take(0);
4516 m_activeQueue.append(entry);
4520 if (!entry->url.protocol().startsWith(
"http"))
4523 TDEIO_ARGS << entry->url;
4524 m_packedArgs = packedArgs;
4525 m_outgoingMetaData = entry->metaData;
4526 m_command = CMD_GET;
4527 b_multiGetActive =
false;
4531 flushQueue(m_activeQueue);
4532 b_multiGetActive =
true;
4535 TransferJob::start(slave);
4538 bool MultiGetJob::findCurrentEntry()
4540 if (b_multiGetActive)
4542 long id = m_incomingMetaData[
"request-id"].toLong();
4543 for(GetRequest *entry = m_activeQueue.first(); entry; entry = m_activeQueue.next())
4545 if (entry->id ==
id)
4547 m_currentEntry = entry;
4556 m_currentEntry = m_activeQueue.first();
4557 return (m_currentEntry != 0);
4561 void MultiGetJob::slotRedirection(
const KURL &url)
4563 if (!findCurrentEntry())
return;
4564 if (tdeApp && !tdeApp->authorizeURLAction(
"redirect", m_url,
url))
4566 kdWarning(7007) <<
"MultiGetJob: Redirection from " << m_currentEntry->url <<
" to " <<
url <<
" REJECTED!" << endl;
4569 m_redirectionURL =
url;
4570 if (m_currentEntry->url.hasUser() && !
url.hasUser() && (m_currentEntry->url.host().lower() ==
url.host().lower()))
4571 m_redirectionURL.setUser(m_currentEntry->url.user());
4572 get(m_currentEntry->id, m_redirectionURL, m_currentEntry->metaData);
4576 void MultiGetJob::slotFinished()
4578 if (!findCurrentEntry())
return;
4579 if (m_redirectionURL.isEmpty())
4582 emit
result(m_currentEntry->id);
4584 m_redirectionURL = KURL();
4586 m_incomingMetaData.clear();
4587 m_activeQueue.removeRef(m_currentEntry);
4588 if (m_activeQueue.count() == 0)
4590 if (m_waitQueue.count() == 0)
4593 TransferJob::slotFinished();
4600 GetRequest *entry = m_waitQueue.at(0);
4608 void MultiGetJob::slotData(
const TQByteArray &_data)
4610 if(!m_currentEntry)
return;
4611 if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error)
4612 emit
data(m_currentEntry->id, _data);
4615 void MultiGetJob::slotMimetype(
const TQString &_mimetype )
4617 if (b_multiGetActive)
4619 TQPtrList<GetRequest> newQueue;
4620 flushQueue(newQueue);
4621 if (!newQueue.isEmpty())
4623 while(!newQueue.isEmpty())
4624 m_activeQueue.append(newQueue.take(0));
4625 m_slave->
send( m_command, m_packedArgs );
4628 if (!findCurrentEntry())
return;
4629 emit
mimetype(m_currentEntry->id, _mimetype);
4635 job->
get(
id, url, metaData);
4641 CacheInfo::CacheInfo(
const KURL &url)
4646 TQString CacheInfo::cachedFileName()
4648 const TQChar separator =
'_';
4650 TQString CEF = m_url.path();
4652 int p = CEF.find(
'/');
4657 p = CEF.find(
'/', p);
4660 TQString host = m_url.host().lower();
4661 CEF = host + CEF +
'_';
4664 if (dir[dir.length()-1] !=
'/')
4667 int l = m_url.host().length();
4668 for(
int i = 0; i < l; i++)
4670 if (host[i].isLetter() && (host[i] !=
'w'))
4676 if (dir[dir.length()-1] ==
'/')
4679 unsigned long hash = 0x00000000;
4680 TQCString u = m_url.url().latin1();
4681 for(
int i = u.length(); i--;)
4683 hash = (hash * 12211 + u[i]) % 2147483563;
4686 TQString hashString;
4687 hashString.sprintf(
"%08lx", hash);
4689 CEF = CEF + hashString;
4691 CEF = dir +
"/" + CEF;
4696 TQFile *CacheInfo::cachedFile()
4699 const char *mode = (readWrite ?
"rb+" :
"rb");
4701 const char *mode = (readWrite ?
"r+" :
"r");
4704 FILE *fs = fopen(TQFile::encodeName(CEF), mode);
4712 if (ok && (!fgets(buffer, 400, fs)))
4714 if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
4718 time_t currentDate = time(0);
4721 if (ok && (!fgets(buffer, 400, fs)))
4725 int l = strlen(buffer);
4728 if (m_.url.url() != buffer)
4735 if (ok && (!fgets(buffer, 400, fs)))
4739 date = (time_t) strtoul(buffer, 0, 10);
4740 if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge))
4742 m_bMustRevalidate =
true;
4743 m_expireDate = currentDate;
4748 m_cacheExpireDateOffset = ftell(fs);
4749 if (ok && (!fgets(buffer, 400, fs)))
4755 date = (time_t) strtoul(buffer, 0, 10);
4757 if (!date || difftime(currentDate, date) >= 0)
4758 m_bMustRevalidate =
true;
4759 m_expireDate = date;
4764 if (ok && (!fgets(buffer, 400, fs)))
4768 m_etag = TQString(buffer).stripWhiteSpace();
4772 if (ok && (!fgets(buffer, 400, fs)))
4776 m_lastModified = TQString(buffer).stripWhiteSpace();
4784 unlink( TQFile::encodeName(CEF) );
4789 void CacheInfo::flush()
4791 cachedFile().remove();
4794 void CacheInfo::touch()
4798 void CacheInfo::setExpireDate(
int);
4799 void CacheInfo::setExpireTimeout(
int);
4802 int CacheInfo::creationDate();
4803 int CacheInfo::expireDate();
4804 int CacheInfo::expireTimeout();
4807 void Job::virtual_hook(
int,
void* )
4810 void SimpleJob::virtual_hook(
int id,
void* data )
4811 { TDEIO::Job::virtual_hook(
id, data ); }
4813 void MkdirJob::virtual_hook(
int id,
void* data )
4814 { SimpleJob::virtual_hook(
id, data ); }
4816 void StatJob::virtual_hook(
int id,
void* data )
4817 { SimpleJob::virtual_hook(
id, data ); }
4819 void TransferJob::virtual_hook(
int id,
void* data )
4820 { SimpleJob::virtual_hook(
id,
data ); }
4822 void MultiGetJob::virtual_hook(
int id,
void* data )
4823 { TransferJob::virtual_hook(
id,
data ); }
4825 void MimetypeJob::virtual_hook(
int id,
void* data )
4826 { TransferJob::virtual_hook(
id,
data ); }
4828 void FileCopyJob::virtual_hook(
int id,
void* data )
4829 { Job::virtual_hook(
id, data ); }
4831 void ListJob::virtual_hook(
int id,
void* data )
4832 { SimpleJob::virtual_hook(
id, data ); }
4834 void CopyJob::virtual_hook(
int id,
void* data )
4835 { Job::virtual_hook(
id, data ); }
4837 void DeleteJob::virtual_hook(
int id,
void* data )
4838 { Job::virtual_hook(
id, data ); }
4840 void LocalURLJob::virtual_hook(
int id,
void* data )
4841 { Job::virtual_hook(
id, data ); }
4844 #include "jobclasses.moc"