00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef HAVE_CONFIG_H
00016 #include <config.h>
00017 #endif
00018
00019 #include "sievejob.h"
00020
00021 #include <kio/job.h>
00022 using KIO::Job;
00023
00024 using KIO::UDSAtomTypes;
00025 using KIO::UDSEntryList;
00026 using KIO::UDSEntry;
00027 #include <kdebug.h>
00028
00029 #include <qtextcodec.h>
00030
00031 #include <cassert>
00032
00033 namespace KMail {
00034
00035 SieveJob::SieveJob( const KURL & url, const QString & script,
00036 const QValueStack<Command> & commands,
00037 QObject * parent, const char * name )
00038 : QObject( parent, name ),
00039 mUrl( url ), mJob( 0 ), mDec( 0 ),
00040 mScript( script ), mFileExists( DontKnow ), mCommands( commands )
00041 {
00042 assert( !commands.isEmpty() );
00043 schedule( commands.top() );
00044 }
00045
00046 SieveJob::~SieveJob() {
00047 kill();
00048 delete mDec;
00049 kdDebug(5006) << "~SieveJob()" << endl;
00050 }
00051
00052 void SieveJob::kill( bool quiet ) {
00053 if ( mJob ) mJob->kill( quiet );
00054 }
00055
00056 void SieveJob::schedule( Command command ) {
00057 switch ( command ) {
00058 case Get:
00059 kdDebug(5006) << "SieveJob::schedule: get( " << mUrl.prettyURL() << " )" << endl;
00060 mJob = KIO::get( mUrl );
00061 connect( mJob, SIGNAL(data(KIO::Job*,const QByteArray&)),
00062 SLOT(slotData(KIO::Job*,const QByteArray&)) );
00063 break;
00064 case Put:
00065 kdDebug(5006) << "SieveJob::schedule: put( " << mUrl.prettyURL() << " )" << endl;
00066 mJob = KIO::put( mUrl, 0600, true , false );
00067 connect( mJob, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
00068 SLOT(slotDataReq(KIO::Job*,QByteArray&)) );
00069 break;
00070 case Activate:
00071 kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0700 )"
00072 << endl;
00073 mJob = KIO::chmod( mUrl, 0700 );
00074 break;
00075 case Deactivate:
00076 kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0600 )"
00077 << endl;
00078 mJob = KIO::chmod( mUrl, 0600 );
00079 break;
00080 case SearchActive:
00081 kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
00082 {
00083 KURL url = mUrl;
00084 url.cd("..");
00085 kdDebug(5006) << "SieveJob::schedule: listDir's real URL: " << url.prettyURL()
00086 << endl;
00087 mJob = KIO::listDir( url );
00088 connect( mJob, SIGNAL(entries(KIO::Job*,const KIO::UDSEntryList&)),
00089 SLOT(slotEntries(KIO::Job*,const KIO::UDSEntryList&)) );
00090 break;
00091 }
00092 default:
00093 assert( 0 );
00094 }
00095
00096 connect( mJob, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)) );
00097 }
00098
00099 void SieveJob::slotData( Job *, const QByteArray & data ) {
00100
00101 if ( data.size() == 0 )
00102 return;
00103
00104
00105 if ( !mDec )
00106 mDec = QTextCodec::codecForMib( 106 )->makeDecoder();
00107
00108
00109 mScript += mDec->toUnicode( data.data(), data.size() );
00110 }
00111
00112 void SieveJob::slotDataReq( Job *, QByteArray & data ) {
00113
00114 if ( mScript.isEmpty() ) {
00115 data = QByteArray();
00116 return;
00117 }
00118
00119
00120 data = mScript.utf8();
00121
00122
00123 if ( data.size() > 0 && data[(int)data.size() - 1] == '\0' )
00124 data.resize( data.size() - 1 );
00125
00126
00127 mScript = QString::null;
00128 }
00129
00130 void SieveJob::slotEntries( Job *, const UDSEntryList & l ) {
00131 if ( !mActiveScriptName.isEmpty() && mFileExists != DontKnow )
00132 return;
00133
00134 for ( UDSEntryList::const_iterator it = l.begin() ; it != l.end() ; ++it ) {
00135
00136
00137
00138 QString filename;
00139 bool isActive = false;
00140 for ( UDSEntry::const_iterator et = (*it).begin() ; et != (*it).end() ; ++ et )
00141 if ( (*et).m_uds == KIO::UDS_NAME ) {
00142 if ( isActive ) {
00143 mActiveScriptName = (*et).m_str;
00144 break;
00145 } else
00146 filename = (*et).m_str;
00147 } else if ( (*et).m_uds == KIO::UDS_ACCESS && (*et).m_long == 0700 ) {
00148 if ( !filename.isEmpty() ) {
00149 mActiveScriptName = filename;
00150 break;
00151 } else
00152 isActive = true;
00153 }
00154 if ( mFileExists == DontKnow && filename == mUrl.fileName() )
00155 mFileExists = Yes;
00156 if ( mFileExists == Yes && !mActiveScriptName.isEmpty() )
00157 return;
00158 }
00159 }
00160
00161 void SieveJob::slotResult( Job * job ) {
00162
00163
00164
00165 if ( mCommands.top() == SearchActive &&
00166 mFileExists == DontKnow && !job->error() )
00167 mFileExists = No;
00168
00169 mCommands.pop();
00170 delete mDec; mDec = 0;
00171
00172 if ( mSieveCapabilities.empty() ) {
00173 mSieveCapabilities = QStringList::split( ' ', job->queryMetaData( "sieveExtensions" ) );
00174 kdDebug(5006) << "received sieve extensions supported:" << endl
00175 << mSieveCapabilities.join("\n") << endl;
00176 }
00177
00178
00179 if ( job->error() ) {
00180 job->showErrorDialog( 0 );
00181 emit result( this, false, mScript,
00182 mUrl.fileName() == mActiveScriptName );
00183 mJob = 0;
00184 delete this;
00185 return;
00186 }
00187
00188
00189 if ( !mCommands.empty() ) {
00190
00191 if ( mCommands.top() == Get && mFileExists == No ) {
00192 mScript = QString::null;
00193 mCommands.pop();
00194 }
00195 }
00196
00197 if ( mCommands.empty() ) {
00198
00199 emit result( this, true, mScript, mUrl.fileName() == mActiveScriptName );
00200 mJob = 0;
00201 delete this;
00202 return;
00203 } else {
00204
00205 schedule( mCommands.top() );
00206 }
00207 }
00208
00209 SieveJob * SieveJob::put( const KURL & dest, const QString & script,
00210 bool makeActive, bool wasActive ) {
00211 QValueStack<Command> commands;
00212 if ( makeActive )
00213 commands.push( Activate );
00214 if ( wasActive )
00215 commands.push( Deactivate );
00216 commands.push( Put );
00217 return new SieveJob( dest, script, commands );
00218 }
00219
00220 SieveJob * SieveJob::get( const KURL & src ) {
00221 QValueStack<Command> commands;
00222 commands.push( Get );
00223 commands.push( SearchActive );
00224 return new SieveJob( src, QString::null, commands );
00225 }
00226
00227
00228 }
00229
00230 #include "sievejob.moc"