kmail

sievejob.cpp
1 /*
2  sievejob.h
3 
4  KMail, the KDE mail client.
5  Copyright (c) 2002 Marc Mutz <mutz@kde.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License,
9  version 2.0, as published by the Free Software Foundation.
10  You should have received a copy of the GNU General Public License
11  along with this program; if not, write to the Free Software Foundation,
12  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
13 */
14 
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18 
19 #include "sievejob.h"
20 
21 #include <tdeio/job.h>
22 using TDEIO::Job;
23 // <tdeio/global.h>
24 using TDEIO::UDSAtomTypes;
25 using TDEIO::UDSEntryList;
26 using TDEIO::UDSEntry;
27 #include <kdebug.h>
28 
29 #include <tqtextcodec.h>
30 
31 #include <cassert>
32 
33 namespace KMail {
34 
35  SieveJob::SieveJob( const KURL & url, const TQString & script,
36  const TQValueStack<Command> & commands,
37  TQObject * parent, const char * name )
38  : TQObject( parent, name ),
39  mUrl( url ), mJob( 0 ), mDec( 0 ),
40  mScript( script ), mFileExists( DontKnow ), mCommands( commands ),
41  mShowProgressInfo(true)
42  {
43  assert( !commands.isEmpty() );
44  schedule( commands.top(), true );
45  }
46 
47  SieveJob::SieveJob( const KURL & url, const TQString & script,
48  const TQValueStack<Command> & commands,
49  bool showProgressInfo,
50  TQObject * parent, const char * name )
51  : TQObject( parent, name ),
52  mUrl( url ), mJob( 0 ), mDec( 0 ),
53  mScript( script ), mFileExists( DontKnow ), mCommands( commands ),
54  mShowProgressInfo(showProgressInfo)
55  {
56  assert( !commands.isEmpty() );
57  schedule( commands.top(), showProgressInfo );
58  }
59 
60  SieveJob::~SieveJob() {
61  kill();
62  delete mDec;
63  kdDebug(5006) << "~SieveJob()" << endl;
64  }
65 
66  void SieveJob::kill( bool quiet ) {
67  if ( mJob ) mJob->kill( quiet );
68  }
69 
70  void SieveJob::schedule( Command command, bool showProgressInfo ) {
71  switch ( command ) {
72  case Get:
73  kdDebug(5006) << "SieveJob::schedule: get( " << mUrl.prettyURL() << " )" << endl;
74  mJob = TDEIO::get( mUrl, false /*reload*/, showProgressInfo );
75  connect( mJob, TQ_SIGNAL(data(TDEIO::Job*,const TQByteArray&)),
76  TQ_SLOT(slotData(TDEIO::Job*,const TQByteArray&)) );
77  break;
78  case Put:
79  kdDebug(5006) << "SieveJob::schedule: put( " << mUrl.prettyURL() << " )" << endl;
80  mJob = TDEIO::put( mUrl, 0600, true /*overwrite*/, false /*resume*/, showProgressInfo );
81  connect( mJob, TQ_SIGNAL(dataReq(TDEIO::Job*,TQByteArray&)),
82  TQ_SLOT(slotDataReq(TDEIO::Job*,TQByteArray&)) );
83  break;
84  case Activate:
85  kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0700 )"
86  << endl;
87  mJob = TDEIO::chmod( mUrl, 0700 );
88  break;
89  case Deactivate:
90  kdDebug(5006) << "SieveJob::schedule: chmod( " << mUrl.prettyURL() << ", 0600 )"
91  << endl;
92  mJob = TDEIO::chmod( mUrl, 0600 );
93  break;
94  case SearchActive:
95  kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
96  {
97  KURL url = mUrl;
98  TQString query = url.query(); //save query part, because KURL::cd() erases it
99  if ( !url.fileName().isEmpty() )
100  url.cd("..");
101  url.setQuery( query );
102  kdDebug(5006) << "SieveJob::schedule: listDir's real URL: " << url.prettyURL()
103  << endl;
104  mJob = TDEIO::listDir( url, showProgressInfo );
105  connect( mJob, TQ_SIGNAL(entries(TDEIO::Job*,const TDEIO::UDSEntryList&)),
106  TQ_SLOT(slotEntries(TDEIO::Job*,const TDEIO::UDSEntryList&)) );
107  break;
108  }
109  case List:
110  kdDebug(5006) << "SieveJob::schedule: listDir( " << mUrl.prettyURL() << " )" << endl;
111  {
112  mJob = TDEIO::listDir( mUrl, showProgressInfo );
113  connect( mJob, TQ_SIGNAL( entries(TDEIO::Job *, const TDEIO::UDSEntryList & ) ),
114  TQ_SLOT( slotEntries( TDEIO::Job *, const TDEIO::UDSEntryList & ) ) );
115  break;
116  }
117  case Delete:
118  kdDebug(5006) << "SieveJob::schedule: delete( " << mUrl.prettyURL() << " )" << endl;
119  mJob = TDEIO::del( mUrl, false/*shred*/, showProgressInfo );
120  break;
121  default:
122  assert( 0 );
123  }
124  mJob->setInteractive(showProgressInfo);
125  // common to all jobs:
126  connect( mJob, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotResult(TDEIO::Job*)) );
127  }
128 
129  void SieveJob::slotData( Job *, const TQByteArray & data ) {
130  // check for end-of-data marker:
131  if ( data.size() == 0 )
132  return;
133 
134  // make sure we have a textdecoder;
135  if ( !mDec )
136  mDec = TQTextCodec::codecForMib( 106 /*utf8*/ )->makeDecoder();
137 
138  // decode utf8; add to mScript:
139  mScript += mDec->toUnicode( data.data(), data.size() );
140  }
141 
142  void SieveJob::slotDataReq( Job *, TQByteArray & data ) {
143  // check whether we have already sent our data:
144  if ( mScript.isEmpty() ) {
145  data = TQByteArray(); // end-of-data marker
146  return;
147  }
148 
149  // Convert mScript into UTF-8:
150  data = mScript.utf8();
151 
152  // "data" contains a trailing NUL, remove:
153  if ( data.size() > 0 && data[(int)data.size() - 1] == '\0' )
154  data.resize( data.size() - 1 );
155 
156  // mark mScript sent:
157  mScript = TQString();
158  }
159 
160  void SieveJob::slotEntries( Job *, const UDSEntryList & l ) {
161  // loop over entries:
162  for ( UDSEntryList::const_iterator it = l.begin() ; it != l.end() ; ++it ) {
163  // Loop over all UDS atoms to find the UDS_ACCESS and UDS_NAME atoms;
164  // note if we find an exec'able file ( == active script )
165  // or the requested filename (mUrl.fileName()).
166  TQString filename;
167  bool isActive = false;
168  for ( UDSEntry::const_iterator et = (*it).begin() ; et != (*it).end() ; ++ et ) {
169  if ( ( *et ).m_uds == TDEIO::UDS_NAME ) {
170  filename = ( *et ).m_str;
171  mAvailableScripts.append( filename );
172  } else if ( ( *et ).m_uds == TDEIO::UDS_ACCESS && ( *et ).m_long == 0700 )
173  isActive = true;
174  }
175 
176  if ( isActive )
177  mActiveScriptName = filename;
178 
179  if ( mFileExists == DontKnow && filename == mUrl.fileName() )
180  mFileExists = Yes;
181  emit item( this, filename, isActive );
182  if ( mFileExists == Yes && !mActiveScriptName.isEmpty() )
183  return; // early return if we have all information
184  }
185  }
186 
187  void SieveJob::slotResult( Job * job ) {
188  Command lastCmd = mCommands.top();
189 
190  // First, let's see if we come back from a SearchActive. If so, set
191  // mFileExists to No if we didn't see the mUrl.fileName() during
192  // listDir...
193  if ( lastCmd == SearchActive && mFileExists == DontKnow && !job->error() )
194  mFileExists = No;
195  // prepare for next round:
196  mCommands.pop();
197  delete mDec; mDec = 0;
198 
199  if ( mSieveCapabilities.empty() ) {
200  mSieveCapabilities = TQStringList::split( ' ', job->queryMetaData( "sieveExtensions" ) );
201  kdDebug(5006) << "Received Sieve extensions supported:" << endl
202  << mSieveCapabilities.join("\n") << endl;
203  }
204 
205  // check for errors:
206  if ( job->error() ) {
207  if ( job->isInteractive() ) {
208  job->showErrorDialog( 0 );
209  }
210 
211  emit result( this, false, mScript, mUrl.fileName() == mActiveScriptName );
212 
213  if ( lastCmd == List )
214  emit gotList( this, false, mAvailableScripts, mActiveScriptName );
215  else
216  emit gotScript( this, false, mScript, mUrl.fileName() == mActiveScriptName );
217 
218  mJob = 0;
219  delete this;
220  return;
221  }
222 
223  // check for new tasks:
224  if ( !mCommands.empty() ) {
225  // Don't fail get'ting a non-existant script:
226  if ( mCommands.top() == Get && mFileExists == No ) {
227  mScript = TQString();
228  mCommands.pop();
229  }
230  }
231 
232  if ( mCommands.empty() ) {
233  // was last command; report success and delete this object:
234  emit result( this, true, mScript, mUrl.fileName() == mActiveScriptName );
235  if ( lastCmd == List )
236  emit gotList( this, true, mAvailableScripts, mActiveScriptName );
237  else
238  emit gotScript( this, true, mScript, mUrl.fileName() == mActiveScriptName );
239 
240  mJob = 0; // deletes itself on returning from this slot
241  delete this;
242  return;
243  } else {
244  // schedule the next command:
245  schedule( mCommands.top(), mShowProgressInfo );
246  }
247  }
248 
249  SieveJob * SieveJob::put( const KURL & dest, const TQString & script,
250  bool makeActive, bool wasActive ) {
251  TQValueStack<Command> commands;
252  if ( makeActive )
253  commands.push( Activate );
254  if ( wasActive )
255  commands.push( Deactivate );
256  commands.push( Put );
257  return new SieveJob( dest, script, commands );
258  }
259 
260  SieveJob * SieveJob::get( const KURL & src, bool showProgressInfo ) {
261  TQValueStack<Command> commands;
262  commands.push( Get );
263  commands.push( SearchActive );
264  return new SieveJob( src, TQString(), commands, showProgressInfo );
265  }
266 
267  SieveJob * SieveJob::list( const KURL & src ) {
268  TQValueStack<Command> commands;
269  commands.push( List );
270  return new SieveJob( src, TQString(), commands );
271  }
272  SieveJob * SieveJob::del( const KURL & url ) {
273  TQValueStack<Command> commands;
274  commands.push( Delete );
275  return new SieveJob( url, TQString(), commands );
276  }
277 
278  SieveJob * SieveJob::desactivate( const KURL & url ) {
279  TQValueStack<Command> commands;
280  commands.push( Deactivate );
281  return new SieveJob( url, TQString(), commands );
282  }
283 
284  SieveJob * SieveJob::activate( const KURL & url ) {
285  TQValueStack<Command> commands;
286  commands.push( Activate );
287  return new SieveJob( url, TQString(), commands );
288  }
289 
290 } // namespace KMail
291 
292 #include "sievejob.moc"
folderdiaquotatab.h
Definition: aboutdata.cpp:40