12 #include <libtdepim/tdefileio.h> 13 #include "kmfoldermaildir.h" 14 #include "kmfoldermgr.h" 16 #include "undostack.h" 17 #include "maildirjob.h" 18 #include "kcursorsaver.h" 19 #include "jobscheduler.h" 20 using KMail::MaildirJob;
21 #include "compactionjob.h" 22 #include "kmmsgdict.h" 25 #include <tdeapplication.h> 27 #include <tdelocale.h> 28 #include <kstaticdeleter.h> 29 #include <tdemessagebox.h> 36 #include <sys/types.h> 51 TQValueList<KMFolderMaildir::DirSizeJobQueueEntry> KMFolderMaildir::s_DirSizeJobQueue;
54 KMFolderMaildir::KMFolderMaildir(
KMFolder* folder,
const char* name)
55 :
KMFolderIndex(folder, name), mCurrentlyCheckingFolderSize(false)
62 KMFolderMaildir::~KMFolderMaildir()
64 if (mOpenCount>0)
close(
"~foldermaildir",
true);
65 if (kmkernel->undoStack()) kmkernel->undoStack()->folderDestroyed( folder() );
69 int KMFolderMaildir::canAccess()
72 assert(!folder()->name().isEmpty());
74 TQString sBadFolderName;
75 if (access(TQFile::encodeName(
location()), R_OK | W_OK | X_OK) != 0) {
77 }
else if (access(TQFile::encodeName(
location() +
"/new"), R_OK | W_OK | X_OK) != 0) {
78 sBadFolderName =
location() +
"/new";
79 }
else if (access(TQFile::encodeName(
location() +
"/cur"), R_OK | W_OK | X_OK) != 0) {
80 sBadFolderName =
location() +
"/cur";
81 }
else if (access(TQFile::encodeName(
location() +
"/tmp"), R_OK | W_OK | X_OK) != 0) {
82 sBadFolderName =
location() +
"/tmp";
85 if ( !sBadFolderName.isEmpty() ) {
86 int nRetVal = TQFile::exists(sBadFolderName) ? EPERM : ENOENT;
88 if ( nRetVal == ENOENT )
89 KMessageBox::sorry(0, i18n(
"Error opening %1; this folder is missing.")
90 .arg(sBadFolderName));
92 KMessageBox::sorry(0, i18n(
"Error opening %1; either this is not a valid " 93 "maildir folder, or you do not have sufficient access permissions.")
94 .arg(sBadFolderName));
102 int KMFolderMaildir::open(
const char *)
107 kmkernel->jobScheduler()->notifyOpeningFolder( folder() );
109 if (mOpenCount > 1)
return 0;
111 assert(!folder()->name().isEmpty());
118 if (!folder()->path().isEmpty())
124 str = i18n(
"Folder `%1' changed; recreating index.")
131 updateIndexStreamPtr();
155 int KMFolderMaildir::createMaildirFolders(
const TQString & folderPath )
159 dirinfo.setFile( folderPath +
"/new" );
160 if ( dirinfo.exists() )
return EEXIST;
161 dirinfo.setFile( folderPath +
"/cur" );
162 if ( dirinfo.exists() )
return EEXIST;
163 dirinfo.setFile( folderPath +
"/tmp" );
164 if ( dirinfo.exists() )
return EEXIST;
167 if ( ::mkdir( TQFile::encodeName( folderPath ), S_IRWXU ) > 0 ) {
168 kdDebug(5006) <<
"Could not create folder " << folderPath << endl;
171 if ( ::mkdir( TQFile::encodeName( folderPath +
"/new" ), S_IRWXU ) > 0 ) {
172 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/new" << endl;
175 if ( ::mkdir( TQFile::encodeName( folderPath +
"/cur" ), S_IRWXU ) > 0 ) {
176 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/cur" << endl;
179 if ( ::mkdir( TQFile::encodeName( folderPath +
"/tmp" ), S_IRWXU ) > 0 ) {
180 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/tmp" << endl;
188 int KMFolderMaildir::create()
193 assert(!folder()->name().isEmpty());
194 assert(mOpenCount == 0);
196 rc = createMaildirFolders(
location() );
201 if (!folder()->path().isEmpty())
203 old_umask = umask(077);
205 updateIndexStreamPtr(
true);
225 void KMFolderMaildir::reallyDoClose(
const char* owner)
238 updateIndexStreamPtr(
true);
249 void KMFolderMaildir::sync()
253 kmkernel->emergencyExit( i18n(
"Could not sync maildir folder.") );
258 int KMFolderMaildir::expungeContents()
263 TQStringList files(d.entryList());
264 TQStringList::ConstIterator it(files.begin());
265 for ( ; it != files.end(); ++it)
266 TQFile::remove(d.filePath(*it));
269 files = d.entryList();
270 for (it = files.begin(); it != files.end(); ++it)
271 TQFile::remove(d.filePath(*it));
276 int KMFolderMaildir::compact(
unsigned int startIndex,
int nbMessages,
const TQStringList& entryList,
bool& done )
278 TQString subdirNew(
location() +
"/new/");
279 TQString subdirCur(
location() +
"/cur/");
281 unsigned int stopIndex = nbMessages == -1 ?
mMsgList.
count() :
284 for(
unsigned int idx = startIndex; idx < stopIndex; ++idx) {
285 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList.at(idx);
289 TQString filename(mi->fileName());
290 if (filename.isEmpty())
294 if ( entryList.contains( filename ) )
295 moveInternal(subdirNew + filename, subdirCur + filename, mi);
299 filename = constructValidFileName( filename, mi->status() );
302 if (filename != mi->fileName())
304 moveInternal(subdirCur + mi->fileName(), subdirCur + filename, mi);
305 mi->setFileName(filename);
313 mi->setStatus(KMMsgStatusUnread);
323 int KMFolderMaildir::compact(
bool silent )
326 int rc = job->executeNow( silent );
333 KMFolderMaildir::doCreateJob(
KMMessage *msg, FolderJob::JobType jt,
334 KMFolder *folder, TQString,
const AttachmentStrategy* )
const 336 MaildirJob *job =
new MaildirJob( msg, jt, folder );
337 job->setParentFolder(
this );
343 KMFolderMaildir::doCreateJob( TQPtrList<KMMessage>& msgList,
const TQString& sets,
344 FolderJob::JobType jt,
KMFolder *folder )
const 346 MaildirJob *job =
new MaildirJob( msgList, sets, jt, folder );
347 job->setParentFolder(
this );
355 return addMsgInternal( aMsg, index_return );
359 int KMFolderMaildir::addMsgInternal(
KMMessage* aMsg,
int* index_return,
378 msgParent = aMsg->parent();
381 if (msgParent==folder() && !kmkernel->folderIsDraftOrOutbox(folder()))
384 idx = msgParent->
find(aMsg);
393 const TQString uidHeader = aMsg->
headerField(
"X-UID" );
394 if ( !uidHeader.isEmpty() && stripUid )
398 len = msgText.length();
402 if ( !uidHeader.isEmpty() && stripUid )
407 kdDebug(5006) <<
"Message added to folder `" << name() <<
"' contains no data. Ignoring it." << endl;
412 TQString filename = constructValidFileName( aMsg->
fileName(), aMsg->
status() );
414 TQString tmp_file(
location() +
"/tmp/");
415 tmp_file += filename;
417 if (!KPIM::kCStringToFile(msgText, tmp_file,
false,
false,
false))
418 kmkernel->emergencyExit( i18n(
"Message could not be added to the folder, possibly disk space is low.") );
420 TQFile file(tmp_file);
421 size = msgText.length();
424 rc = openThis.openResult();
427 kdDebug(5006) <<
"KMFolderMaildir::addMsg-open: " << rc <<
" of folder: " <<
label() << endl;
432 TQString new_loc(
location() +
"/cur/");
434 if (moveInternal(tmp_file, new_loc, filename, aMsg->
status()).isNull())
440 if (msgParent && idx >= 0)
441 msgParent->
take(idx);
444 if ( stripUid ) aMsg->setUID( 0 );
447 aMsg->setFileName(filename);
449 if (aMsg->isUnread() || aMsg->isNew() || folder() == kmkernel->outboxFolder())
456 kdDebug( 5006 ) <<
"FolderStorage::msgStatusChanged" << endl;
459 if ( !mEmitChangedTimer->isActive() ) {
461 mEmitChangedTimer->start( 3000 );
469 if ( aMsg->attachmentState() == KMMsgAttachmentUnknown && aMsg->
readyToShow() ) {
470 aMsg->updateAttachmentState();
472 if ( aMsg->invitationState() == KMMsgInvitationUnknown && aMsg->
readyToShow() ) {
473 aMsg->updateInvitationState();
477 aMsg->setParent(folder());
478 aMsg->setMsgSize(size);
480 if (aMsg->getMsgSerNum() <= 0)
495 const uchar *buffer = mb->asIndexString(len);
498 mb->setIndexLength( len );
500 kdDebug(5006) <<
"Whoa! " << __FILE__ <<
":" << __LINE__ << endl;
509 kdDebug(5006) <<
"Error: Could not add message to folder (No space left on device?)" << endl;
511 kdDebug(5006) <<
"Undoing changes" << endl;
514 kmkernel->emergencyExit(i18n(
"KMFolderMaildir::addMsg: abnormally terminating to prevent data loss."));
547 KMMessage* KMFolderMaildir::readMsg(
int idx)
549 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList[idx];
558 DwString KMFolderMaildir::getDwString(
int idx)
560 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList[idx];
561 TQString abs_file(
location() +
"/cur/");
562 abs_file += mi->fileName();
563 TQFileInfo fi( abs_file );
565 if (fi.exists() && fi.isFile() && fi.isWritable() && fi.size() > 0)
567 FILE* stream = fopen(TQFile::encodeName(abs_file),
"r+");
569 size_t msgSize = fi.size();
570 char* msgText =
new char[ msgSize + 1 ];
571 fread(msgText, msgSize, 1, stream);
573 msgText[msgSize] =
'\0';
577 str.TakeBuffer( msgText, msgSize + 1, 0, newMsgSize );
581 kdDebug(5006) <<
"Could not open file r+ " << abs_file << endl;
586 void KMFolderMaildir::readFileHeaderIntern(
const TQString& dir,
const TQString& file, KMMsgStatus status)
589 char path_buffer[PATH_MAX];
590 if(!::getcwd(path_buffer, PATH_MAX - 1))
593 ::chdir(TQFile::encodeName(dir));
597 if (status == KMMsgStatusRead)
599 if (file.find(
":2,") == -1)
600 status = KMMsgStatusUnread;
601 else if (file.right(5) ==
":2,RS")
602 status |= KMMsgStatusReplied;
607 if ( f.open( IO_ReadOnly ) == false ) {
608 kdWarning(5006) <<
"The file '" << TQString(TQFile::encodeName(dir)) <<
"/" << file
609 <<
"' could not be opened for reading the message. " 610 "Please check ownership and permissions." 617 bool inHeader =
true;
618 TQCString *lastStr = 0;
620 TQCString dateStr, fromStr, toStr, subjStr;
621 TQCString xmarkStr, replyToIdStr, msgIdStr, referencesStr;
622 TQCString statusStr, replyToAuxIdStr, uidStr;
623 TQCString contentTypeStr, charset;
629 if ( f.atEnd() || ( -1 == f.readLine(line, MAX_LINE) ) )
634 if (atEof || !inHeader)
636 msgIdStr = msgIdStr.stripWhiteSpace();
637 if( !msgIdStr.isEmpty() ) {
639 rightAngle = msgIdStr.find(
'>' );
640 if( rightAngle != -1 )
641 msgIdStr.truncate( rightAngle + 1 );
644 replyToIdStr = replyToIdStr.stripWhiteSpace();
645 if( !replyToIdStr.isEmpty() ) {
647 rightAngle = replyToIdStr.find(
'>' );
648 if( rightAngle != -1 )
649 replyToIdStr.truncate( rightAngle + 1 );
652 referencesStr = referencesStr.stripWhiteSpace();
653 if( !referencesStr.isEmpty() ) {
654 int leftAngle, rightAngle;
655 leftAngle = referencesStr.findRev(
'<' );
656 if( ( leftAngle != -1 )
657 && ( replyToIdStr.isEmpty() || ( replyToIdStr[0] !=
'<' ) ) ) {
659 replyToIdStr = referencesStr.mid( leftAngle );
663 leftAngle = referencesStr.findRev(
'<', leftAngle - 1 );
664 if( leftAngle != -1 )
665 referencesStr = referencesStr.mid( leftAngle );
666 rightAngle = referencesStr.findRev(
'>' );
667 if( rightAngle != -1 )
668 referencesStr.truncate( rightAngle + 1 );
674 replyToAuxIdStr = referencesStr;
675 rightAngle = referencesStr.find(
'>' );
676 if( rightAngle != -1 )
677 replyToAuxIdStr.truncate( rightAngle + 1 );
680 statusStr = statusStr.stripWhiteSpace();
681 if (!statusStr.isEmpty())
684 if (statusStr[0] ==
'S')
685 status |= KMMsgStatusSent;
686 else if (statusStr[0] ==
'F')
687 status |= KMMsgStatusForwarded;
688 else if (statusStr[0] ==
'D')
689 status |= KMMsgStatusDeleted;
690 else if (statusStr[0] ==
'Q')
691 status |= KMMsgStatusQueued;
692 else if (statusStr[0] ==
'G')
693 status |= KMMsgStatusFlag;
696 contentTypeStr = contentTypeStr.stripWhiteSpace();
698 if ( !contentTypeStr.isEmpty() )
700 int cidx = contentTypeStr.find(
"charset=" );
702 charset = contentTypeStr.mid( cidx + 8 );
703 if ( !charset.isEmpty() && ( charset[0] ==
'"' ) ) {
704 charset = charset.mid( 1 );
707 while ( (
unsigned int) cidx < charset.length() ) {
708 if ( charset[cidx] ==
'"' || ( !isalnum(charset[cidx]) &&
709 charset[cidx] !=
'-' && charset[cidx] !=
'_' ) )
713 charset.truncate( cidx );
719 KMMsgInfo *mi =
new KMMsgInfo(folder());
720 mi->init( subjStr.stripWhiteSpace(),
721 fromStr.stripWhiteSpace(),
722 toStr.stripWhiteSpace(),
724 xmarkStr.stripWhiteSpace(),
725 replyToIdStr, replyToAuxIdStr, msgIdStr,
727 KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
728 KMMsgMDNStateUnknown, charset, f.size() );
730 dateStr = dateStr.stripWhiteSpace();
731 if (!dateStr.isEmpty())
732 mi->setDate(dateStr.data());
733 if ( !uidStr.isEmpty() )
734 mi->setUID( uidStr.toULong() );
739 if (status & KMMsgStatusNew)
741 TQString newDir(
location() +
"/new/");
742 TQString curDir(
location() +
"/cur/");
743 moveInternal(newDir + file, curDir + file, mi);
750 if (inHeader && ( line[0] ==
'\t' || line[0] ==
' ' ) )
753 while (line[i] ==
'\t' || line[i] ==
' ')
755 if (line[i] <
' ' && line[i] > 0)
759 *lastStr += line + i;
764 if (inHeader && (line[0] ==
'\n' || line[0] ==
'\r'))
769 if (strncasecmp(line,
"Date:", 5) == 0)
771 dateStr = TQCString(line+5);
774 else if (strncasecmp(line,
"From:", 5) == 0)
776 fromStr = TQCString(line+5);
779 else if (strncasecmp(line,
"To:", 3) == 0)
781 toStr = TQCString(line+3);
784 else if (strncasecmp(line,
"Subject:", 8) == 0)
786 subjStr = TQCString(line+8);
789 else if (strncasecmp(line,
"References:", 11) == 0)
791 referencesStr = TQCString(line+11);
792 lastStr = &referencesStr;
794 else if (strncasecmp(line,
"Message-Id:", 11) == 0)
796 msgIdStr = TQCString(line+11);
799 else if (strncasecmp(line,
"X-KMail-Mark:", 13) == 0)
801 xmarkStr = TQCString(line+13);
803 else if (strncasecmp(line,
"X-Status:", 9) == 0)
805 statusStr = TQCString(line+9);
807 else if (strncasecmp(line,
"In-Reply-To:", 12) == 0)
809 replyToIdStr = TQCString(line+12);
810 lastStr = &replyToIdStr;
812 else if (strncasecmp(line,
"X-UID:", 6) == 0)
814 uidStr = TQCString(line+6);
817 else if (strncasecmp(line,
"Content-Type:", 13) == 0)
819 contentTypeStr = TQCString(line+13);
820 lastStr = &contentTypeStr;
825 if (status & KMMsgStatusNew || status & KMMsgStatusUnread ||
826 (folder() == kmkernel->outboxFolder()))
832 ::chdir(path_buffer);
835 int KMFolderMaildir::createIndexFromContents()
848 dirinfo.setFile(
location() +
"/new");
849 if (!dirinfo.exists() || !dirinfo.isDir())
851 kdDebug(5006) <<
"Directory " <<
location() <<
"/new doesn't exist or is a file"<< endl;
855 newDir.setFilter(TQDir::Files);
857 dirinfo.setFile(
location() +
"/cur");
858 if (!dirinfo.exists() || !dirinfo.isDir())
860 kdDebug(5006) <<
"Directory " <<
location() <<
"/cur doesn't exist or is a file"<< endl;
864 curDir.setFilter(TQDir::Files);
867 const TQFileInfoList *list = curDir.entryInfoList();
868 TQFileInfoListIterator it(*list);
871 while ((fi = it.current()))
873 readFileHeaderIntern(curDir.path(), fi->fileName(), KMMsgStatusRead);
878 list = newDir.entryInfoList();
881 while ((fi=it.current()))
883 readFileHeaderIntern(newDir.path(), fi->fileName(), KMMsgStatusNew);
888 emit
statusMsg(i18n(
"Writing index file"));
895 if (kmkernel->outboxFolder() == folder() &&
count() > 0)
896 KMessageBox::information(0, i18n(
"Your outbox contains messages which were " 897 "most-likely not created by KMail;\nplease remove them from there if you " 898 "do not want KMail to send them."));
909 return KMFolderIndex::IndexCorrupt;
911 TQFileInfo new_info(
location() +
"/new");
912 TQFileInfo cur_info(
location() +
"/cur");
915 if (!index_info.exists())
916 return KMFolderIndex::IndexMissing;
921 return ((new_info.lastModified() > index_info.lastModified().addSecs(5)) ||
922 (cur_info.lastModified() > index_info.lastModified().addSecs(5)))
923 ? KMFolderIndex::IndexTooOld
924 : KMFolderIndex::IndexOk;
928 void KMFolderMaildir::removeMsg(
int idx,
bool)
931 if (!msg || !msg->fileName())
return;
933 removeFile(msg->fileName());
939 KMMessage* KMFolderMaildir::take(
int idx)
948 if ( removeFile(msg->
fileName()) ) {
956 bool KMFolderMaildir::removeFile(
const TQString & folderPath,
957 const TQString & filename )
963 TQCString abs_file( TQFile::encodeName( folderPath +
"/cur/" + filename ) );
964 if ( ::unlink( abs_file ) == 0 )
967 if ( errno == ENOENT ) {
968 abs_file = TQFile::encodeName( folderPath +
"/new/" + filename );
969 if ( ::unlink( abs_file ) == 0 )
973 kdDebug(5006) <<
"Can't delete " << abs_file <<
" " << perror << endl;
977 bool KMFolderMaildir::removeFile(
const TQString & filename )
979 return removeFile(
location(), filename );
982 #include <sys/types.h> 984 static bool removeDirAndContentsRecursively(
const TQString & path )
990 d.setFilter( TQDir::Files | TQDir::Dirs | TQDir::Hidden | TQDir::NoSymLinks );
992 const TQFileInfoList *list = d.entryInfoList();
993 TQFileInfoListIterator it( *list );
996 while ( (fi = it.current()) != 0 ) {
998 if ( fi->fileName() !=
"." && fi->fileName() !=
".." )
999 success = success && removeDirAndContentsRecursively( fi->absFilePath() );
1001 success = success && d.remove( fi->absFilePath() );
1007 success = success && d.rmdir( path );
1013 int KMFolderMaildir::removeContents()
1017 if ( !removeDirAndContentsRecursively(
location() +
"/new/" ) )
return 1;
1018 if ( !removeDirAndContentsRecursively(
location() +
"/cur/" ) )
return 1;
1019 if ( !removeDirAndContentsRecursively(
location() +
"/tmp/" ) )
return 1;
1024 if ( dir.count() == 2 ) {
1025 if ( !removeDirAndContentsRecursively(
location() ), 0 )
return 1;
1030 static TQRegExp *suffix_regex = 0;
1031 static KStaticDeleter<TQRegExp> suffix_regex_sd;
1035 TQString KMFolderMaildir::constructValidFileName(
const TQString & filename,
1036 KMMsgStatus status )
1038 TQString aFileName( filename );
1040 if (aFileName.isEmpty())
1042 aFileName.sprintf(
"%ld.%d.", (
long)time(0), getpid());
1043 aFileName += TDEApplication::randomString(5);
1047 suffix_regex_sd.setObject(suffix_regex,
new TQRegExp(
":2,?R?S?$"));
1049 aFileName.truncate(aFileName.findRev(*suffix_regex));
1052 if (! ((status & KMMsgStatusNew) || (status & KMMsgStatusUnread)) )
1054 TQString suffix(
":2," );
1055 if (status & KMMsgStatusReplied)
1059 aFileName += suffix;
1066 TQString KMFolderMaildir::moveInternal(
const TQString& oldLoc,
const TQString& newLoc, KMMsgInfo *mi)
1068 TQString filename(mi->fileName());
1069 TQString ret(moveInternal(oldLoc, newLoc, filename, mi->status()));
1071 if (filename != mi->fileName())
1072 mi->setFileName(filename);
1078 TQString KMFolderMaildir::moveInternal(
const TQString& oldLoc,
const TQString& newLoc, TQString& aFileName, KMMsgStatus status)
1080 TQString dest(newLoc);
1082 while (TQFile::exists(dest))
1084 aFileName = constructValidFileName( TQString(), status );
1086 TQFileInfo fi(dest);
1087 dest = fi.dirPath(
true) +
"/" + aFileName;
1092 if (d.rename(oldLoc, dest) ==
false)
1099 void KMFolderMaildir::msgStatusChanged(
const KMMsgStatus oldStatus,
1100 const KMMsgStatus newStatus,
int idx)
1109 TQ_INT64 KMFolderMaildir::doFolderSize()
const 1111 if ( mCurrentlyCheckingFolderSize )
1115 mCurrentlyCheckingFolderSize =
true;
1118 KFileItem *item = 0;
1119 item =
new KFileItem( S_IFDIR, -1,
location() +
"/cur" );
1120 list.append( item );
1121 item =
new KFileItem( S_IFDIR, -1,
location() +
"/new" );
1122 list.append( item );
1123 item =
new KFileItem( S_IFDIR, -1,
location() +
"/tmp" );
1124 list.append( item );
1125 s_DirSizeJobQueue.append(
1126 tqMakePair( TQGuardedPtr<const KMFolderMaildir>(
this ), list ) );
1130 if ( s_DirSizeJobQueue.size() == 1 )
1134 KDirSize* job = KDirSize::dirSizeJob( list );
1135 connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
1136 this, TQT_SLOT( slotDirSizeJobResult( TDEIO::Job* ) ) );
1142 void KMFolderMaildir::slotDirSizeJobResult( TDEIO::Job* job )
1144 mCurrentlyCheckingFolderSize =
false;
1145 KDirSize * dirsize =
dynamic_cast<KDirSize*
>( job );
1146 if ( dirsize && ! dirsize->error() )
1148 mSize = dirsize->totalSize();
1154 s_DirSizeJobQueue.pop_front();
1157 while ( s_DirSizeJobQueue.size() > 0 )
1159 DirSizeJobQueueEntry entry = s_DirSizeJobQueue.first();
1166 KDirSize* job = KDirSize::dirSizeJob( entry.second );
1167 connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
1168 entry.first, TQT_SLOT( slotDirSizeJobResult( TDEIO::Job* ) ) );
1174 s_DirSizeJobQueue.pop_front();
1179 #include "kmfoldermaildir.moc" void setDirty(bool f)
Change the dirty flag.
virtual TQString indexLocation() const
Returns full path to index file.
off_t mHeaderOffset
offset of header of index file
void invalidateFolder()
Called when serial numbers for a folder are invalidated, invalidates/recreates data structures depend...
bool needsCompact
sven: true if on destruct folder needs to be compacted.
virtual int canAccess()=0
Check folder for permissions Returns zero if readable and writable.
A FolderStorage with an index for faster access to often used message properties. ...
virtual void msgStatusChanged(const KMMsgStatus oldStatus, const KMMsgStatus newStatus, int idx)
Called by KMMsgBase::setStatus when status of a message has changed required to keep the number unrea...
virtual void removeMsg(int i, bool imapQuiet=false)
Remove (first occurrence of) given message from the folder.
KMMessage * take(int idx)
Detach message from this folder.
IndexStatus
This enum indicates the status of the index file.
RAII for KMFolder::open() / close().
void clear(bool autoDelete=TRUE, bool syncDict=false)
Clear messages.
virtual int updateIndex()
Incrementally update the index if possible else call writeIndex.
KMMsgBase & toMsgBase()
Get KMMsgBase for this object.
FILE * mIndexStream
table of contents file
void setStatusFields()
Set "Status" and "X-Status" fields of the message from the internal message status.
void setHeaderField(const TQCString &name, const TQString &value, HeaderFieldType type=Unstructured, bool prepend=false)
Set the header field with the given name to the given value.
virtual bool canAddMsgNow(KMMessage *aMsg, int *aIndex_ret)
Returns FALSE, if the message has to be retrieved from an IMAP account first.
bool mAutoCreateIndex
is the automatic creation of a index file allowed ?
TQString location() const
Returns full path to folder file.
void setComplete(bool v)
Set if the message is a complete message.
virtual DwString getDwString(int idx)=0
Read a message and returns a DwString.
size_t crlf2lf(char *str, const size_t strLen)
Convert all sequences of "\r\n" (carriage return followed by a line feed) to a single "\n" (line feed...
bool readIndex()
Read index file and fill the message-info list mMsgList.
void setMsgSerNum(unsigned long newMsgSerNum=0)
Sets the message serial number.
void statusMsg(const TQString &)
Emmited to display a message somewhere in a status line.
A job that runs in the background and compacts maildir folders.
void numUnreadMsgsChanged(KMFolder *)
Emitted when number of unread messages has changed.
void setMsgInfo(KMMsgInfo *msgInfo)
Set the KMMsgInfo object corresponding to this message.
virtual int writeIndex(bool createEmptyIndex=false)
Write index to index-file.
bool reset(unsigned int size)
Clear the array and resize it to given size.
void close(const char *owner, bool force=false)
Close folder.
virtual void writeConfig()
Write the config file.
TQCString asString() const
Return the entire message contents as a string.
KMMsgList mMsgList
list of index entries or messages
void fromDwString(const DwString &str, bool setStatus=false)
Parse the string and create this message from it.
int find(const KMMsgBase *msg) const
Returns the index of the given message or -1 if not found.
void replaceMsgSerNum(unsigned long sernum, KMMsgBase *msg, int idx)
Replaces the serial number for the message msg at index idx with sernum.
int mUnreadMsgs
number of unread messages, -1 if not yet set
KMMessage * getMsg(int idx)
Read message at given index.
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
void folderSizeChanged()
Emitted when the folder's size changes.
KMMsgStatus status() const
Status of the message.
virtual int createIndexFromContents()=0
Create index file from messages file and fill the message-info list mMsgList.
unsigned int append(KMMsgBase *msg, bool syncDict=true)
Append given message after the last used message.
bool mCompactable
false if index file is out of sync with mbox file
void set(unsigned int idx, KMMsgBase *msg)
Set message at given index.
int appendToFolderIdsFile(int idx=-1)
Append message to end of message serial number file.
TQString fileName() const
Get/set filename in mail folder.
virtual void correctUnreadMsgsCount()
A cludge to help make sure the count of unread messges is kept in sync.
void removeHeaderField(const TQCString &name)
Remove header field with given name.
TQString label() const
Returns the label of the folder for visualization.
virtual IndexStatus indexStatus()=0
Tests whether the contents of this folder is newer than the index.
virtual KMMessage * take(int idx)
Detach message from this folder.
bool readyToShow() const
Return if the message is ready to be shown.
bool autoCreateIndex() const
Returns TRUE if a table of contents file is automatically created.
virtual int addMsg(TQPtrList< KMMessage > &, TQValueList< int > &index_return)
Adds the given messages to the folder.
TQString headerField(const TQCString &name) const
Returns the value of a header field with the given name.
virtual int count(bool cache=false) const
Number of messages in this folder.
unsigned int count() const
Number of messages in the array.
bool mExportsSernums
Has this storage exported its serial numbers to the global message dict for lookup?
void emitMsgAddedSignals(int idx)
Called by derived classes implementation of addMsg.