• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KMBox Library

  • kmbox
mbox.cpp
1/*
2 Copyright (c) 1996-1998 Stefan Taferner <taferner@kde.org>
3 Copyright (c) 2009 Bertjan Broeksema <broeksema@kde.org>
4
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301, USA.
19
20 NOTE: Most of the code inside here is an slightly adjusted version of
21 kdepim/kmail/kmfoldermbox.cpp. This is why I added a line for Stefan Taferner.
22
23 Bertjan Broeksema, april 2009
24*/
25
26#include "mbox.h"
27#include "mbox_p.h"
28#include "mboxentry_p.h"
29
30#include <KDebug>
31#include <KStandardDirs>
32#include <KUrl>
33
34#include <QtCore/QBuffer>
35#include <QtCore/QProcess>
36
37using namespace KMBox;
38
40
41MBox::MBox()
42 : d( new MBoxPrivate( this ) )
43{
44 // Set some sane defaults
45 d->mFileLocked = false;
46 d->mLockType = None;
47
48 d->mUnlockTimer.setInterval( 0 );
49 d->mUnlockTimer.setSingleShot( true );
50}
51
52MBox::~MBox()
53{
54 if ( d->mFileLocked ) {
55 unlock();
56 }
57
58 d->close();
59
60 delete d;
61}
62
63// Appended entries works as follows: When an mbox file is loaded from disk,
64// d->mInitialMboxFileSize is set to the file size at that moment. New entries
65// are stored in memory (d->mAppendedEntries). The initial file size and the size
66// of the buffer determine the offset for the next message to append.
67MBoxEntry MBox::appendMessage( const KMime::Message::Ptr &entry )
68{
69 // It doesn't make sense to add entries when we don't have an reference file.
70 Q_ASSERT( !d->mMboxFile.fileName().isEmpty() );
71
72 const QByteArray rawEntry = MBoxPrivate::escapeFrom( entry->encodedContent() );
73
74 if ( rawEntry.size() <= 0 ) {
75 kDebug() << "Message added to folder `" << d->mMboxFile.fileName()
76 << "' contains no data. Ignoring it.";
77 return MBoxEntry();
78 }
79
80 int nextOffset = d->mAppendedEntries.size(); // Offset of the appended message
81
82 // Make sure the byte array is large enough to check for an end character.
83 // Then check if the required newlines are there.
84 if ( nextOffset < 1 && d->mMboxFile.size() > 0 ) { // Empty, add one empty line
85 d->mAppendedEntries.append( "\n" );
86 ++nextOffset;
87 } else if ( nextOffset == 1 && d->mAppendedEntries.at( 0 ) != '\n' ) {
88 // This should actually not happen, but catch it anyway.
89 if ( d->mMboxFile.size() < 0 ) {
90 d->mAppendedEntries.append( "\n" );
91 ++nextOffset;
92 }
93 } else if ( nextOffset >= 2 ) {
94 if ( d->mAppendedEntries.at( nextOffset - 1 ) != '\n' ) {
95 if ( d->mAppendedEntries.at( nextOffset ) != '\n' ) {
96 d->mAppendedEntries.append( "\n\n" );
97 nextOffset += 2;
98 } else {
99 d->mAppendedEntries.append( "\n" );
100 ++nextOffset;
101 }
102 }
103 }
104
105 const QByteArray separator = MBoxPrivate::mboxMessageSeparator( rawEntry );
106 d->mAppendedEntries.append( separator );
107 d->mAppendedEntries.append( rawEntry );
108 if ( rawEntry[rawEntry.size() - 1] != '\n' ) {
109 d->mAppendedEntries.append( "\n\n" );
110 } else {
111 d->mAppendedEntries.append( "\n" );
112 }
113
114 MBoxEntry resultEntry;
115 resultEntry.d->mOffset = d->mInitialMboxFileSize + nextOffset;
116 resultEntry.d->mMessageSize = rawEntry.size();
117 resultEntry.d->mSeparatorSize = separator.size();
118 d->mEntries << resultEntry;
119
120 return resultEntry;
121}
122
123MBoxEntry::List MBox::entries( const MBoxEntry::List &deletedEntries ) const
124{
125 if ( deletedEntries.isEmpty() ) {
126 // fast path
127 return d->mEntries;
128 }
129
130 MBoxEntry::List result;
131
132 foreach ( const MBoxEntry &entry, d->mEntries ) {
133 if ( !deletedEntries.contains( entry ) ) {
134 result << entry;
135 }
136 }
137
138 return result;
139}
140
141QString MBox::fileName() const
142{
143 return d->mMboxFile.fileName();
144}
145
146bool MBox::load( const QString &fileName )
147{
148 if ( d->mFileLocked ) {
149 return false;
150 }
151
152 d->initLoad( fileName );
153
154 if ( !lock() ) {
155 kDebug() << "Failed to lock";
156 return false;
157 }
158
159 d->mInitialMboxFileSize = d->mMboxFile.size(); // AFTER the file has been locked
160
161 QByteArray line;
162 QByteArray prevSeparator;
163 quint64 offs = 0; // The offset of the next message to read.
164
165 while ( !d->mMboxFile.atEnd() ) {
166 quint64 pos = d->mMboxFile.pos();
167
168 line = d->mMboxFile.readLine();
169
170 // if atEnd, use mail only if there was a separator line at all,
171 // otherwise it's not a valid mbox
172 if ( d->isMBoxSeparator( line ) ||
173 ( d->mMboxFile.atEnd() && ( prevSeparator.size() != 0 ) ) ) {
174
175 // if we are the at the file end, update pos to not forget the last line
176 if ( d->mMboxFile.atEnd() ) {
177 pos = d->mMboxFile.pos();
178 }
179
180 // Found the separator or at end of file, the message starts at offs
181 quint64 msgSize = pos - offs;
182
183 if ( pos > 0 ) {
184 // This is not the separator of the first mail in the file. If pos == 0
185 // than we matched the separator of the first mail in the file.
186 MBoxEntry entry;
187 entry.d->mOffset = offs;
188 entry.d->mSeparatorSize = prevSeparator.size();
189 entry.d->mMessageSize = msgSize - 1;
190
191 // Don't add the separator size and the newline up to the message size.
192 entry.d->mMessageSize -= prevSeparator.size() + 1;
193
194 d->mEntries << entry;
195 }
196
197 if ( d->isMBoxSeparator( line ) ) {
198 prevSeparator = line;
199 }
200
201 offs += msgSize; // Mark the beginning of the next message.
202 }
203 }
204
205 // FIXME: What if unlock fails?
206 // if no separator was found, the file is still valid if it is empty
207 return unlock() && ( ( prevSeparator.size() != 0 ) || ( d->mMboxFile.size() == 0 ) );
208}
209
210bool MBox::lock()
211{
212 if ( d->mMboxFile.fileName().isEmpty() ) {
213 return false; // We cannot lock if there is no file loaded.
214 }
215
216 // We can't load another file when the mbox currently is locked so if d->mFileLocked
217 // is true atm just return true.
218 if ( locked() ) {
219 return true;
220 }
221
222 if ( d->mLockType == None ) {
223 d->mFileLocked = true;
224 if ( d->open() ) {
225 d->startTimerIfNeeded();
226 return true;
227 }
228
229 d->mFileLocked = false;
230 return false;
231 }
232
233 QStringList args;
234 int rc = 0;
235
236 switch ( d->mLockType ) {
237 case ProcmailLockfile:
238 args << QLatin1String( "-l20" ) << QLatin1String( "-r5" );
239 if ( !d->mLockFileName.isEmpty() ) {
240 args << QString::fromLocal8Bit( QFile::encodeName( d->mLockFileName ) );
241 } else {
242 args << QString::fromLocal8Bit( QFile::encodeName( d->mMboxFile.fileName() +
243 QLatin1String( ".lock" ) ) );
244 }
245
246 rc = QProcess::execute( QLatin1String( "lockfile" ), args );
247 if ( rc != 0 ) {
248 kDebug() << "lockfile -l20 -r5 " << d->mMboxFile.fileName()
249 << ": Failed (" << rc << ") switching to read only mode";
250 d->mReadOnly = true; // In case the MBox object was created read/write we
251 // set it to read only when locking failed.
252 } else {
253 d->mFileLocked = true;
254 }
255 break;
256
257 case MuttDotlock:
258 args << QString::fromLocal8Bit( QFile::encodeName( d->mMboxFile.fileName() ) );
259 rc = QProcess::execute( QLatin1String( "mutt_dotlock" ), args );
260
261 if ( rc != 0 ) {
262 kDebug() << "mutt_dotlock " << d->mMboxFile.fileName()
263 << ": Failed (" << rc << ") switching to read only mode";
264 d->mReadOnly = true; // In case the MBox object was created read/write we
265 // set it to read only when locking failed.
266 } else {
267 d->mFileLocked = true;
268 }
269 break;
270
271 case MuttDotlockPrivileged:
272 args << QLatin1String( "-p" )
273 << QString::fromLocal8Bit( QFile::encodeName( d->mMboxFile.fileName() ) );
274 rc = QProcess::execute( QLatin1String( "mutt_dotlock" ), args );
275
276 if ( rc != 0 ) {
277 kDebug() << "mutt_dotlock -p " << d->mMboxFile.fileName() << ":"
278 << ": Failed (" << rc << ") switching to read only mode";
279 d->mReadOnly = true;
280 } else {
281 d->mFileLocked = true;
282 }
283 break;
284
285 case None:
286 d->mFileLocked = true;
287 break;
288 default:
289 break;
290 }
291
292 if ( d->mFileLocked ) {
293 if ( !d->open() ) {
294 const bool unlocked = unlock();
295 Q_ASSERT( unlocked ); // If this fails we're in trouble.
296 Q_UNUSED( unlocked );
297 }
298 }
299
300 d->startTimerIfNeeded();
301 return d->mFileLocked;
302}
303
304bool MBox::locked() const
305{
306 return d->mFileLocked;
307}
308
309static bool lessThanByOffset( const MBoxEntry &left, const MBoxEntry &right )
310{
311 return left.messageOffset() < right.messageOffset();
312}
313
314bool MBox::purge( const MBoxEntry::List &deletedEntries, QList<MBoxEntry::Pair> *movedEntries )
315{
316 if ( d->mMboxFile.fileName().isEmpty() || d->mReadOnly ) {
317 return false; // No file loaded yet or it's readOnly
318 }
319
320 if ( deletedEntries.isEmpty() ) {
321 return true; // Nothing to do.
322 }
323
324 if ( !lock() ) {
325 return false;
326 }
327
328 foreach ( const MBoxEntry &entry, deletedEntries ) {
329 d->mMboxFile.seek( entry.messageOffset() );
330 const QByteArray line = d->mMboxFile.readLine();
331
332 if ( !d->isMBoxSeparator( line ) ) {
333 qDebug() << "Found invalid separator at:" << entry.messageOffset();
334 unlock();
335 return false; // The file is messed up or the index is incorrect.
336 }
337 }
338
339 // All entries are deleted, so just resize the file to a size of 0.
340 if ( deletedEntries.size() == d->mEntries.size() ) {
341 d->mEntries.clear();
342 d->mMboxFile.resize( 0 );
343 kDebug() << "Purge comleted successfully, unlocking the file.";
344 return unlock();
345 }
346
347 qSort( d->mEntries.begin(), d->mEntries.end(), lessThanByOffset );
348 quint64 writeOffset = 0;
349 bool writeOffSetInitialized = false;
350 MBoxEntry::List resultingEntryList;
351 QList<MBoxEntry::Pair> tmpMovedEntries;
352
353 quint64 origFileSize = d->mMboxFile.size();
354
355 QListIterator<MBoxEntry> i( d->mEntries );
356 while ( i.hasNext() ) {
357 MBoxEntry entry = i.next();
358
359 if ( deletedEntries.contains( entry ) && !writeOffSetInitialized ) {
360 writeOffset = entry.messageOffset();
361 writeOffSetInitialized = true;
362 } else if ( writeOffSetInitialized &&
363 writeOffset < entry.messageOffset() &&
364 !deletedEntries.contains( entry ) ) {
365 // The current message doesn't have to be deleted, but must be moved.
366 // First determine the size of the entry that must be moved.
367 quint64 entrySize = 0;
368 if ( i.hasNext() ) {
369 entrySize = i.next().messageOffset() - entry.messageOffset();
370 i.previous(); // Go back to make sure that we also handle the next entry.
371 } else {
372 entrySize = origFileSize - entry.messageOffset();
373 }
374
375 Q_ASSERT( entrySize > 0 ); // MBox entries really cannot have a size <= 0;
376
377 // we map the whole area of the file starting at the writeOffset up to the
378 // message that have to be moved into memory. This includes eventually the
379 // messages that are the deleted between the first deleted message
380 // encountered and the message that has to be moved.
381 quint64 mapSize = entry.messageOffset() + entrySize - writeOffset;
382
383 // Now map writeOffSet + mapSize into mem.
384 uchar *memArea = d->mMboxFile.map( writeOffset, mapSize );
385
386 // Now read the entry that must be moved to writeOffset.
387 quint64 startOffset = entry.messageOffset() - writeOffset;
388 memmove( memArea, memArea + startOffset, entrySize );
389
390 d->mMboxFile.unmap( memArea );
391
392 MBoxEntry resultEntry;
393 resultEntry.d->mOffset = writeOffset;
394 resultEntry.d->mSeparatorSize = entry.separatorSize();
395 resultEntry.d->mMessageSize = entry.messageSize();
396
397 resultingEntryList << resultEntry;
398 tmpMovedEntries << MBoxEntry::Pair( MBoxEntry( entry.messageOffset() ),
399 MBoxEntry( resultEntry.messageOffset() ) );
400 writeOffset += entrySize;
401 } else if ( !deletedEntries.contains( entry ) ) {
402 // Unmoved and not deleted entry, can only ocure before the first deleted
403 // entry.
404 Q_ASSERT( !writeOffSetInitialized );
405 resultingEntryList << entry;
406 }
407 }
408
409 // Chop off remaining entry bits.
410 d->mMboxFile.resize( writeOffset );
411 d->mEntries = resultingEntryList;
412
413 kDebug() << "Purge comleted successfully, unlocking the file.";
414 if ( movedEntries ) {
415 *movedEntries = tmpMovedEntries;
416 }
417 return unlock(); // FIXME: What if this fails? It will return false but the
418 // file has changed.
419}
420
421QByteArray MBox::readRawMessage( const MBoxEntry &entry )
422{
423 const bool wasLocked = locked();
424 if ( !wasLocked ) {
425 if ( !lock() ) {
426 return QByteArray();
427 }
428 }
429
430 // TODO: Add error handling in case locking failed.
431
432 quint64 offset = entry.messageOffset();
433
434 Q_ASSERT( d->mFileLocked );
435 Q_ASSERT( d->mMboxFile.isOpen() );
436 Q_ASSERT( ( d->mInitialMboxFileSize + d->mAppendedEntries.size() ) > offset );
437
438 QByteArray message;
439
440 if ( offset < d->mInitialMboxFileSize ) {
441 d->mMboxFile.seek( offset );
442
443 QByteArray line = d->mMboxFile.readLine();
444
445 if ( !d->isMBoxSeparator( line ) ) {
446 kDebug() << "[MBox::readEntry] Invalid entry at:" << offset;
447 if ( !wasLocked ) {
448 unlock();
449 }
450 return QByteArray(); // The file is messed up or the index is incorrect.
451 }
452
453 line = d->mMboxFile.readLine();
454 while ( !d->isMBoxSeparator( line ) ) {
455 message += line;
456 if ( d->mMboxFile.atEnd() ) {
457 break;
458 }
459 line = d->mMboxFile.readLine();
460 }
461 } else {
462 offset -= d->mInitialMboxFileSize;
463 if ( offset > static_cast<quint64>( d->mAppendedEntries.size() ) ) {
464 if ( !wasLocked ) {
465 unlock();
466 }
467 return QByteArray();
468 }
469
470 QBuffer buffer( &( d->mAppendedEntries ) );
471 buffer.open( QIODevice::ReadOnly );
472 buffer.seek( offset );
473
474 QByteArray line = buffer.readLine();
475
476 if ( !d->isMBoxSeparator( line ) ) {
477 kDebug() << "[MBox::readEntry] Invalid appended entry at:" << offset;
478 if ( !wasLocked ) {
479 unlock();
480 }
481 return QByteArray(); // The file is messed up or the index is incorrect.
482 }
483
484 line = buffer.readLine();
485 while ( !d->isMBoxSeparator( line ) && !buffer.atEnd() ) {
486 message += line;
487 line = buffer.readLine();
488 }
489 }
490
491 // Remove te last '\n' added by writeEntry.
492 if ( message.endsWith( '\n' ) ) {
493 message.chop( 1 );
494 }
495
496 MBoxPrivate::unescapeFrom( message.data(), message.size() );
497
498 if ( !wasLocked ) {
499 if ( !d->startTimerIfNeeded() ) {
500 const bool unlocked = unlock();
501 Q_ASSERT( unlocked );
502 Q_UNUSED( unlocked );
503 }
504 }
505
506 return message;
507}
508
509KMime::Message *MBox::readMessage( const MBoxEntry &entry )
510{
511 const QByteArray message = readRawMessage( entry );
512 if ( message.isEmpty() ) {
513 return 0;
514 }
515
516 KMime::Message *mail = new KMime::Message();
517 mail->setContent( KMime::CRLFtoLF( message ) );
518 mail->parse();
519
520 return mail;
521}
522
523QByteArray MBox::readMessageHeaders( const MBoxEntry &entry )
524{
525 const bool wasLocked = d->mFileLocked;
526 if ( !wasLocked ) {
527 if (!lock()) {
528 kDebug() << "Failed to lock";
529 return QByteArray();
530 }
531 }
532
533 const quint64 offset = entry.messageOffset();
534
535 Q_ASSERT( d->mFileLocked );
536 Q_ASSERT( d->mMboxFile.isOpen() );
537 Q_ASSERT( ( d->mInitialMboxFileSize + d->mAppendedEntries.size() ) > offset );
538
539 QByteArray headers;
540 if ( offset < d->mInitialMboxFileSize ) {
541 d->mMboxFile.seek( offset );
542 QByteArray line = d->mMboxFile.readLine();
543
544 while ( line[0] != '\n' && !d->mMboxFile.atEnd() ) {
545 headers += line;
546 line = d->mMboxFile.readLine();
547 }
548 } else {
549 QBuffer buffer( &( d->mAppendedEntries ) );
550 buffer.open( QIODevice::ReadOnly );
551 buffer.seek( offset - d->mInitialMboxFileSize );
552 QByteArray line = buffer.readLine();
553
554 while ( line[0] != '\n' && !buffer.atEnd() ) {
555 headers += line;
556 line = buffer.readLine();
557 }
558 }
559
560 if ( !wasLocked ) {
561 unlock();
562 }
563
564 return headers;
565}
566
567bool MBox::save( const QString &fileName )
568{
569 if ( !fileName.isEmpty() && KUrl( fileName ).toLocalFile() != d->mMboxFile.fileName() ) {
570 if ( !d->mMboxFile.copy( fileName ) ) {
571 return false;
572 } else {
573 // if the original file was read-only, also the copied file is read-only
574 // Let's make it writable now
575 QFile::setPermissions(fileName, d->mMboxFile.permissions() | QFile::WriteOwner);
576 }
577
578 if ( d->mAppendedEntries.size() == 0 ) {
579 return true; // Nothing to do
580 }
581
582 QFile otherFile( fileName );
583 Q_ASSERT( otherFile.exists() );
584 if ( !otherFile.open( QIODevice::ReadWrite ) ) {
585 return false;
586 }
587
588 otherFile.seek( d->mMboxFile.size() );
589 otherFile.write( d->mAppendedEntries );
590
591 // Don't clear mAppendedEntries and don't update mInitialFileSize. These
592 // are still valid for the original file.
593 return true;
594 }
595
596 if ( d->mReadOnly )
597 return false;
598
599 if ( d->mAppendedEntries.size() == 0 ) {
600 return true; // Nothing to do.
601 }
602
603 if ( !lock() ) {
604 return false;
605 }
606
607 Q_ASSERT( d->mMboxFile.isOpen() );
608
609 d->mMboxFile.seek( d->mMboxFile.size() );
610 d->mMboxFile.write( d->mAppendedEntries );
611 d->mAppendedEntries.clear();
612 d->mInitialMboxFileSize = d->mMboxFile.size();
613
614 return unlock();
615}
616
617bool MBox::setLockType( LockType ltype )
618{
619 if ( d->mFileLocked ) {
620 kDebug() << "File is currently locked.";
621 return false; // Don't change the method if the file is currently locked.
622 }
623
624 switch ( ltype ) {
625 case ProcmailLockfile:
626 if ( KStandardDirs::findExe( QLatin1String( "lockfile" ) ).isEmpty() ) {
627 kDebug() << "Could not find the lockfile executable";
628 return false;
629 }
630 break;
631 case MuttDotlock: // fall through
632 case MuttDotlockPrivileged:
633 if ( KStandardDirs::findExe( QLatin1String( "mutt_dotlock" ) ).isEmpty() ) {
634 kDebug() << "Could not find the mutt_dotlock executable";
635 return false;
636 }
637 break;
638 default:
639 break; // We assume fcntl available and lock_none doesn't need a check.
640 }
641
642 d->mLockType = ltype;
643 return true;
644}
645
646void MBox::setLockFile( const QString &lockFile )
647{
648 d->mLockFileName = lockFile;
649}
650
651void MBox::setUnlockTimeout( int msec )
652{
653 d->mUnlockTimer.setInterval( msec );
654}
655
656bool MBox::unlock()
657{
658 if ( d->mLockType == None && !d->mFileLocked ) {
659 d->mFileLocked = false;
660 d->mMboxFile.close();
661 return true;
662 }
663
664 int rc = 0;
665 QStringList args;
666
667 switch ( d->mLockType ) {
668 case ProcmailLockfile:
669 // QFile::remove returns true on succes so negate the result.
670 if ( !d->mLockFileName.isEmpty() ) {
671 rc = !QFile( d->mLockFileName ).remove();
672 } else {
673 rc = !QFile( d->mMboxFile.fileName() + QLatin1String( ".lock" ) ).remove();
674 }
675 break;
676
677 case MuttDotlock:
678 args << QLatin1String( "-u" )
679 << QString::fromLocal8Bit( QFile::encodeName( d->mMboxFile.fileName() ) );
680 rc = QProcess::execute( QLatin1String( "mutt_dotlock" ), args );
681 break;
682
683 case MuttDotlockPrivileged:
684 args << QLatin1String( "-u" ) << QLatin1String( "-p" )
685 << QString::fromLocal8Bit( QFile::encodeName( d->mMboxFile.fileName() ) );
686 rc = QProcess::execute( QLatin1String( "mutt_dotlock" ), args );
687 break;
688
689 case None: // Fall through.
690 default:
691 break;
692 }
693
694 if ( rc == 0 ) { // Unlocking succeeded
695 d->mFileLocked = false;
696 }
697
698 d->mMboxFile.close();
699
700 return !d->mFileLocked;
701}
702
703void MBox::setReadOnly(bool ro)
704{
705 d->mReadOnly = ro;
706}
707
708bool MBox::isReadOnly() const
709{
710 return d->mReadOnly;
711}
KMBox::MBoxEntry
A class that encapsulates an entry of a MBox.
Definition: mboxentry.h:39
KMBox::MBoxEntry::separatorSize
quint64 separatorSize() const
Returns the separator size of the message that is referenced by this mbox entry object.
Definition: mboxentry.cpp:80
KMBox::MBoxEntry::Pair
QPair< MBoxEntry, MBoxEntry > Pair
Describes a pair of mbox entry objects.
Definition: mboxentry.h:49
KMBox::MBoxEntry::messageOffset
quint64 messageOffset() const
Returns the offset of the message that is referenced by this mbox entry object.
Definition: mboxentry.cpp:70
KMBox::MBoxEntry::messageSize
quint64 messageSize() const
Returns the size of the message that is referenced by this mbox entry object.
Definition: mboxentry.cpp:75
KMBox::MBoxEntry::List
QList< MBoxEntry > List
Describes a list of mbox entry objects.
Definition: mboxentry.h:44
KMBox::MBox::readRawMessage
QByteArray readRawMessage(const MBoxEntry &entry)
Reads the entire message from the file for the given mbox entry.
Definition: mbox.cpp:421
KMBox::MBox::setReadOnly
void setReadOnly(bool ro=true)
Set the access mode of the mbox file to read only.
Definition: mbox.cpp:703
KMBox::MBox::lock
bool lock()
Locks the mbox file using the configured lock method.
Definition: mbox.cpp:210
KMBox::MBox::load
bool load(const QString &fileName)
Loads the raw mbox data from disk into the current MBox object.
Definition: mbox.cpp:146
KMBox::MBox::setLockFile
void setLockFile(const QString &lockFile)
Sets the lockfile that should be used by the procmail or the KDE lock file method.
Definition: mbox.cpp:646
KMBox::MBox::~MBox
~MBox()
Destroys the mbox object.
Definition: mbox.cpp:52
KMBox::MBox::MBox
MBox()
Creates a new mbox object.
Definition: mbox.cpp:41
KMBox::MBox::appendMessage
MBoxEntry appendMessage(const KMime::Message::Ptr &message)
Appends message to the MBox and returns the corresponding mbox entry for it.
Definition: mbox.cpp:67
KMBox::MBox::setLockType
bool setLockType(LockType ltype)
Sets the locktype that should be used for locking the mbox file.
Definition: mbox.cpp:617
KMBox::MBox::isReadOnly
bool isReadOnly() const
Returns if the current access mode is set to readOnly.
Definition: mbox.cpp:708
KMBox::MBox::save
bool save(const QString &fileName=QString())
Writes the mbox to disk.
Definition: mbox.cpp:567
KMBox::MBox::fileName
QString fileName() const
Returns the file name that was passed to the last call to load().
Definition: mbox.cpp:141
KMBox::MBox::setUnlockTimeout
void setUnlockTimeout(int msec)
By default the unlock method will directly unlock the file.
Definition: mbox.cpp:651
KMBox::MBox::entries
MBoxEntry::List entries(const MBoxEntry::List &deletedEntries=MBoxEntry::List()) const
Retrieve the mbox entry objects for all emails from the file except the deleteEntries.
Definition: mbox.cpp:123
KMBox::MBox::purge
bool purge(const MBoxEntry::List &deletedEntries, QList< MBoxEntry::Pair > *movedEntries=0)
Removes all messages for the given mbox entries from the current reference file (the file that is loa...
Definition: mbox.cpp:314
KMBox::MBox::locked
bool locked() const
Returns whether or not the mbox currently is locked.
Definition: mbox.cpp:304
KMBox::MBox::unlock
bool unlock()
Unlock the mbox file.
Definition: mbox.cpp:656
KMBox::MBox::LockType
LockType
Describes the type of locking that will be used.
Definition: mbox.h:44
KMBox::MBox::readMessageHeaders
QByteArray readMessageHeaders(const MBoxEntry &entry)
Reads the headers of the message for the given mbox entry.
Definition: mbox.cpp:523
KMBox::MBox::readMessage
KMime::Message * readMessage(const MBoxEntry &entry)
Reads the entire message from the file for the given mbox entry.
Definition: mbox.cpp:509
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KMBox Library

Skip menu "KMBox Library"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal