21 #include <tqfileinfo.h>
24 #include "kmfoldermbox.h"
25 #include "folderstorage.h"
28 #include "kmmsgdict.h"
29 #include "undostack.h"
30 #include "kcursorsaver.h"
31 #include "jobscheduler.h"
32 #include "compactionjob.h"
36 #include <tdelocale.h>
37 #include <tdemessagebox.h>
38 #include <knotifyclient.h>
40 #include <tdeconfig.h>
54 #include <sys/types.h>
57 #include "broadcaststatus.h"
58 using KPIM::BroadcastStatus;
69 #define MSG_SEPERATOR_START "From "
70 #define MSG_SEPERATOR_START_LEN (sizeof(MSG_SEPERATOR_START) - 1)
71 #define MSG_SEPERATOR_REGEX "^From .*[0-9][0-9]:[0-9][0-9]"
75 KMFolderMbox::KMFolderMbox(
KMFolder* folder,
const char* name)
81 mLockType = lock_none;
86 KMFolderMbox::~KMFolderMbox()
89 close(
"~kmfoldermbox",
true);
90 if (kmkernel->undoStack())
91 kmkernel->undoStack()->folderDestroyed( folder() );
95 int KMFolderMbox::open(
const char *owner)
101 kmkernel->jobScheduler()->notifyOpeningFolder( folder() );
103 if (mOpenCount > 1)
return 0;
105 assert(!folder()->name().isEmpty());
107 mFilesLocked =
false;
108 mStream = fopen(TQFile::encodeName(location()),
"r+");
111 KNotifyClient::event( 0,
"warning",
112 i18n(
"Cannot open file \"%1\":\n%2").arg(location()).arg(strerror(errno)));
113 kdDebug(5006) <<
"Cannot open folder `" << location() <<
"': " << strerror(errno) << endl;
120 if (!folder()->path().isEmpty())
124 if (KMFolderIndex::IndexOk != index_status)
128 if (KMFolderIndex::IndexTooOld == index_status) {
129 TQString msg = i18n(
"<qt><p>The index of folder '%2' seems "
130 "to be out of date. To prevent message "
131 "corruption the index will be "
132 "regenerated. As a result deleted "
133 "messages might reappear and status "
134 "flags might be lost.</p>"
135 "<p>Please read the corresponding entry "
136 "in the <a href=\"%1\">FAQ section of the manual "
138 "information about how to prevent this "
139 "problem from happening again.</p></qt>")
140 .arg(
"help:/kmail/faq.html#faq-index-regeneration")
146 if (kmkernel->startingUp())
148 TDEConfigGroup configGroup( KMKernel::config(),
"Notification Messages" );
150 configGroup.readBoolEntry(
"showIndexRegenerationMessage",
true );
152 KMessageBox::queuedMessageBox( 0, KMessageBox::Information,
153 msg, i18n(
"Index Out of Date"),
154 KMessageBox::AllowLink );
159 KMessageBox::information( 0, msg, i18n(
"Index Out of Date"),
160 "showIndexRegenerationMessage",
161 KMessageBox::AllowLink );
166 str = i18n(
"Folder `%1' changed. Recreating index.")
170 mIndexStream = fopen(TQFile::encodeName(indexLocation()),
"r+");
171 if ( mIndexStream ) {
172 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
173 updateIndexStreamPtr();
178 rc = createIndexFromContents();
181 rc = createIndexFromContents();
185 mAutoCreateIndex =
false;
186 rc = createIndexFromContents();
191 fcntl(fileno(mStream), F_SETFD, FD_CLOEXEC);
193 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
199 int KMFolderMbox::canAccess()
201 assert(!folder()->name().isEmpty());
203 if (access(TQFile::encodeName(location()), R_OK | W_OK) != 0) {
204 kdDebug(5006) <<
"KMFolderMbox::access call to access function failed" << endl;
211 int KMFolderMbox::create()
216 assert(!folder()->name().isEmpty());
217 assert(mOpenCount == 0);
219 kdDebug(5006) <<
"Creating folder " << name() << endl;
220 if (access(TQFile::encodeName(location()), F_OK) == 0) {
221 kdDebug(5006) <<
"KMFolderMbox::create call to access function failed." << endl;
222 kdDebug(5006) <<
"File:: " << endl;
223 kdDebug(5006) <<
"Error " << endl;
227 old_umask = umask(077);
228 mStream = fopen(TQFile::encodeName(location()),
"w+");
231 if (!mStream)
return errno;
233 fcntl(fileno(mStream), F_SETFD, FD_CLOEXEC);
235 if (!folder()->path().isEmpty())
237 old_umask = umask(077);
238 mIndexStream = fopen(TQFile::encodeName(indexLocation()),
"w+");
239 updateIndexStreamPtr(
true);
242 if (!mIndexStream)
return errno;
243 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
247 mAutoCreateIndex =
false;
260 void KMFolderMbox::reallyDoClose(
const char* owner)
263 if (mAutoCreateIndex)
265 if (KMFolderIndex::IndexOk != indexStatus()) {
266 kdDebug(5006) <<
"Critical error: " << location() <<
267 " has been modified by an external application while KMail was running." << endl;
276 if (mStream) unlock();
277 mMsgList.clear(
true);
279 if (mStream) fclose(mStream);
281 fclose(mIndexStream);
282 updateIndexStreamPtr(
true);
288 mFilesLocked =
false;
291 mMsgList.reset(INIT_MSGS);
295 void KMFolderMbox::sync()
298 if (!mStream || fsync(fileno(mStream)) ||
299 !mIndexStream || fsync(fileno(mIndexStream))) {
300 kmkernel->emergencyExit( i18n(
"Could not sync index file <b>%1</b>: %2").arg( indexLocation() ).arg(errno ? TQString::fromLocal8Bit(strerror(errno)) : i18n(
"Internal error. Please copy down the details and report a bug.")));
305 int KMFolderMbox::lock()
315 assert(mStream != 0);
316 mFilesLocked =
false;
322 rc = fcntl(fileno(mStream), F_SETLKW, &fl);
326 kdDebug(5006) <<
"Cannot lock folder `" << location() <<
"': "
327 << strerror(errno) <<
" (" << errno <<
")" << endl;
334 rc = fcntl(fileno(mIndexStream), F_SETLK, &fl);
338 kdDebug(5006) <<
"Cannot lock index of folder `" << location() <<
"': "
339 << strerror(errno) <<
" (" << errno <<
")" << endl;
342 fcntl(fileno(mIndexStream), F_SETLK, &fl);
349 case procmail_lockfile:
350 cmd_str =
"lockfile -l20 -r5 ";
351 if (!mProcmailLockFileName.isEmpty())
352 cmd_str += TQFile::encodeName(TDEProcess::quote(mProcmailLockFileName));
354 cmd_str += TQFile::encodeName(TDEProcess::quote(location() +
".lock"));
356 rc = system( cmd_str.data() );
359 kdDebug(5006) <<
"Cannot lock folder `" << location() <<
"': "
360 << strerror(rc) <<
" (" << rc <<
")" << endl;
366 cmd_str =
"lockfile -l20 -r5 " + TQFile::encodeName(TDEProcess::quote(indexLocation() +
".lock"));
367 rc = system( cmd_str.data() );
370 kdDebug(5006) <<
"Cannot lock index of folder `" << location() <<
"': "
371 << strerror(rc) <<
" (" << rc <<
")" << endl;
379 cmd_str =
"mutt_dotlock " + TQFile::encodeName(TDEProcess::quote(location()));
380 rc = system( cmd_str.data() );
383 kdDebug(5006) <<
"Cannot lock folder `" << location() <<
"': "
384 << strerror(rc) <<
" (" << rc <<
")" << endl;
390 cmd_str =
"mutt_dotlock " + TQFile::encodeName(TDEProcess::quote(indexLocation()));
391 rc = system( cmd_str.data() );
394 kdDebug(5006) <<
"Cannot lock index of folder `" << location() <<
"': "
395 << strerror(rc) <<
" (" << rc <<
")" << endl;
402 case mutt_dotlock_privileged:
403 cmd_str =
"mutt_dotlock -p " + TQFile::encodeName(TDEProcess::quote(location()));
404 rc = system( cmd_str.data() );
407 kdDebug(5006) <<
"Cannot lock folder `" << location() <<
"': "
408 << strerror(rc) <<
" (" << rc <<
")" << endl;
414 cmd_str =
"mutt_dotlock -p " + TQFile::encodeName(TDEProcess::quote(indexLocation()));
415 rc = system( cmd_str.data() );
418 kdDebug(5006) <<
"Cannot lock index of folder `" << location() <<
"': "
419 << strerror(rc) <<
" (" << rc <<
")" << endl;
438 KMFolderMbox::doCreateJob(
KMMessage *msg, FolderJob::JobType jt,
439 KMFolder *folder, TQString,
const AttachmentStrategy* )
const
441 MboxJob *job =
new MboxJob( msg, jt, folder );
442 job->setParent(
this );
448 KMFolderMbox::doCreateJob( TQPtrList<KMMessage>& msgList,
const TQString& sets,
449 FolderJob::JobType jt,
KMFolder *folder )
const
451 MboxJob *job =
new MboxJob( msgList, sets, jt, folder );
452 job->setParent(
this );
457 int KMFolderMbox::unlock()
467 assert(mStream != 0);
468 mFilesLocked =
false;
473 if (mIndexStream) fcntl(fileno(mIndexStream), F_SETLK, &fl);
474 fcntl(fileno(mStream), F_SETLK, &fl);
478 case procmail_lockfile:
480 if (!mProcmailLockFileName.isEmpty())
481 cmd_str += TQFile::encodeName(TDEProcess::quote(mProcmailLockFileName));
483 cmd_str += TQFile::encodeName(TDEProcess::quote(location() +
".lock"));
485 rc = system( cmd_str.data() );
488 cmd_str =
"rm -f " + TQFile::encodeName(TDEProcess::quote(indexLocation() +
".lock"));
489 rc = system( cmd_str.data() );
494 cmd_str =
"mutt_dotlock -u " + TQFile::encodeName(TDEProcess::quote(location()));
495 rc = system( cmd_str.data() );
498 cmd_str =
"mutt_dotlock -u " + TQFile::encodeName(TDEProcess::quote(indexLocation()));
499 rc = system( cmd_str.data() );
503 case mutt_dotlock_privileged:
504 cmd_str =
"mutt_dotlock -p -u " + TQFile::encodeName(TDEProcess::quote(location()));
505 rc = system( cmd_str.data() );
508 cmd_str =
"mutt_dotlock -p -u " + TQFile::encodeName(TDEProcess::quote(indexLocation()));
509 rc = system( cmd_str.data() );
527 return KMFolderIndex::IndexCorrupt;
529 TQFileInfo contInfo(location());
530 TQFileInfo indInfo(indexLocation());
532 if (!contInfo.exists())
return KMFolderIndex::IndexOk;
533 if (!indInfo.exists())
return KMFolderIndex::IndexMissing;
538 return ( contInfo.lastModified() > indInfo.lastModified().addSecs(5) )
539 ? KMFolderIndex::IndexTooOld
540 : KMFolderIndex::IndexOk;
545 int KMFolderMbox::createIndexFromContents()
548 char status[8], xstatus[8];
549 TQCString subjStr, dateStr, fromStr, toStr, xmarkStr, *lastStr=0;
550 TQCString replyToIdStr, replyToAuxIdStr, referencesStr, msgIdStr;
551 TQCString sizeServerStr, uidStr;
552 TQCString contentTypeStr, charset;
554 bool inHeader =
true;
557 TQRegExp regexp(MSG_SEPERATOR_REGEX);
558 int i, num, numStatus;
561 assert(mStream != 0);
578 replyToAuxIdStr =
"";
582 size_t sizeServer = 0;
588 off_t pos = ftell(mStream);
589 if (!fgets(line, MAX_LINE, mStream)) atEof =
true;
592 (memcmp(line, MSG_SEPERATOR_START, MSG_SEPERATOR_START_LEN)==0 &&
593 regexp.search(line) >= 0))
596 pos = ftell(mStream);
602 msgStr = i18n(
"Creating index file: one message done",
"Creating index file: %n messages done", num);
603 emit statusMsg(msgStr);
609 msgIdStr = msgIdStr.stripWhiteSpace();
610 if( !msgIdStr.isEmpty() ) {
612 rightAngle = msgIdStr.find(
'>' );
613 if( rightAngle != -1 )
614 msgIdStr.truncate( rightAngle + 1 );
617 replyToIdStr = replyToIdStr.stripWhiteSpace();
618 if( !replyToIdStr.isEmpty() ) {
620 rightAngle = replyToIdStr.find(
'>' );
621 if( rightAngle != -1 )
622 replyToIdStr.truncate( rightAngle + 1 );
625 referencesStr = referencesStr.stripWhiteSpace();
626 if( !referencesStr.isEmpty() ) {
627 int leftAngle, rightAngle;
628 leftAngle = referencesStr.findRev(
'<' );
629 if( ( leftAngle != -1 )
630 && ( replyToIdStr.isEmpty() || ( replyToIdStr[0] !=
'<' ) ) ) {
632 replyToIdStr = referencesStr.mid( leftAngle );
636 leftAngle = referencesStr.findRev(
'<', leftAngle - 1 );
637 if( leftAngle != -1 )
638 referencesStr = referencesStr.mid( leftAngle );
639 rightAngle = referencesStr.findRev(
'>' );
640 if( rightAngle != -1 )
641 referencesStr.truncate( rightAngle + 1 );
647 replyToAuxIdStr = referencesStr;
648 rightAngle = referencesStr.find(
'>' );
649 if( rightAngle != -1 )
650 replyToAuxIdStr.truncate( rightAngle + 1 );
653 contentTypeStr = contentTypeStr.stripWhiteSpace();
655 if ( !contentTypeStr.isEmpty() )
657 int cidx = contentTypeStr.find(
"charset=" );
659 charset = contentTypeStr.mid( cidx + 8 );
660 if ( !charset.isEmpty() && ( charset[0] ==
'"' ) ) {
661 charset = charset.mid( 1 );
664 while ( (
unsigned int) cidx < charset.length() ) {
665 if ( charset[cidx] ==
'"' || ( !isalnum(charset[cidx]) &&
666 charset[cidx] !=
'-' && charset[cidx] !=
'_' ) )
670 charset.truncate( cidx );
676 mi =
new KMMsgInfo(folder());
677 mi->init( subjStr.stripWhiteSpace(),
678 fromStr.stripWhiteSpace(),
679 toStr.stripWhiteSpace(),
681 xmarkStr.stripWhiteSpace(),
682 replyToIdStr, replyToAuxIdStr, msgIdStr,
683 KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
684 KMMsgMDNStateUnknown, charset, offs, size, sizeServer, uid );
685 mi->setStatus(status, xstatus);
686 mi->setDate( dateStr.stripWhiteSpace().data() );
688 mMsgList.append(mi, mExportsSernums );
695 replyToAuxIdStr =
"";
704 else num--,numStatus++;
707 offs = ftell(mStream);
714 if (inHeader && (line[0]==
'\t' || line[0]==
' '))
717 while (line [i]==
'\t' || line [i]==
' ') i++;
718 if (line [i] <
' ' && line [i]>0) inHeader =
false;
719 else if (lastStr) *lastStr += line + i;
723 if (inHeader && (line [0]==
'\n' || line [0]==
'\r'))
725 if (!inHeader)
continue;
730 if ((needStatus & 1) && strncasecmp(line,
"Status:", 7) == 0)
732 for(i=0; i<4 && line[i+8] >
' '; i++)
733 status[i] = line[i+8];
737 else if ((needStatus & 2) && strncasecmp(line,
"X-Status:", 9)==0)
739 for(i=0; i<4 && line[i+10] >
' '; i++)
740 xstatus[i] = line[i+10];
744 else if (strncasecmp(line,
"X-KMail-Mark:",13)==0)
745 xmarkStr = TQCString(line+13);
746 else if (strncasecmp(line,
"In-Reply-To:",12)==0) {
747 replyToIdStr = TQCString(line+12);
748 lastStr = &replyToIdStr;
750 else if (strncasecmp(line,
"References:",11)==0) {
751 referencesStr = TQCString(line+11);
752 lastStr = &referencesStr;
754 else if (strncasecmp(line,
"Message-Id:",11)==0) {
755 msgIdStr = TQCString(line+11);
758 else if (strncasecmp(line,
"Date:",5)==0)
760 dateStr = TQCString(line+5);
763 else if (strncasecmp(line,
"From:", 5)==0)
765 fromStr = TQCString(line+5);
768 else if (strncasecmp(line,
"To:", 3)==0)
770 toStr = TQCString(line+3);
773 else if (strncasecmp(line,
"Subject:",8)==0)
775 subjStr = TQCString(line+8);
778 else if (strncasecmp(line,
"X-Length:",9)==0)
780 sizeServerStr = TQCString(line+9);
781 sizeServer = sizeServerStr.toULong();
782 lastStr = &sizeServerStr;
784 else if (strncasecmp(line,
"X-UID:",6)==0)
786 uidStr = TQCString(line+6);
787 uid = uidStr.toULong();
790 else if (strncasecmp(line,
"Content-Type:", 13) == 0)
792 contentTypeStr = TQCString(line+13);
793 lastStr = &contentTypeStr;
797 if (mAutoCreateIndex)
799 emit statusMsg(i18n(
"Writing index file"));
802 else mHeaderOffset = 0;
804 correctUnreadMsgsCount();
806 if (kmkernel->outboxFolder() == folder() && count() > 0)
807 KMessageBox::queuedMessageBox(0, KMessageBox::Information,
808 i18n(
"Your outbox contains messages which were "
809 "most-likely not created by KMail;\nplease remove them from there if you "
810 "do not want KMail to send them."));
818 KMMessage* KMFolderMbox::readMsg(
int idx)
820 KMMsgInfo* mi = (KMMsgInfo*)mMsgList[idx];
822 assert(mi!=0 && !mi->isMessage());
823 assert(mStream != 0);
833 #define STRDIM(x) (sizeof(x)/sizeof(*x)-1)
835 static size_t unescapeFrom(
char* str,
size_t strLen ) {
838 if ( strLen <= STRDIM(
">From ") )
845 const char * s = str;
847 const char *
const e = str + strLen - STRDIM(
">From ");
850 if ( *s ==
'\n' && *(s+1) ==
'>' ) {
853 while ( s < e && *s == '>
' )
855 if ( tqstrncmp( s, "From ", STRDIM("From ") ) == 0 )
858 *d++ = *s++; // yes, s might be e here, but e is not the end :-)
861 while ( s < str + strLen )
863 if ( d < s ) // only NUL-terminate if it's shorter
870 TQByteArray KMFolderMbox::escapeFrom(
const DwString & str ) {
871 const unsigned int strLen = str.length();
872 if ( strLen <= STRDIM(
"From ") )
875 TQByteArray result(
int( strLen + 5 ) / 6 * 7 + 1 );
877 const char * s = str.data();
878 const char *
const e = s + strLen - STRDIM(
"From ");
879 char * d = result.data();
881 bool onlyAnglesAfterLF =
false;
885 onlyAnglesAfterLF =
true;
890 if ( onlyAnglesAfterLF && tqstrncmp( s+1,
"rom ", STRDIM(
"rom ") ) == 0 )
894 onlyAnglesAfterLF =
false;
899 while ( s < str.data() + strLen )
902 result.truncate( d - result.data() );
909 DwString KMFolderMbox::getDwString(
int idx)
911 KMMsgInfo* mi = (KMMsgInfo*)mMsgList[idx];
914 assert(mStream != 0);
916 size_t msgSize = mi->msgSize();
917 char* msgText =
new char[ msgSize + 1 ];
919 fseek(mStream, mi->folderOffset(), SEEK_SET);
920 fread(msgText, msgSize, 1, mStream);
921 msgText[msgSize] =
'\0';
923 size_t newMsgSize = unescapeFrom( msgText, msgSize );
928 msgStr.TakeBuffer( msgText, msgSize + 1, 0, newMsgSize );
936 if (!canAddMsgNow(aMsg, aIndex_ret))
return 0;
941 bool editing =
false;
945 rc = openThis.openResult();
948 kdDebug(5006) <<
"KMFolderMbox::addMsg-open: " << rc <<
" of folder: " << label() << endl;
953 msgParent = aMsg->parent();
956 if ( msgParent== folder() )
958 if (kmkernel->folderIsDraftOrOutbox( folder() ))
961 kdDebug(5006) <<
"Editing message in outbox or drafts" << endl;
968 idx = msgParent->
find(aMsg);
972 if (folderType() != KMFolderTypeImap)
995 size_t len = msgText.size();
997 assert(mStream != 0);
1001 kdDebug(5006) <<
"Message added to folder `" << name() <<
"' contains no data. Ignoring it." << endl;
1007 fseek(mStream, 0, SEEK_END);
1008 off_t revert = ftell(mStream);
1009 if (ftell(mStream) >= 2) {
1011 fseek(mStream, -2, SEEK_END);
1012 fread(endStr, 1, 2, mStream);
1013 if (ftell(mStream) > 0 && endStr[0]!=
'\n') {
1015 if (endStr[1]!=
'\n') {
1017 fwrite(
"\n\n", 1, 2, mStream);
1020 else fwrite(
"\n", 1, 1, mStream);
1023 fseek(mStream,0,SEEK_END);
1024 int error = ferror(mStream);
1029 fwrite( messageSeparator.data(), messageSeparator.length(), 1, mStream );
1030 off_t offs = ftell(mStream);
1031 fwrite(msgText.data(), len, 1, mStream);
1032 if (msgText[(
int)len-1]!=
'\n') fwrite(
"\n\n", 1, 2, mStream);
1034 size_t size = ftell(mStream) - offs;
1036 error = ferror(mStream);
1038 kdDebug(5006) <<
"Error: Could not add message to folder: " << strerror(errno) << endl;
1039 if (ftell(mStream) > revert) {
1040 kdDebug(5006) <<
"Undoing changes" << endl;
1041 truncate( TQFile::encodeName(location()), revert );
1043 kmkernel->emergencyExit( i18n(
"Could not add message to folder: ") + TQString::fromLocal8Bit(strerror(errno)));
1059 if (idx >= 0) msgParent->
take(idx);
1063 if (aMsg->isUnread() || aMsg->isNew() ||
1064 (folder() == kmkernel->outboxFolder())) {
1065 if (mUnreadMsgs == -1) mUnreadMsgs = 1;
1068 emit numUnreadMsgsChanged( folder() );
1073 if ( aMsg->attachmentState() == KMMsgAttachmentUnknown && aMsg->
readyToShow() ) {
1074 aMsg->updateAttachmentState();
1076 if ( aMsg->invitationState() == KMMsgInvitationUnknown && aMsg->
readyToShow() ) {
1077 aMsg->updateInvitationState();
1081 aMsg->setParent(folder());
1082 aMsg->setFolderOffset(offs);
1083 aMsg->setMsgSize(size);
1084 idx = mMsgList.append(&aMsg->
toMsgBase(), mExportsSernums );
1085 if ( aMsg->getMsgSerNum() <= 0 )
1088 replaceMsgSerNum( aMsg->getMsgSerNum(), &aMsg->
toMsgBase(), idx );
1091 if ((idx > 0) && (growth > 0)) {
1093 if ((ulong)revert == mMsgList[idx - 1]->folderOffset() + mMsgList[idx - 1]->msgSize() )
1094 mMsgList[idx - 1]->setMsgSize( mMsgList[idx - 1]->msgSize() + growth );
1098 if (mAutoCreateIndex)
1100 assert(mIndexStream != 0);
1101 clearerr(mIndexStream);
1102 fseek(mIndexStream, 0, SEEK_END);
1103 revert = ftell(mIndexStream);
1107 const uchar *buffer = mb->asIndexString(len);
1108 fwrite(&len,
sizeof(len), 1, mIndexStream);
1109 mb->setIndexOffset( ftell(mIndexStream) );
1110 mb->setIndexLength( len );
1111 if(fwrite(buffer, len, 1, mIndexStream) != 1)
1112 kdDebug(5006) <<
"Whoa! " << __FILE__ <<
":" << __LINE__ << endl;
1114 fflush(mIndexStream);
1115 error = ferror(mIndexStream);
1117 if ( mExportsSernums )
1118 error |= appendToFolderIdsFile( idx );
1121 kdWarning(5006) <<
"Error: Could not add message to folder (No space left on device?)" << endl;
1122 if (ftell(mIndexStream) > revert) {
1123 kdWarning(5006) <<
"Undoing changes" << endl;
1124 truncate( TQFile::encodeName(indexLocation()), revert );
1127 kmkernel->emergencyExit( i18n(
"Could not add message to folder:") + TQString::fromLocal8Bit(strerror(errno)));
1129 kmkernel->emergencyExit( i18n(
"Could not add message to folder (No space left on device?)") );
1144 if (aIndex_ret) *aIndex_ret = idx;
1145 emitMsgAddedSignals(idx);
1153 int KMFolderMbox::compact(
unsigned int startIndex,
int nbMessages, FILE* tmpfile, off_t& offs,
bool& done )
1157 unsigned int stopIndex = nbMessages == -1 ? mMsgList.count() :
1158 TQMIN( mMsgList.count(), startIndex + nbMessages );
1160 for(
unsigned int idx = startIndex; idx < stopIndex; ++idx) {
1161 KMMsgInfo* mi = (KMMsgInfo*)mMsgList.at(idx);
1162 size_t msize = mi->msgSize();
1163 if (mtext.size() < msize + 2)
1164 mtext.resize(msize+2);
1165 off_t folder_offset = mi->folderOffset();
1168 for(off_t i = folder_offset-25;
true; i -= 20) {
1169 off_t chunk_offset = i <= 0 ? 0 : i;
1170 if(fseek(mStream, chunk_offset, SEEK_SET) == -1) {
1174 if (mtext.size() < 20)
1176 fread(mtext.data(), 20, 1, mStream);
1178 if ( mtext.contains(
"from ",
false ) ) {
1179 if (mtext.size() < (size_t)folder_offset)
1180 mtext.resize(folder_offset);
1181 if(fseek(mStream, chunk_offset, SEEK_SET) == -1 ||
1182 !fread(mtext.data(), folder_offset, 1, mStream) ||
1183 !fwrite(mtext.data(), folder_offset, 1, tmpfile)) {
1187 offs += folder_offset;
1194 for(
int i2 = 0; i2 < 20; i2++) {
1195 if(*(mtext.data()+i2) ==
'\n')
1198 if(last_crlf != -1) {
1199 int size = folder_offset - (i + last_crlf+1);
1200 if ((
int)mtext.size() < size)
1202 if(fseek(mStream, i + last_crlf+1, SEEK_SET) == -1 ||
1203 !fread(mtext.data(), size, 1, mStream) ||
1204 !fwrite(mtext.data(), size, 1, tmpfile)) {
1217 if(fseek(mStream, folder_offset, SEEK_SET) == -1 ||
1218 !fread(mtext.data(), msize, 1, mStream) || !fwrite(mtext.data(), msize, 1, tmpfile)) {
1222 mi->setFolderOffset(offs);
1225 done = ( !rc && stopIndex == mMsgList.count() );
1230 int KMFolderMbox::compact(
bool silent )
1236 int rc = job->executeNow( silent );
1241 TQString statusMsg = BroadcastStatus::instance()->statusMsg();
1243 BroadcastStatus::instance()->setStatusMsg( statusMsg );
1249 void KMFolderMbox::setLockType( LockType ltype )
1255 void KMFolderMbox::setProcmailLockFileName(
const TQString &fname )
1257 mProcmailLockFileName = fname;
1261 int KMFolderMbox::removeContents()
1264 rc = unlink(TQFile::encodeName(location()));
1269 int KMFolderMbox::expungeContents()
1272 if (truncate(TQFile::encodeName(location()), 0))
1279 TQ_INT64 KMFolderMbox::doFolderSize()
const
1281 TQFileInfo info( location() );
1282 return (TQ_INT64)(info.size());
1286 #include "kmfoldermbox.moc"