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 QString query = url.query();
00085 if ( !url.fileName().isEmpty() )
00086 url.cd("..");
00087 url.setQuery( query );
00088 kdDebug(5006) << "SieveJob::schedule: listDir's real URL: " << url.prettyURL()
00089 << endl;
00090 mJob = KIO::listDir( url );
00091 connect( mJob, SIGNAL(entries(KIO::Job*,const KIO::UDSEntryList&)),
00092 SLOT(slotEntries(KIO::Job*,const KIO::UDSEntryList&)) );
00093 break;
00094 }
00095 case List:
00096 kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
00097 {
00098 mJob = KIO::listDir( mUrl );
00099 connect( mJob, SIGNAL( entries(KIO::Job *, const KIO::UDSEntryList & ) ),
00100 SLOT( slotEntries( KIO::Job *, const KIO::UDSEntryList & ) ) );
00101 break;
00102 }
00103 case Delete:
00104 kdDebug(5006) << "SieveJob::schedule: delete( " << mUrl.prettyURL() << " )" << endl;
00105 mJob = KIO::del( mUrl );
00106 break;
00107 default:
00108 assert( 0 );
00109 }
00110
00111 connect( mJob, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)) );
00112 }
00113
00114 void SieveJob::slotData( Job *, const QByteArray & data ) {
00115
00116 if ( data.size() == 0 )
00117 return;
00118
00119
00120 if ( !mDec )
00121 mDec = QTextCodec::codecForMib( 106 )->makeDecoder();
00122
00123
00124 mScript += mDec->toUnicode( data.data(), data.size() );
00125 }
00126
00127 void SieveJob::slotDataReq( Job *, QByteArray & data ) {
00128
00129 if ( mScript.isEmpty() ) {
00130 data = QByteArray();
00131 return;
00132 }
00133
00134
00135 data = mScript.utf8();
00136
00137
00138 if ( data.size() > 0 && data[(int)data.size() - 1] == '\0' )
00139 data.resize( data.size() - 1 );
00140
00141
00142 mScript = QString::null;
00143 }
00144
00145 void SieveJob::slotEntries( Job *, const UDSEntryList & l ) {
00146
00147 for ( UDSEntryList::const_iterator it = l.begin() ; it != l.end() ; ++it ) {
00148
00149
00150
00151 QString filename;
00152 bool isActive = false;
00153 for ( UDSEntry::const_iterator et = (*it).begin() ; et != (*it).end() ; ++ et ) {
00154 if ( ( *et ).m_uds == KIO::UDS_NAME ) {
00155 filename = ( *et ).m_str;
00156 mAvailableScripts.append( filename );
00157 } else if ( ( *et ).m_uds == KIO::UDS_ACCESS && ( *et ).m_long == 0700 )
00158 isActive = true;
00159 }
00160
00161 if ( isActive )
00162 mActiveScriptName = filename;
00163
00164 if ( mFileExists == DontKnow && filename == mUrl.fileName() )
00165 mFileExists = Yes;
00166 emit item( this, filename, isActive );
00167 if ( mFileExists == Yes && !mActiveScriptName.isEmpty() )
00168 return;
00169 }
00170 }
00171
00172 void SieveJob::slotResult( Job * job ) {
00173 Command lastCmd = mCommands.top();
00174
00175
00176
00177
00178 if ( lastCmd == SearchActive && mFileExists == DontKnow && !job->error() )
00179 mFileExists = No;
00180
00181 mCommands.pop();
00182 delete mDec; mDec = 0;
00183
00184 if ( mSieveCapabilities.empty() ) {
00185 mSieveCapabilities = QStringList::split( ' ', job->queryMetaData( "sieveExtensions" ) );
00186 kdDebug(5006) << "Received Sieve extensions supported:" << endl
00187 << mSieveCapabilities.join("\n") << endl;
00188 }
00189
00190
00191 if ( job->error() ) {
00192 job->showErrorDialog( 0 );
00193
00194 emit result( this, false, mScript, mUrl.fileName() == mActiveScriptName );
00195
00196 if ( lastCmd == List )
00197 emit gotList( this, false, mAvailableScripts, mActiveScriptName );
00198 else
00199 emit gotScript( this, false, mScript, mUrl.fileName() == mActiveScriptName );
00200
00201 mJob = 0;
00202 delete this;
00203 return;
00204 }
00205
00206
00207 if ( !mCommands.empty() ) {
00208
00209 if ( mCommands.top() == Get && mFileExists == No ) {
00210 mScript = QString::null;
00211 mCommands.pop();
00212 }
00213 }
00214
00215 if ( mCommands.empty() ) {
00216
00217 emit result( this, true, mScript, mUrl.fileName() == mActiveScriptName );
00218 if ( lastCmd == List )
00219 emit gotList( this, true, mAvailableScripts, mActiveScriptName );
00220 else
00221 emit gotScript( this, true, mScript, mUrl.fileName() == mActiveScriptName );
00222
00223 mJob = 0;
00224 delete this;
00225 return;
00226 } else {
00227
00228 schedule( mCommands.top() );
00229 }
00230 }
00231
00232 SieveJob * SieveJob::put( const KURL & dest, const QString & script,
00233 bool makeActive, bool wasActive ) {
00234 QValueStack<Command> commands;
00235 if ( makeActive )
00236 commands.push( Activate );
00237 if ( wasActive )
00238 commands.push( Deactivate );
00239 commands.push( Put );
00240 return new SieveJob( dest, script, commands );
00241 }
00242
00243 SieveJob * SieveJob::get( const KURL & src ) {
00244 QValueStack<Command> commands;
00245 commands.push( Get );
00246 commands.push( SearchActive );
00247 return new SieveJob( src, QString::null, commands );
00248 }
00249
00250 SieveJob * SieveJob::list( const KURL & src ) {
00251 QValueStack<Command> commands;
00252 commands.push( List );
00253 return new SieveJob( src, QString::null, commands );
00254 }
00255 SieveJob * SieveJob::del( const KURL & url ) {
00256 QValueStack<Command> commands;
00257 commands.push( Delete );
00258 return new SieveJob( url, QString::null, commands );
00259 }
00260
00261 SieveJob * SieveJob::activate( const KURL & url ) {
00262 QValueStack<Command> commands;
00263 commands.push( Activate );
00264 commands.push( Deactivate );
00265 return new SieveJob( url, QString::null, commands );
00266 }
00267
00268 }
00269
00270 #include "sievejob.moc"
00271
00272
00273