kmail
kmfolderindex_common.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kmfolderindex.h"
00020 #include "kmfolder.h"
00021 #include "messageproperty.h"
00022 #include <config-kmail.h>
00023
00024 #include <kdebug.h>
00025 #include <kde_file.h>
00026
00027 #include <QFileInfo>
00028 #include <QDir>
00029 #include <QTimer>
00030 #include <QByteArray>
00031 #include <QDateTime>
00032
00033 #include <unistd.h>
00034
00035
00036 #define INDEX_VERSION 1506
00037
00038 #ifndef MAX_LINE
00039 #define MAX_LINE 4096
00040 #endif
00041
00042 #ifndef INIT_MSGS
00043 #define INIT_MSGS 8
00044 #endif
00045
00046 #include <errno.h>
00047 #include <assert.h>
00048 #include <utime.h>
00049 #include <fcntl.h>
00050
00051 #ifdef HAVE_BYTESWAP_H
00052 #include <byteswap.h>
00053 #endif
00054 #include <QCursor>
00055 #include <kmessagebox.h>
00056 #include <klocale.h>
00057 #include "kmmsgdict.h"
00058 #include "kcursorsaver.h"
00059
00060
00061
00062
00063
00064 #ifdef bswap_32
00065 #define kmail_swap_32(x) bswap_32(x)
00066 #else
00067 #define kmail_swap_32(x) \
00068 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
00069 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
00070 #endif
00071
00072 #include <stdlib.h>
00073 #include <sys/types.h>
00074 #include <sys/stat.h>
00075 #include <sys/file.h>
00076
00077 int KMFolderIndex::openInternal( OpenInternalOptions options )
00078 {
00079 int rc = 0;
00080 if ( folder()->path().isEmpty() )
00081 {
00082 mAutoCreateIndex = false;
00083 rc = createIndexFromContents();
00084 }
00085 else {
00086 bool shouldCreateIndexFromContents = false;
00087 KMFolderIndex::IndexStatus index_status = indexStatus();
00088 if ( KMFolderIndex::IndexOk != index_status )
00089 {
00090 if ( ( options & CheckIfIndexTooOld ) && KMFolderIndex::IndexTooOld == index_status ) {
00091 QString msg = i18n("<qt><p>The index of folder '%2' seems "
00092 "to be out of date. To prevent message "
00093 "corruption the index will be "
00094 "regenerated. As a result deleted "
00095 "messages might reappear and status "
00096 "flags might be lost.</p>"
00097 "<p>Please read the corresponding entry "
00098 "in the <a href=\"%1\">FAQ section of the manual "
00099 "of KMail</a> for "
00100 "information about how to prevent this "
00101 "problem from happening again.</p></qt>",
00102 QString("help:/kmail/faq.html#faq-index-regeneration"),
00103 objectName());
00104
00105
00106
00107
00108 if ( kmkernel->startingUp() ) {
00109 KConfigGroup configGroup( KMKernel::config(),
00110 "Notification Messages" );
00111 bool showMessage =
00112 configGroup.readEntry( "showIndexRegenerationMessage", true );
00113 if ( showMessage ) {
00114 KMessageBox::queuedMessageBox( 0, KMessageBox::Information,
00115 msg, i18n("Index Out of Date"),
00116 KMessageBox::AllowLink );
00117 }
00118 } else {
00119 KCursorSaver idle( KBusyPtr::idle() );
00120 KMessageBox::information( 0, msg, i18n("Index Out of Date"),
00121 "showIndexRegenerationMessage",
00122 KMessageBox::AllowLink );
00123 }
00124 }
00125 #ifdef KMAIL_SQLITE_INDEX
00126 #else
00127 mIndexStream = 0;
00128 #endif
00129 shouldCreateIndexFromContents = true;
00130 emit statusMsg( i18n("Folder `%1' changed; recreating index.", objectName()) );
00131 } else {
00132 #ifdef KMAIL_SQLITE_INDEX
00133 if ( !openDatabase( SQLITE_OPEN_READWRITE ) )
00134 shouldCreateIndexFromContents = true;
00135 #else
00136 mIndexStream = KDE_fopen(QFile::encodeName(indexLocation()), "r+");
00137 kDebug( StorageDebug ) << "KDE_fopen(indexLocation()=" << indexLocation() << ", \"r+\") == mIndexStream == " << mIndexStream;
00138 if ( mIndexStream ) {
00139 # ifndef Q_WS_WIN
00140 fcntl(fileno(mIndexStream), F_SETFD, FD_CLOEXEC);
00141 # endif
00142 if (!updateIndexStreamPtr())
00143 return 1;
00144 }
00145 else
00146 shouldCreateIndexFromContents = true;
00147 #endif
00148 }
00149
00150 if ( shouldCreateIndexFromContents )
00151 rc = createIndexFromContents();
00152 else {
00153 rc = readIndex() ? 0 : 1;
00154 if ( rc != 0 && ( options & CreateIndexFromContentsWhenReadIndexFailed ) )
00155 rc = createIndexFromContents();
00156 }
00157 }
00158
00159 mChanged = false;
00160 return rc;
00161 }
00162
00163 int KMFolderIndex::createInternal()
00164 {
00165 if ( folder()->path().isEmpty() ) {
00166 mAutoCreateIndex = false;
00167 }
00168 else {
00169
00170
00171
00172
00173
00174
00175 #ifdef KMAIL_SQLITE_INDEX
00176
00177 #else
00178 int old_umask = umask( 077 );
00179 mIndexStream = KDE_fopen( QFile::encodeName(indexLocation() ), "w+" );
00180 const bool updateIndexStreamPtrResult = updateIndexStreamPtr( true );
00181 umask( old_umask );
00182 if ( !updateIndexStreamPtrResult )
00183 return 1;
00184
00185 if ( !mIndexStream )
00186 return errno;
00187 # ifndef Q_WS_WIN
00188 fcntl( fileno( mIndexStream ), F_SETFD, FD_CLOEXEC );
00189 # endif
00190 #endif
00191 }
00192
00193 mOpenCount++;
00194 mChanged = false;
00195
00196 return writeIndex();
00197 }
00198
00199 void KMFolderIndex::addToSerialCache() const
00200 {
00201 Q_ASSERT( mOpenCount > 0 );
00202
00203 KMFolder *fld = folder();
00204 const KMMsgDict *dict = KMMsgDict::instance();
00205 unsigned int index = 0;
00206 Q_ASSERT( fld );
00207
00208 if ( fld ) {
00209 QVector<KMMsgBase*>::ConstIterator it = mMsgList.constBegin();
00210 while ( it != mMsgList.constEnd() ) {
00211 const KMMsgBase *msg = *it;
00212 if ( msg ) {
00213 unsigned long msn = dict->getMsgSerNum( fld, index );
00214 if ( msn )
00215 KMail::MessageProperty::setSerialCache( msg, msn );
00216 }
00217 ++it;
00218 ++index;
00219 }
00220 }
00221 }