11 #include <libtdepim/tdefileio.h> 12 #include "kmfoldermaildir.h" 13 #include "kmfoldermgr.h" 15 #include "undostack.h" 16 #include "maildirjob.h" 17 #include "kcursorsaver.h" 18 #include "jobscheduler.h" 19 using KMail::MaildirJob;
20 #include "compactionjob.h" 21 #include "kmmsgdict.h" 24 #include <tdeapplication.h> 26 #include <tdelocale.h> 27 #include <kstaticdeleter.h> 28 #include <tdemessagebox.h> 35 #include <sys/types.h> 50 TQValueList<KMFolderMaildir::DirSizeJobQueueEntry> KMFolderMaildir::s_DirSizeJobQueue;
53 KMFolderMaildir::KMFolderMaildir(
KMFolder* folder,
const char* name)
54 :
KMFolderIndex(folder, name), mCurrentlyCheckingFolderSize(false)
61 KMFolderMaildir::~KMFolderMaildir()
63 if (mOpenCount>0)
close(
"~foldermaildir",
true);
64 if (kmkernel->undoStack()) kmkernel->undoStack()->folderDestroyed( folder() );
68 int KMFolderMaildir::canAccess()
71 assert(!folder()->name().isEmpty());
73 TQString sBadFolderName;
74 if (access(TQFile::encodeName(
location()), R_OK | W_OK | X_OK) != 0) {
76 }
else if (access(TQFile::encodeName(
location() +
"/new"), R_OK | W_OK | X_OK) != 0) {
77 sBadFolderName =
location() +
"/new";
78 }
else if (access(TQFile::encodeName(
location() +
"/cur"), R_OK | W_OK | X_OK) != 0) {
79 sBadFolderName =
location() +
"/cur";
80 }
else if (access(TQFile::encodeName(
location() +
"/tmp"), R_OK | W_OK | X_OK) != 0) {
81 sBadFolderName =
location() +
"/tmp";
84 if ( !sBadFolderName.isEmpty() ) {
85 int nRetVal = TQFile::exists(sBadFolderName) ? EPERM : ENOENT;
87 if ( nRetVal == ENOENT )
88 KMessageBox::sorry(0, i18n(
"Error opening %1; this folder is missing.")
89 .arg(sBadFolderName));
91 KMessageBox::sorry(0, i18n(
"Error opening %1; either this is not a valid " 92 "maildir folder, or you do not have sufficient access permissions.")
93 .arg(sBadFolderName));
101 int KMFolderMaildir::open(
const char *)
106 kmkernel->jobScheduler()->notifyOpeningFolder( folder() );
108 if (mOpenCount > 1)
return 0;
110 assert(!folder()->name().isEmpty());
117 if (!folder()->path().isEmpty())
123 str = i18n(
"Folder `%1' changed; recreating index.")
130 updateIndexStreamPtr();
154 int KMFolderMaildir::createMaildirFolders(
const TQString & folderPath )
158 dirinfo.setFile( folderPath +
"/new" );
159 if ( dirinfo.exists() )
return EEXIST;
160 dirinfo.setFile( folderPath +
"/cur" );
161 if ( dirinfo.exists() )
return EEXIST;
162 dirinfo.setFile( folderPath +
"/tmp" );
163 if ( dirinfo.exists() )
return EEXIST;
166 if ( ::mkdir( TQFile::encodeName( folderPath ), S_IRWXU ) > 0 ) {
167 kdDebug(5006) <<
"Could not create folder " << folderPath << endl;
170 if ( ::mkdir( TQFile::encodeName( folderPath +
"/new" ), S_IRWXU ) > 0 ) {
171 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/new" << endl;
174 if ( ::mkdir( TQFile::encodeName( folderPath +
"/cur" ), S_IRWXU ) > 0 ) {
175 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/cur" << endl;
178 if ( ::mkdir( TQFile::encodeName( folderPath +
"/tmp" ), S_IRWXU ) > 0 ) {
179 kdDebug(5006) <<
"Could not create folder " << folderPath <<
"/tmp" << endl;
187 int KMFolderMaildir::create()
192 assert(!folder()->name().isEmpty());
193 assert(mOpenCount == 0);
195 rc = createMaildirFolders(
location() );
200 if (!folder()->path().isEmpty())
202 old_umask = umask(077);
204 updateIndexStreamPtr(
true);
224 void KMFolderMaildir::reallyDoClose(
const char* owner)
237 updateIndexStreamPtr(
true);
248 void KMFolderMaildir::sync()
252 kmkernel->emergencyExit( i18n(
"Could not sync maildir folder.") );
257 int KMFolderMaildir::expungeContents()
262 TQStringList files(d.entryList());
263 TQStringList::ConstIterator it(files.begin());
264 for ( ; it != files.end(); ++it)
265 TQFile::remove(d.filePath(*it));
268 files = d.entryList();
269 for (it = files.begin(); it != files.end(); ++it)
270 TQFile::remove(d.filePath(*it));
275 int KMFolderMaildir::compact(
unsigned int startIndex,
int nbMessages,
const TQStringList& entryList,
bool& done )
277 TQString subdirNew(
location() +
"/new/");
278 TQString subdirCur(
location() +
"/cur/");
280 unsigned int stopIndex = nbMessages == -1 ?
mMsgList.
count() :
283 for(
unsigned int idx = startIndex; idx < stopIndex; ++idx) {
284 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList.at(idx);
288 TQString filename(mi->fileName());
289 if (filename.isEmpty())
293 if ( entryList.contains( filename ) )
294 moveInternal(subdirNew + filename, subdirCur + filename, mi);
298 filename = constructValidFileName( filename, mi->status() );
301 if (filename != mi->fileName())
303 moveInternal(subdirCur + mi->fileName(), subdirCur + filename, mi);
304 mi->setFileName(filename);
312 mi->setStatus(KMMsgStatusUnread);
322 int KMFolderMaildir::compact(
bool silent )
325 int rc = job->executeNow( silent );
332 KMFolderMaildir::doCreateJob(
KMMessage *msg, FolderJob::JobType jt,
333 KMFolder *folder, TQString,
const AttachmentStrategy* )
const 335 MaildirJob *job =
new MaildirJob( msg, jt, folder );
336 job->setParentFolder(
this );
342 KMFolderMaildir::doCreateJob( TQPtrList<KMMessage>& msgList,
const TQString& sets,
343 FolderJob::JobType jt,
KMFolder *folder )
const 345 MaildirJob *job =
new MaildirJob( msgList, sets, jt, folder );
346 job->setParentFolder(
this );
354 return addMsgInternal( aMsg, index_return );
358 int KMFolderMaildir::addMsgInternal(
KMMessage* aMsg,
int* index_return,
377 msgParent = aMsg->parent();
380 if (msgParent==folder() && !kmkernel->folderIsDraftOrOutbox(folder()))
383 idx = msgParent->
find(aMsg);
392 const TQString uidHeader = aMsg->
headerField(
"X-UID" );
393 if ( !uidHeader.isEmpty() && stripUid )
397 len = msgText.length();
401 if ( !uidHeader.isEmpty() && stripUid )
406 kdDebug(5006) <<
"Message added to folder `" << name() <<
"' contains no data. Ignoring it." << endl;
411 TQString filename = constructValidFileName( aMsg->
fileName(), aMsg->
status() );
413 TQString tmp_file(
location() +
"/tmp/");
414 tmp_file += filename;
416 if (!KPIM::kCStringToFile(msgText, tmp_file,
false,
false,
false))
417 kmkernel->emergencyExit( i18n(
"Message could not be added to the folder, possibly disk space is low.") );
419 TQFile file(tmp_file);
420 size = msgText.length();
423 rc = openThis.openResult();
426 kdDebug(5006) <<
"KMFolderMaildir::addMsg-open: " << rc <<
" of folder: " <<
label() << endl;
431 TQString new_loc(
location() +
"/cur/");
433 if (moveInternal(tmp_file, new_loc, filename, aMsg->
status()).isNull())
439 if (msgParent && idx >= 0)
440 msgParent->
take(idx);
443 if ( stripUid ) aMsg->setUID( 0 );
446 aMsg->setFileName(filename);
448 if (aMsg->isUnread() || aMsg->isNew() || folder() == kmkernel->outboxFolder())
455 kdDebug( 5006 ) <<
"FolderStorage::msgStatusChanged" << endl;
458 if ( !mEmitChangedTimer->isActive() ) {
460 mEmitChangedTimer->start( 3000 );
468 if ( aMsg->attachmentState() == KMMsgAttachmentUnknown && aMsg->
readyToShow() ) {
469 aMsg->updateAttachmentState();
471 if ( aMsg->invitationState() == KMMsgInvitationUnknown && aMsg->
readyToShow() ) {
472 aMsg->updateInvitationState();
476 aMsg->setParent(folder());
477 aMsg->setMsgSize(size);
479 if (aMsg->getMsgSerNum() <= 0)
494 const uchar *buffer = mb->asIndexString(len);
497 mb->setIndexLength( len );
499 kdDebug(5006) <<
"Whoa! " << __FILE__ <<
":" << __LINE__ << endl;
508 kdDebug(5006) <<
"Error: Could not add message to folder (No space left on device?)" << endl;
510 kdDebug(5006) <<
"Undoing changes" << endl;
513 kmkernel->emergencyExit(i18n(
"KMFolderMaildir::addMsg: abnormally terminating to prevent data loss."));
546 KMMessage* KMFolderMaildir::readMsg(
int idx)
548 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList[idx];
557 DwString KMFolderMaildir::getDwString(
int idx)
559 KMMsgInfo* mi = (KMMsgInfo*)
mMsgList[idx];
560 TQString abs_file(
location() +
"/cur/");
561 abs_file += mi->fileName();
562 TQFileInfo fi( abs_file );
564 if (fi.exists() && fi.isFile() && fi.isWritable() && fi.size() > 0)
566 FILE* stream = fopen(TQFile::encodeName(abs_file),
"r+");
568 size_t msgSize = fi.size();
569 char* msgText =
new char[ msgSize + 1 ];
570 fread(msgText, msgSize, 1, stream);
572 msgText[msgSize] =
'\0';
576 str.TakeBuffer( msgText, msgSize + 1, 0, newMsgSize );
580 kdDebug(5006) <<
"Could not open file r+ " << abs_file << endl;
585 void KMFolderMaildir::readFileHeaderIntern(
const TQString& dir,
const TQString& file, KMMsgStatus status)
588 char path_buffer[PATH_MAX];
589 if(!::getcwd(path_buffer, PATH_MAX - 1))
592 ::chdir(TQFile::encodeName(dir));
596 if (status == KMMsgStatusRead)
598 if (file.find(
":2,") == -1)
599 status = KMMsgStatusUnread;
600 else if (file.right(5) ==
":2,RS")
601 status |= KMMsgStatusReplied;
606 if ( f.open( IO_ReadOnly ) == false ) {
607 kdWarning(5006) <<
"The file '" << TQString(TQFile::encodeName(dir)) <<
"/" << file
608 <<
"' could not be opened for reading the message. " 609 "Please check ownership and permissions." 616 bool inHeader =
true;
617 TQCString *lastStr = 0;
619 TQCString dateStr, fromStr, toStr, subjStr;
620 TQCString xmarkStr, replyToIdStr, msgIdStr, referencesStr;
621 TQCString statusStr, replyToAuxIdStr, uidStr;
622 TQCString contentTypeStr, charset;
628 if ( f.atEnd() || ( -1 == f.readLine(line, MAX_LINE) ) )
633 if (atEof || !inHeader)
635 msgIdStr = msgIdStr.stripWhiteSpace();
636 if( !msgIdStr.isEmpty() ) {
638 rightAngle = msgIdStr.find(
'>' );
639 if( rightAngle != -1 )
640 msgIdStr.truncate( rightAngle + 1 );
643 replyToIdStr = replyToIdStr.stripWhiteSpace();
644 if( !replyToIdStr.isEmpty() ) {
646 rightAngle = replyToIdStr.find(
'>' );
647 if( rightAngle != -1 )
648 replyToIdStr.truncate( rightAngle + 1 );
651 referencesStr = referencesStr.stripWhiteSpace();
652 if( !referencesStr.isEmpty() ) {
653 int leftAngle, rightAngle;
654 leftAngle = referencesStr.findRev(
'<' );
655 if( ( leftAngle != -1 )
656 && ( replyToIdStr.isEmpty() || ( replyToIdStr[0] !=
'<' ) ) ) {
658 replyToIdStr = referencesStr.mid( leftAngle );
662 leftAngle = referencesStr.findRev(
'<', leftAngle - 1 );
663 if( leftAngle != -1 )
664 referencesStr = referencesStr.mid( leftAngle );
665 rightAngle = referencesStr.findRev(
'>' );
666 if( rightAngle != -1 )
667 referencesStr.truncate( rightAngle + 1 );
673 replyToAuxIdStr = referencesStr;
674 rightAngle = referencesStr.find(
'>' );
675 if( rightAngle != -1 )
676 replyToAuxIdStr.truncate( rightAngle + 1 );
679 statusStr = statusStr.stripWhiteSpace();
680 if (!statusStr.isEmpty())
683 if (statusStr[0] ==
'S')
684 status |= KMMsgStatusSent;
685 else if (statusStr[0] ==
'F')
686 status |= KMMsgStatusForwarded;
687 else if (statusStr[0] ==
'D')
688 status |= KMMsgStatusDeleted;
689 else if (statusStr[0] ==
'Q')
690 status |= KMMsgStatusQueued;
691 else if (statusStr[0] ==
'G')
692 status |= KMMsgStatusFlag;
695 contentTypeStr = contentTypeStr.stripWhiteSpace();
697 if ( !contentTypeStr.isEmpty() )
699 int cidx = contentTypeStr.find(
"charset=" );
701 charset = contentTypeStr.mid( cidx + 8 );
702 if ( !charset.isEmpty() && ( charset[0] ==
'"' ) ) {
703 charset = charset.mid( 1 );
706 while ( (
unsigned int) cidx < charset.length() ) {
707 if ( charset[cidx] ==
'"' || ( !isalnum(charset[cidx]) &&
708 charset[cidx] !=
'-' && charset[cidx] !=
'_' ) )
712 charset.truncate( cidx );
718 KMMsgInfo *mi =
new KMMsgInfo(folder());
719 mi->init( subjStr.stripWhiteSpace(),
720 fromStr.stripWhiteSpace(),
721 toStr.stripWhiteSpace(),
723 xmarkStr.stripWhiteSpace(),
724 replyToIdStr, replyToAuxIdStr, msgIdStr,
726 KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
727 KMMsgMDNStateUnknown, charset, f.size() );
729 dateStr = dateStr.stripWhiteSpace();
730 if (!dateStr.isEmpty())
731 mi->setDate(dateStr.data());
732 if ( !uidStr.isEmpty() )
733 mi->setUID( uidStr.toULong() );
738 if (status & KMMsgStatusNew)
740 TQString newDir(
location() +
"/new/");
741 TQString curDir(
location() +
"/cur/");
742 moveInternal(newDir + file, curDir + file, mi);
749 if (inHeader && ( line[0] ==
'\t' || line[0] ==
' ' ) )
752 while (line[i] ==
'\t' || line[i] ==
' ')
754 if (line[i] <
' ' && line[i] > 0)
758 *lastStr += line + i;
763 if (inHeader && (line[0] ==
'\n' || line[0] ==
'\r'))
768 if (strncasecmp(line,
"Date:", 5) == 0)
770 dateStr = TQCString(line+5);
773 else if (strncasecmp(line,
"From:", 5) == 0)
775 fromStr = TQCString(line+5);
778 else if (strncasecmp(line,
"To:", 3) == 0)
780 toStr = TQCString(line+3);
783 else if (strncasecmp(line,
"Subject:", 8) == 0)
785 subjStr = TQCString(line+8);
788 else if (strncasecmp(line,
"References:", 11) == 0)
790 referencesStr = TQCString(line+11);
791 lastStr = &referencesStr;
793 else if (strncasecmp(line,
"Message-Id:", 11) == 0)
795 msgIdStr = TQCString(line+11);
798 else if (strncasecmp(line,
"X-KMail-Mark:", 13) == 0)
800 xmarkStr = TQCString(line+13);
802 else if (strncasecmp(line,
"X-Status:", 9) == 0)
804 statusStr = TQCString(line+9);
806 else if (strncasecmp(line,
"In-Reply-To:", 12) == 0)
808 replyToIdStr = TQCString(line+12);
809 lastStr = &replyToIdStr;
811 else if (strncasecmp(line,
"X-UID:", 6) == 0)
813 uidStr = TQCString(line+6);
816 else if (strncasecmp(line,
"Content-Type:", 13) == 0)
818 contentTypeStr = TQCString(line+13);
819 lastStr = &contentTypeStr;
824 if (status & KMMsgStatusNew || status & KMMsgStatusUnread ||
825 (folder() == kmkernel->outboxFolder()))
831 ::chdir(path_buffer);
834 int KMFolderMaildir::createIndexFromContents()
847 dirinfo.setFile(
location() +
"/new");
848 if (!dirinfo.exists() || !dirinfo.isDir())
850 kdDebug(5006) <<
"Directory " <<
location() <<
"/new doesn't exist or is a file"<< endl;
854 newDir.setFilter(TQDir::Files);
856 dirinfo.setFile(
location() +
"/cur");
857 if (!dirinfo.exists() || !dirinfo.isDir())
859 kdDebug(5006) <<
"Directory " <<
location() <<
"/cur doesn't exist or is a file"<< endl;
863 curDir.setFilter(TQDir::Files);
866 const TQFileInfoList *list = curDir.entryInfoList();
867 TQFileInfoListIterator it(*list);
870 while ((fi = it.current()))
872 readFileHeaderIntern(curDir.path(), fi->fileName(), KMMsgStatusRead);
877 list = newDir.entryInfoList();
880 while ((fi=it.current()))
882 readFileHeaderIntern(newDir.path(), fi->fileName(), KMMsgStatusNew);
887 emit
statusMsg(i18n(
"Writing index file"));
894 if (kmkernel->outboxFolder() == folder() &&
count() > 0)
895 KMessageBox::information(0, i18n(
"Your outbox contains messages which were " 896 "most-likely not created by KMail;\nplease remove them from there if you " 897 "do not want KMail to send them."));
908 return KMFolderIndex::IndexCorrupt;
910 TQFileInfo new_info(
location() +
"/new");
911 TQFileInfo cur_info(
location() +
"/cur");
914 if (!index_info.exists())
915 return KMFolderIndex::IndexMissing;
920 return ((new_info.lastModified() > index_info.lastModified().addSecs(5)) ||
921 (cur_info.lastModified() > index_info.lastModified().addSecs(5)))
922 ? KMFolderIndex::IndexTooOld
923 : KMFolderIndex::IndexOk;
927 void KMFolderMaildir::removeMsg(
int idx,
bool)
930 if (!msg || !msg->fileName())
return;
932 removeFile(msg->fileName());
938 KMMessage* KMFolderMaildir::take(
int idx)
947 if ( removeFile(msg->
fileName()) ) {
955 bool KMFolderMaildir::removeFile(
const TQString & folderPath,
956 const TQString & filename )
962 TQCString abs_file( TQFile::encodeName( folderPath +
"/cur/" + filename ) );
963 if ( ::unlink( abs_file ) == 0 )
966 if ( errno == ENOENT ) {
967 abs_file = TQFile::encodeName( folderPath +
"/new/" + filename );
968 if ( ::unlink( abs_file ) == 0 )
972 kdDebug(5006) <<
"Can't delete " << abs_file <<
" " << perror << endl;
976 bool KMFolderMaildir::removeFile(
const TQString & filename )
978 return removeFile(
location(), filename );
981 #include <sys/types.h> 983 static bool removeDirAndContentsRecursively(
const TQString & path )
989 d.setFilter( TQDir::Files | TQDir::Dirs | TQDir::Hidden | TQDir::NoSymLinks );
991 const TQFileInfoList *list = d.entryInfoList();
992 TQFileInfoListIterator it( *list );
995 while ( (fi = it.current()) != 0 ) {
997 if ( fi->fileName() !=
"." && fi->fileName() !=
".." )
998 success = success && removeDirAndContentsRecursively( fi->absFilePath() );
1000 success = success && d.remove( fi->absFilePath() );
1006 success = success && d.rmdir( path );
1012 int KMFolderMaildir::removeContents()
1016 if ( !removeDirAndContentsRecursively(
location() +
"/new/" ) )
return 1;
1017 if ( !removeDirAndContentsRecursively(
location() +
"/cur/" ) )
return 1;
1018 if ( !removeDirAndContentsRecursively(
location() +
"/tmp/" ) )
return 1;
1023 if ( dir.count() == 2 ) {
1024 if ( !removeDirAndContentsRecursively(
location() ), 0 )
return 1;
1029 static TQRegExp *suffix_regex = 0;
1030 static KStaticDeleter<TQRegExp> suffix_regex_sd;
1034 TQString KMFolderMaildir::constructValidFileName(
const TQString & filename,
1035 KMMsgStatus status )
1037 TQString aFileName( filename );
1039 if (aFileName.isEmpty())
1041 aFileName.sprintf(
"%ld.%d.", (
long)time(0), getpid());
1042 aFileName += TDEApplication::randomString(5);
1046 suffix_regex_sd.setObject(suffix_regex,
new TQRegExp(
":2,?R?S?$"));
1048 aFileName.truncate(aFileName.findRev(*suffix_regex));
1051 if (! ((status & KMMsgStatusNew) || (status & KMMsgStatusUnread)) )
1053 TQString suffix(
":2," );
1054 if (status & KMMsgStatusReplied)
1058 aFileName += suffix;
1065 TQString KMFolderMaildir::moveInternal(
const TQString& oldLoc,
const TQString& newLoc, KMMsgInfo *mi)
1067 TQString filename(mi->fileName());
1068 TQString ret(moveInternal(oldLoc, newLoc, filename, mi->status()));
1070 if (filename != mi->fileName())
1071 mi->setFileName(filename);
1077 TQString KMFolderMaildir::moveInternal(
const TQString& oldLoc,
const TQString& newLoc, TQString& aFileName, KMMsgStatus status)
1079 TQString dest(newLoc);
1081 while (TQFile::exists(dest))
1083 aFileName = constructValidFileName( TQString(), status );
1085 TQFileInfo fi(dest);
1086 dest = fi.dirPath(
true) +
"/" + aFileName;
1091 if (d.rename(oldLoc, dest) ==
false)
1098 void KMFolderMaildir::msgStatusChanged(
const KMMsgStatus oldStatus,
1099 const KMMsgStatus newStatus,
int idx)
1108 TQ_INT64 KMFolderMaildir::doFolderSize()
const 1110 if ( mCurrentlyCheckingFolderSize )
1114 mCurrentlyCheckingFolderSize =
true;
1117 KFileItem *item = 0;
1118 item =
new KFileItem( S_IFDIR, -1,
location() +
"/cur" );
1119 list.append( item );
1120 item =
new KFileItem( S_IFDIR, -1,
location() +
"/new" );
1121 list.append( item );
1122 item =
new KFileItem( S_IFDIR, -1,
location() +
"/tmp" );
1123 list.append( item );
1124 s_DirSizeJobQueue.append(
1125 tqMakePair( TQGuardedPtr<const KMFolderMaildir>(
this ), list ) );
1129 if ( s_DirSizeJobQueue.size() == 1 )
1133 KDirSize* job = KDirSize::dirSizeJob( list );
1134 connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
1135 this, TQT_SLOT( slotDirSizeJobResult( TDEIO::Job* ) ) );
1141 void KMFolderMaildir::slotDirSizeJobResult( TDEIO::Job* job )
1143 mCurrentlyCheckingFolderSize =
false;
1144 KDirSize * dirsize =
dynamic_cast<KDirSize*
>( job );
1145 if ( dirsize && ! dirsize->error() )
1147 mSize = dirsize->totalSize();
1153 s_DirSizeJobQueue.pop_front();
1156 while ( s_DirSizeJobQueue.size() > 0 )
1158 DirSizeJobQueueEntry entry = s_DirSizeJobQueue.first();
1165 KDirSize* job = KDirSize::dirSizeJob( entry.second );
1166 connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
1167 entry.first, TQT_SLOT( slotDirSizeJobResult( TDEIO::Job* ) ) );
1173 s_DirSizeJobQueue.pop_front();
1178 #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.