You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
9.1 KiB
290 lines
9.1 KiB
/* -*- c++ -*-
|
|
sievejob.h
|
|
|
|
KMail, the KDE mail client.
|
|
Copyright (c) 2002 Marc Mutz <mutz@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License,
|
|
version 2.0, as published by the Free Software Foundation.
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include "sievejob.h"
|
|
|
|
#include <kio/job.h>
|
|
using KIO::Job;
|
|
// <kio/global.h>
|
|
using KIO::UDSAtomTypes;
|
|
using KIO::UDSEntryList;
|
|
using KIO::UDSEntry;
|
|
#include <kdebug.h>
|
|
|
|
#include <tqtextcodec.h>
|
|
|
|
#include <cassert>
|
|
|
|
namespace KMail {
|
|
|
|
SieveJob::SieveJob( const KURL & url, const TQString & script,
|
|
const TQValueStack<Command> & commands,
|
|
TQObject * parent, const char * name )
|
|
: TQObject( parent, name ),
|
|
mUrl( url ), mJob( 0 ), mDec( 0 ),
|
|
mScript( script ), mFileExists( DontKnow ), mCommands( commands ),
|
|
mShowProgressInfo(true)
|
|
{
|
|
assert( !commands.isEmpty() );
|
|
schedule( commands.top(), true );
|
|
}
|
|
|
|
SieveJob::SieveJob( const KURL & url, const TQString & script,
|
|
const TQValueStack<Command> & commands,
|
|
bool showProgressInfo,
|
|
TQObject * parent, const char * name )
|
|
: TQObject( parent, name ),
|
|
mUrl( url ), mJob( 0 ), mDec( 0 ),
|
|
mScript( script ), mFileExists( DontKnow ), mCommands( commands ),
|
|
mShowProgressInfo(showProgressInfo)
|
|
{
|
|
assert( !commands.isEmpty() );
|
|
schedule( commands.top(), showProgressInfo );
|
|
}
|
|
|
|
SieveJob::~SieveJob() {
|
|
kill();
|
|
delete mDec;
|
|
kdDebug(5006) << "~SieveJob()" << endl;
|
|
}
|
|
|
|
void SieveJob::kill( bool quiet ) {
|
|
if ( mJob ) mJob->kill( quiet );
|
|
}
|
|
|
|
void SieveJob::schedule( Command command, bool showProgressInfo ) {
|
|
switch ( command ) {
|
|
case Get:
|
|
kdDebug(5006) << "SieveJob::schedule: get( " << mUrl.prettyURL() << " )" << endl;
|
|
mJob = KIO::get( mUrl, false /*reload*/, showProgressInfo );
|
|
connect( mJob, TQT_SIGNAL(data(KIO::Job*,const TQByteArray&)),
|
|
TQT_SLOT(slotData(KIO::Job*,const TQByteArray&)) );
|
|
break;
|
|
case Put:
|
|
kdDebug(5006) << "SieveJob::schedule: put( " << mUrl.prettyURL() << " )" << endl;
|
|
mJob = KIO::put( mUrl, 0600, true /*overwrite*/, false /*resume*/, showProgressInfo );
|
|
connect( mJob, TQT_SIGNAL(dataReq(KIO::Job*,TQByteArray&)),
|
|
TQT_SLOT(slotDataReq(KIO::Job*,TQByteArray&)) );
|
|
break;
|
|
case Activate:
|
|
kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0700 )"
|
|
<< endl;
|
|
mJob = KIO::chmod( mUrl, 0700 );
|
|
break;
|
|
case Deactivate:
|
|
kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0600 )"
|
|
<< endl;
|
|
mJob = KIO::chmod( mUrl, 0600 );
|
|
break;
|
|
case SearchActive:
|
|
kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
|
|
{
|
|
KURL url = mUrl;
|
|
TQString query = url.query(); //save query part, because KURL::cd() erases it
|
|
if ( !url.fileName().isEmpty() )
|
|
url.cd("..");
|
|
url.setQuery( query );
|
|
kdDebug(5006) << "SieveJob::schedule: listDir's real URL: " << url.prettyURL()
|
|
<< endl;
|
|
mJob = KIO::listDir( url, showProgressInfo );
|
|
connect( mJob, TQT_SIGNAL(entries(KIO::Job*,const KIO::UDSEntryList&)),
|
|
TQT_SLOT(slotEntries(KIO::Job*,const KIO::UDSEntryList&)) );
|
|
break;
|
|
}
|
|
case List:
|
|
kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
|
|
{
|
|
mJob = KIO::listDir( mUrl, showProgressInfo );
|
|
connect( mJob, TQT_SIGNAL( entries(KIO::Job *, const KIO::UDSEntryList & ) ),
|
|
TQT_SLOT( slotEntries( KIO::Job *, const KIO::UDSEntryList & ) ) );
|
|
break;
|
|
}
|
|
case Delete:
|
|
kdDebug(5006) << "SieveJob::schedule: delete( " << mUrl.prettyURL() << " )" << endl;
|
|
mJob = KIO::del( mUrl, false/*shred*/, showProgressInfo );
|
|
break;
|
|
default:
|
|
assert( 0 );
|
|
}
|
|
mJob->setInteractive(showProgressInfo);
|
|
// common to all jobs:
|
|
connect( mJob, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotResult(KIO::Job*)) );
|
|
}
|
|
|
|
void SieveJob::slotData( Job *, const TQByteArray & data ) {
|
|
// check for end-of-data marker:
|
|
if ( data.size() == 0 )
|
|
return;
|
|
|
|
// make sure we have a textdecoder;
|
|
if ( !mDec )
|
|
mDec = TQTextCodec::codecForMib( 106 /*utf8*/ )->makeDecoder();
|
|
|
|
// decode utf8; add to mScript:
|
|
mScript += mDec->toUnicode( data.data(), data.size() );
|
|
}
|
|
|
|
void SieveJob::slotDataReq( Job *, TQByteArray & data ) {
|
|
// check whether we have already sent our data:
|
|
if ( mScript.isEmpty() ) {
|
|
data = TQByteArray(); // end-of-data marker
|
|
return;
|
|
}
|
|
|
|
// Convert mScript into UTF-8:
|
|
data = mScript.utf8();
|
|
|
|
// "data" contains a trailing NUL, remove:
|
|
if ( data.size() > 0 && data[(int)data.size() - 1] == '\0' )
|
|
data.resize( data.size() - 1 );
|
|
|
|
// mark mScript sent:
|
|
mScript = TQString::null;
|
|
}
|
|
|
|
void SieveJob::slotEntries( Job *, const UDSEntryList & l ) {
|
|
// loop over entries:
|
|
for ( UDSEntryList::const_iterator it = l.begin() ; it != l.end() ; ++it ) {
|
|
// Loop over all UDS atoms to find the UDS_ACCESS and UDS_NAME atoms;
|
|
// note if we find an exec'able file ( == active script )
|
|
// or the requested filename (mUrl.fileName()).
|
|
TQString filename;
|
|
bool isActive = false;
|
|
for ( UDSEntry::const_iterator et = (*it).begin() ; et != (*it).end() ; ++ et ) {
|
|
if ( ( *et ).m_uds == KIO::UDS_NAME ) {
|
|
filename = ( *et ).m_str;
|
|
mAvailableScripts.append( filename );
|
|
} else if ( ( *et ).m_uds == KIO::UDS_ACCESS && ( *et ).m_long == 0700 )
|
|
isActive = true;
|
|
}
|
|
|
|
if ( isActive )
|
|
mActiveScriptName = filename;
|
|
|
|
if ( mFileExists == DontKnow && filename == mUrl.fileName() )
|
|
mFileExists = Yes;
|
|
emit item( this, filename, isActive );
|
|
if ( mFileExists == Yes && !mActiveScriptName.isEmpty() )
|
|
return; // early return if we have all information
|
|
}
|
|
}
|
|
|
|
void SieveJob::slotResult( Job * job ) {
|
|
Command lastCmd = mCommands.top();
|
|
|
|
// First, let's see if we come back from a SearchActive. If so, set
|
|
// mFileExists to No if we didn't see the mUrl.fileName() during
|
|
// listDir...
|
|
if ( lastCmd == SearchActive && mFileExists == DontKnow && !job->error() )
|
|
mFileExists = No;
|
|
// prepare for next round:
|
|
mCommands.pop();
|
|
delete mDec; mDec = 0;
|
|
|
|
if ( mSieveCapabilities.empty() ) {
|
|
mSieveCapabilities = TQStringList::split( ' ', job->queryMetaData( "sieveExtensions" ) );
|
|
kdDebug(5006) << "Received Sieve extensions supported:" << endl
|
|
<< mSieveCapabilities.join("\n") << endl;
|
|
}
|
|
|
|
// check for errors:
|
|
if ( job->error() ) {
|
|
if ( job->isInteractive() ) {
|
|
job->showErrorDialog( 0 );
|
|
}
|
|
|
|
emit result( this, false, mScript, mUrl.fileName() == mActiveScriptName );
|
|
|
|
if ( lastCmd == List )
|
|
emit gotList( this, false, mAvailableScripts, mActiveScriptName );
|
|
else
|
|
emit gotScript( this, false, mScript, mUrl.fileName() == mActiveScriptName );
|
|
|
|
mJob = 0;
|
|
delete this;
|
|
return;
|
|
}
|
|
|
|
// check for new tasks:
|
|
if ( !mCommands.empty() ) {
|
|
// Don't fail get'ting a non-existant script:
|
|
if ( mCommands.top() == Get && mFileExists == No ) {
|
|
mScript = TQString::null;
|
|
mCommands.pop();
|
|
}
|
|
}
|
|
|
|
if ( mCommands.empty() ) {
|
|
// was last command; report success and delete this object:
|
|
emit result( this, true, mScript, mUrl.fileName() == mActiveScriptName );
|
|
if ( lastCmd == List )
|
|
emit gotList( this, true, mAvailableScripts, mActiveScriptName );
|
|
else
|
|
emit gotScript( this, true, mScript, mUrl.fileName() == mActiveScriptName );
|
|
|
|
mJob = 0; // deletes itself on returning from this slot
|
|
delete this;
|
|
return;
|
|
} else {
|
|
// schedule the next command:
|
|
schedule( mCommands.top(), mShowProgressInfo );
|
|
}
|
|
}
|
|
|
|
SieveJob * SieveJob::put( const KURL & dest, const TQString & script,
|
|
bool makeActive, bool wasActive ) {
|
|
TQValueStack<Command> commands;
|
|
if ( makeActive )
|
|
commands.push( Activate );
|
|
if ( wasActive )
|
|
commands.push( Deactivate );
|
|
commands.push( Put );
|
|
return new SieveJob( dest, script, commands );
|
|
}
|
|
|
|
SieveJob * SieveJob::get( const KURL & src, bool showProgressInfo ) {
|
|
TQValueStack<Command> commands;
|
|
commands.push( Get );
|
|
commands.push( SearchActive );
|
|
return new SieveJob( src, TQString::null, commands, showProgressInfo );
|
|
}
|
|
|
|
SieveJob * SieveJob::list( const KURL & src ) {
|
|
TQValueStack<Command> commands;
|
|
commands.push( List );
|
|
return new SieveJob( src, TQString::null, commands );
|
|
}
|
|
SieveJob * SieveJob::del( const KURL & url ) {
|
|
TQValueStack<Command> commands;
|
|
commands.push( Delete );
|
|
return new SieveJob( url, TQString::null, commands );
|
|
}
|
|
|
|
SieveJob * SieveJob::activate( const KURL & url ) {
|
|
TQValueStack<Command> commands;
|
|
commands.push( Activate );
|
|
return new SieveJob( url, TQString::null, commands );
|
|
}
|
|
|
|
} // namespace KMail
|
|
|
|
#include "sievejob.moc"
|
|
|
|
// vim: set noet sts=2 ts=8 sw=2:
|
|
|