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) {
75 sBadFolderName = location();
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())
119 if (KMFolderIndex::IndexOk != indexStatus())
123 str = i18n(
"Folder `%1' changed; recreating index.")
127 mIndexStream = fopen(TQFile::encodeName(indexLocation()),
"r+");
128 if ( mIndexStream ) {
129 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
130 updateIndexStreamPtr();
135 rc = createIndexFromContents();
141 mAutoCreateIndex =
false;
142 rc = createIndexFromContents();
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);
203 mIndexStream = fopen(TQFile::encodeName(indexLocation()),
"w+");
204 updateIndexStreamPtr(
true);
207 if (!mIndexStream)
return errno;
208 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
212 mAutoCreateIndex =
false;
224 void KMFolderMaildir::reallyDoClose(
const char* owner)
227 if (mAutoCreateIndex)
233 mMsgList.clear(
true);
236 fclose(mIndexStream);
237 updateIndexStreamPtr(
true);
244 mMsgList.reset(INIT_MSGS);
248 void KMFolderMaildir::sync()
251 if (!mIndexStream || fsync(fileno(mIndexStream))) {
252 kmkernel->emergencyExit( i18n(
"Could not sync maildir folder.") );
257 int KMFolderMaildir::expungeContents()
260 TQDir d(location() +
"/new");
262 TQStringList files(d.entryList());
263 TQStringList::ConstIterator it(files.begin());
264 for ( ; it != files.end(); ++it)
265 TQFile::remove(d.filePath(*it));
267 d.setPath(location() +
"/cur");
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() :
281 TQMIN( mMsgList.count(), startIndex + nbMessages );
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);
317 done = ( stopIndex == mMsgList.count() );
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 );
353 if (!canAddMsgNow(aMsg, index_return))
return 0;
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())
450 if (mUnreadMsgs == -1)
455 kdDebug( 5006 ) <<
"FolderStorage::msgStatusChanged" << endl;
456 emit numUnreadMsgsChanged( folder() );
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);
478 idx = mMsgList.append( &aMsg->
toMsgBase(), mExportsSernums );
479 if (aMsg->getMsgSerNum() <= 0)
482 replaceMsgSerNum( aMsg->getMsgSerNum(), &aMsg->
toMsgBase(), idx );
485 if (mAutoCreateIndex)
487 assert(mIndexStream != 0);
488 clearerr(mIndexStream);
489 fseek(mIndexStream, 0, SEEK_END);
490 off_t revert = ftell(mIndexStream);
494 const uchar *buffer = mb->asIndexString(len);
495 fwrite(&len,
sizeof(len), 1, mIndexStream);
496 mb->setIndexOffset( ftell(mIndexStream) );
497 mb->setIndexLength( len );
498 if(fwrite(buffer, len, 1, mIndexStream) != 1)
499 kdDebug(5006) <<
"Whoa! " << __FILE__ <<
":" << __LINE__ << endl;
501 fflush(mIndexStream);
502 int error = ferror(mIndexStream);
504 if ( mExportsSernums )
505 error |= appendToFolderIdsFile( idx );
508 kdDebug(5006) <<
"Error: Could not add message to folder (No space left on device?)" << endl;
509 if (ftell(mIndexStream) > revert) {
510 kdDebug(5006) <<
"Undoing changes" << endl;
511 truncate( TQFile::encodeName(indexLocation()), revert );
513 kmkernel->emergencyExit(i18n(
"KMFolderMaildir::addMsg: abnormally terminating to prevent data loss."));
532 emitMsgAddedSignals(idx);
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() );
735 mMsgList.append( mi, mExportsSernums );
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()))
828 if (mUnreadMsgs == 0) ++mUnreadMsgs;
831 ::chdir(path_buffer);
834 int KMFolderMaildir::createIndexFromContents()
838 mMsgList.clear(
true);
839 mMsgList.reset(INIT_MSGS);
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;
853 TQDir newDir(location() +
"/new");
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;
862 TQDir curDir(location() +
"/cur");
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);
886 if ( autoCreateIndex() ) {
887 emit statusMsg(i18n(
"Writing index file"));
890 else mHeaderOffset = 0;
892 correctUnreadMsgsCount();
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");
912 TQFileInfo index_info(indexLocation());
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)
929 KMMsgBase* msg = mMsgList[idx];
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;
1022 TQDir dir(location());
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)
1102 needsCompact =
true;
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 qMakePair( TQGuardedPtr<const KMFolderMaildir>(
this ), list ) );
1129 if ( s_DirSizeJobQueue.size() == 1 )
1133 KDirSize* job = KDirSize::dirSizeJob( list );
1134 connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ),
1135 this, TQ_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();
1150 emit folderSizeChanged();
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, TQ_SIGNAL( result( TDEIO::Job* ) ),
1167 entry.first, TQ_SLOT( slotDirSizeJobResult( TDEIO::Job* ) ) );
1173 s_DirSizeJobQueue.pop_front();
1178 #include "kmfoldermaildir.moc"
virtual KMMessage * take(int idx)
Detach message from this folder.
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.
virtual int addMsg(TQPtrList< KMMessage > &, TQValueList< int > &index_return)
Adds the given messages to the folder.
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
A FolderStorage with an index for faster access to often used message properties.
IndexStatus
This enum indicates the status of the index file.
RAII for KMFolder::open() / close().
KMMessage * take(int idx)
Detach message from this folder.
KMMessage * getMsg(int idx)
Read message at given index.
int find(const KMMsgBase *msg) const
Returns the index of the given message or -1 if not found.
bool readyToShow() const
Return if the message is ready to be shown.
void setStatusFields()
Set "Status" and "X-Status" fields of the message from the internal message status.
void removeHeaderField(const TQCString &name)
Remove header field with given name.
void fromDwString(const DwString &str, bool setStatus=false)
Parse the string and create this message from it.
TQCString asString() const
Return the entire message contents as a string.
void setMsgSerNum(unsigned long newMsgSerNum=0)
Sets the message serial number.
void setComplete(bool v)
Set if the message is a complete message.
KMMsgStatus status() const
Status of the message.
TQString headerField(const TQCString &name) const
Returns the value of a header field with the given name.
TQString fileName() const
Get/set filename in mail folder.
KMMsgBase & toMsgBase()
Get KMMsgBase for this object.
void setMsgInfo(KMMsgInfo *msgInfo)
Set the KMMsgInfo object corresponding to this message.
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.
A job that runs in the background and compacts maildir folders.
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...