From kmail-devel Sat Feb 02 02:49:03 2002 From: Waldo Bastian Date: Sat, 02 Feb 2002 02:49:03 +0000 To: kmail-devel Subject: Re: kmail under Solaris and Linux X-MARC-Message: https://marc.info/?l=kmail-devel&m=101261823417448 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--------------Boundary-00=_R5XVX7G4AHBQWXJT86NQ" --------------Boundary-00=_R5XVX7G4AHBQWXJT86NQ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable On Thursday 31 January 2002 11:02 pm, Michael H=E4ckel wrote: > On Thursday 31 January 2002 23:00:23, Waldo Bastian wrote: > > Can't we add a byte-order indicator at the start of the index file? T= hen, > > when the byte order doesn't match we can use a slower compatibility > > function that fixes the byte order. In 99.9% of the cases this will n= ot > > be needed but when it is needed it wil be used automagically and hass= le > > free. > > > > I can make a patch for it if you like the idea. > > This is not only required for the index file but also for the sorted an= d > serial number files. Ok... first attempt. Make sure to backup your Mail folder first! It adds a two word (8 byte) header to the index file which contains a byt= e=20 order indicator and the size of long (4 or 8) used for the index file. If the header is not present we assume that both the byte order and the s= ize=20 of long of the index file matches with that of the host. The QStrings are always written in network order, just as with Qt 2. That= =20 means that if the host order differs from network order, they are swapped= =20 first, before being written. If the host order _is_ network order, they a= re=20 NOT swapped!=20 This means that the patch is supposed to restore compatibility on Sparc w= ith=20 KDE 2 index-files, but it will probably also mean that it breaks=20 compatibility on Sparc with KDE 3 beta1/2 index-files. During testing I=20 noticed that you will get lots of chinese (korean?) in the subjects of yo= ur=20 msg-list in that case. (Do not panic! :-) Selecting the message should re= sult=20 in the proper subject being shown. I have replaced all ints with either Q_UINT32 or Q_INT32, int seems to be= =20 always 4 bytes, even on 64-bit platforms but we better use an explicit 32= -bit=20 type to minimize surprises. I also converted MsgPartType to Q_UINT32. gcc gives sizeof(MsgpartType) =3D= =3D 4 ,=20 but I'm not sure if every compiler does. The long is another story. It will be either 64 bit or 32 bit. If the siz= e of=20 long in the index file doesn't match with the size of long of the host, t= he=20 long is converted. The conversion from 64 bit to 32 bit just drops the 32= =20 most significant bits. 32 bit seems to be enough for most info.... it wil= l be=20 enough for the date till 2038 and it will be enough for the offset as lon= g as=20 the mbox file does not exceed 4Gb. (But if your mbox is 4Gb, you probably= =20 shouldn't be using mbox.) I added a byteOrder field to the sorted index, if the byte order doesn't = match=20 with the host order it throws away the file. (I should recheck if there a= re=20 types used there that can have a variable size across platforms, I don't=20 think so) I added a byteOrder field to the msg id index. If the byteorder doesn't m= atch=20 it swaps the message ids. I also changed the message ids from "unsigned l= ong"=20 to Q_UINT32. That makes that 64-bit platforms will now use a 32-bit messa= ge=20 id as well. I don't think 64 bits are needed here since I don't think any= one=20 is going to receive so many messages that he needs more than 32 bits for=20 that. Patch attached. It works fine for me, but I haven't tested it cross-platform yet. If you = test=20 it make sure to backup your Mail directory first. Cheers, Waldo --=20 bastian@kde.org | SuSE Labs KDE Developer | bastian@suse.com --------------Boundary-00=_R5XVX7G4AHBQWXJT86NQ Content-Type: text/x-diff; charset="iso-8859-1"; name="kmail.portable.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kmail.portable.patch" Index: kmfolder.cpp =================================================================== RCS file: /home/kde/kdenetwork/kmail/kmfolder.cpp,v retrieving revision 1.215 diff -u -r1.215 kmfolder.cpp --- kmfolder.cpp 2002/01/20 22:20:08 1.215 +++ kmfolder.cpp 2002/02/02 02:05:24 @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -31,6 +32,22 @@ #include #endif +#if HAVE_BYTESWAP_H +#include +#endif + +// We define functions as kmail_swap_NN so that we don't get compile errors +// on platforms where bswap_NN happens to be a function instead of a define. + +/* Swap bytes in 32 bit value. */ +#ifdef bswap_32 +#define kmail_swap_32(x) bswap_32(x) +#else +#define kmail_swap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif + //#define HAVE_MMAP //need to get this into autoconf FIXME --Sam #ifdef HAVE_MMAP #include @@ -83,6 +100,8 @@ mIndexId = -1; mIndexStreamPtr = NULL; mIndexStreamPtrLength = 0; + mIndexSwapByteOrder = false; + mIndexSizeOfLong = sizeof(long); mCompactable = TRUE; mNoContent = FALSE; expireMessages = FALSE; @@ -220,11 +239,20 @@ return errno; fprintf(tmpIndexStream, "# KMail-Index V%d\n", INDEX_VERSION); + + // Header + Q_UINT32 byteOrder = 0x12345678; + Q_UINT32 sizeOfLong = sizeof(long); + + Q_UINT32 header_length = sizeof(byteOrder)+sizeof(sizeOfLong); char pad_char = '\0'; - int header_length = 0; // Reserved for future expansion fwrite(&pad_char, sizeof(pad_char), 1, tmpIndexStream); fwrite(&header_length, sizeof(header_length), 1, tmpIndexStream); + // Write header + fwrite(&byteOrder, sizeof(byteOrder), 1, tmpIndexStream); + fwrite(&sizeOfLong, sizeof(sizeOfLong), 1, tmpIndexStream); + long nho = ftell(tmpIndexStream); for (i=0; i 0xFFFF) + header_length = kmail_swap_32(header_length); + + long endOfHeader = ftell(mIndexStream) + header_length; +qWarning("header_lenght = %d", header_length); + + // Process available header parts + if (header_length >= sizeof(byteOrder)) + { + fread(&byteOrder, sizeof(byteOrder), 1, mIndexStream); + mIndexSwapByteOrder = (byteOrder == 0x78563412); + header_length -= sizeof(byteOrder); + + if (header_length >= sizeof(sizeOfLong)) + { + fread(&sizeOfLong, sizeof(sizeOfLong), 1, mIndexStream); + mIndexSizeOfLong = sizeOfLong; + header_length -= sizeof(sizeOfLong); + } + } + + // Seek to end of header + fseek(mIndexStream, endOfHeader, SEEK_SET ); + + if (mIndexSwapByteOrder) + kdDebug(5006) << "Index File has byte order swapped!" << endl; + if (mIndexSizeOfLong != sizeof(long)) + kdDebug(5006) << "Index File sizeOfLong is " << mIndexSizeOfLong << " while sizeof(long) is " << sizeof(long) << " !" << endl; + } return TRUE; } @@ -311,7 +372,8 @@ //----------------------------------------------------------------------------- bool KMFolder::readIndex() { - int len, offs; + Q_INT32 len; + int offs; KMMsgInfo* mi; assert(mIndexStream != NULL); @@ -331,10 +393,13 @@ mi = NULL; if(version >= 1505) { if(!fread(&len, sizeof(len), 1, mIndexStream)) - break; + break; + if (mIndexSwapByteOrder) + len = kmail_swap_32(len); + offs = ftell(mIndexStream); if(fseek(mIndexStream, len, SEEK_CUR)) - break; + break; mi = new KMMsgInfo(this, offs, len); } else { QCString line(MAX_LINE); Index: kmfolder.h =================================================================== RCS file: /home/kde/kdenetwork/kmail/kmfolder.h,v retrieving revision 1.79 diff -u -r1.79 kmfolder.h --- kmfolder.h 2002/01/05 19:57:21 1.79 +++ kmfolder.h 2002/02/02 02:05:26 @@ -306,7 +306,10 @@ /** Returns a string that can be used to identify this folder */ virtual QString idString(); - uchar *indexStreamBasePtr() { return mIndexStreamPtr; } + uchar *indexStreamBasePtr() { return mIndexStreamPtr; } + + bool indexSwapByteOrder() { return mIndexSwapByteOrder; } + int indexSizeOfLong() { return mIndexSizeOfLong; } /** * Set whether this folder automatically expires messages. @@ -539,6 +542,8 @@ bool mConvertToUtf8; uchar *mIndexStreamPtr; int mIndexStreamPtrLength, mIndexId; + bool mIndexSwapByteOrder; // Index file was written with swapped byte order + int mIndexSizeOfLong; // Index file was written with longs of this size /** Support for automatic expiry of old messages */ bool expireMessages; // TRUE if old messages are expired @@ -551,7 +556,6 @@ /** Points at the reverse dictionary for this folder. */ KMMsgDictREntry *mRDict; - }; #endif /*kmfolder_h*/ Index: kmheaders.cpp =================================================================== RCS file: /home/kde/kdenetwork/kmail/kmheaders.cpp,v retrieving revision 1.389 diff -u -r1.389 kmheaders.cpp --- kmheaders.cpp 2002/01/27 10:24:28 1.389 +++ kmheaders.cpp 2002/02/02 02:05:33 @@ -2726,7 +2726,7 @@ } //Flatten the list and write it to disk -#define KMAIL_SORT_VERSION 1006 +#define KMAIL_SORT_VERSION 1007 #define KMAIL_SORT_FILE(x) x->indexLocation() + ".sorted" #define KMAIL_SORT_HEADER "## KMail Sort V%04d\n\t" #define KMAIL_MAGIC_HEADER_OFFSET 21 //strlen(KMAIL_SORT_HEADER) @@ -2736,14 +2736,14 @@ { fwrite(&msgid, sizeof(msgid), 1, sortStream); fwrite(&parent_id, sizeof(parent_id), 1, sortStream); - int len = key.length() * 2; + Q_INT32 len = key.length() * sizeof(QChar); fwrite(&len, sizeof(len), 1, sortStream); if (len) fwrite(key.unicode(), QMIN(len, KMAIL_MAX_KEY_LEN), 1, sortStream); if (update_discover) { //update the discovered change count - int discovered_count = 0; + Q_INT32 discovered_count = 0; fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET); fread(&discovered_count, sizeof(discovered_count), 1, sortStream); discovered_count++; @@ -2773,9 +2773,14 @@ mSortInfo.dirty = FALSE; fprintf(sortStream, KMAIL_SORT_HEADER, KMAIL_SORT_VERSION); //magic header information - int column = mSortCol, ascending=!mSortDescending; - int threaded = (mNested != mNestedOverride); - int discovered_count = 0, sorted_count=0, appended=0; + Q_INT32 byteOrder = 0x12345678; + Q_INT32 column = mSortCol; + Q_INT32 ascending= !mSortDescending; + Q_INT32 threaded = (mNested != mNestedOverride); + Q_INT32 appended=0; + Q_INT32 discovered_count = 0; + Q_INT32 sorted_count=0; + fwrite(&byteOrder, sizeof(byteOrder), 1, sortStream); fwrite(&column, sizeof(column), 1, sortStream); fwrite(&ascending, sizeof(ascending), 1, sortStream); fwrite(&threaded, sizeof(threaded), 1, sortStream); @@ -2832,6 +2837,7 @@ //magic header twice, case they've changed fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET, SEEK_SET); + fwrite(&byteOrder, sizeof(byteOrder), 1, sortStream); fwrite(&column, sizeof(column), 1, sortStream); fwrite(&ascending, sizeof(ascending), 1, sortStream); fwrite(&threaded, sizeof(threaded), 1, sortStream); @@ -2867,8 +2873,8 @@ khi->key(mSortCol, !mSortDescending)); //update the appended flag - int appended = 1; - fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 12, SEEK_SET); + Q_INT32 appended = 1; + fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET); fwrite(&appended, sizeof(appended), 1, sortStream); if (sortStream && ferror(sortStream)) { @@ -2980,7 +2986,7 @@ bool KMHeaders::readSortOrder(bool set_selection) { //all cases - int column, ascending, threaded, discovered_count, sorted_count, appended; + Q_INT32 column, ascending, threaded, discovered_count, sorted_count, appended; bool unread_exists = false; QMemArray sortCache(mFolder->count()); KMSortCacheItem root; @@ -3012,6 +3018,10 @@ int version; fscanf(sortStream, KMAIL_SORT_HEADER, &version); if(version == KMAIL_SORT_VERSION) { + Q_INT32 byteOrder = 0; + fread(&byteOrder, sizeof(byteOrder), 1, sortStream); + if (byteOrder == 0x12345678) + { fread(&column, sizeof(column), 1, sortStream); fread(&ascending, sizeof(ascending), 1, sortStream); fread(&threaded, sizeof(threaded), 1, sortStream); @@ -3121,6 +3131,11 @@ fclose(sortStream); sortStream = NULL; } + } + else { + fclose(sortStream); + sortStream = NULL; + } } else { fclose(sortStream); sortStream = NULL; @@ -3245,7 +3260,7 @@ } else { //update the appended flag appended = 0; - fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 12, SEEK_SET); + fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET); fwrite(&appended, sizeof(appended), 1, sortStream); } } Index: kmmsgbase.cpp =================================================================== RCS file: /home/kde/kdenetwork/kmail/kmmsgbase.cpp,v retrieving revision 1.104 diff -u -r1.104 kmmsgbase.cpp --- kmmsgbase.cpp 2002/01/16 12:43:35 1.104 +++ kmmsgbase.cpp 2002/02/02 02:05:35 @@ -16,7 +16,47 @@ #include #include +#include +#if HAVE_BYTESWAP_H +#include +#endif + +// We define functions as kmail_swap_NN so that we don't get compile errors +// on platforms where bswap_NN happens to be a function instead of a define. + +/* Swap bytes in 16 bit value. */ +#ifdef bswap_16 +#define kmail_swap_16(x) bswap_16(x) +#else +#define kmail_swap_16(x) \ + ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) +#endif + +/* Swap bytes in 32 bit value. */ +#ifdef bswap_32 +#define kmail_swap_32(x) bswap_32(x) +#else +#define kmail_swap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif + +/* Swap bytes in 64 bit value. */ +#ifdef bswap_64 +#define kmail_swap_64(x) bswap_64(x) +#else +#define kmail_swap_64(x) \ + ((((x) & 0xff00000000000000ull) >> 56) \ + | (((x) & 0x00ff000000000000ull) >> 40) \ + | (((x) & 0x0000ff0000000000ull) >> 24) \ + | (((x) & 0x000000ff00000000ull) >> 8) \ + | (((x) & 0x00000000ff000000ull) << 8) \ + | (((x) & 0x0000000000ff0000ull) << 24) \ + | (((x) & 0x000000000000ff00ull) << 40) \ + | (((x) & 0x00000000000000ffull) << 56)) +#endif + static KMMsgStatus sStatusList[] = { KMMsgStatusDeleted, KMMsgStatusNew, @@ -681,7 +721,7 @@ for (uint i = 0; i < len; i++) { us = str[i].unicode(); - str[i] = QChar(((us & 0xFF) << 8) + ((us & 0xFF00) >> 8)); + str[i] = QChar(kmail_swap_16(us)); } } @@ -698,8 +738,8 @@ memcpy(x, g_chunk+g_chunk_offset, length); \ g_chunk_offset += length; \ } } while(0) -#define COPY_HEADER_TYPE(x) Q_ASSERT(sizeof(x) == sizeof(MsgPartType)); COPY_DATA(&x, sizeof(x)) -#define COPY_HEADER_LEN(x) Q_ASSERT(sizeof(x) == sizeof(short)); COPY_DATA(&x, sizeof(x)); +#define COPY_HEADER_TYPE(x) Q_ASSERT(sizeof(x) == sizeof(Q_UINT32)); COPY_DATA(&x, sizeof(x)); +#define COPY_HEADER_LEN(x) Q_ASSERT(sizeof(x) == sizeof(Q_UINT16)); COPY_DATA(&x, sizeof(x)); //----------------------------------------------------------------------------- QString KMMsgBase::getStringPart(MsgPartType t) const { @@ -707,6 +747,7 @@ g_chunk_offset = 0; bool using_mmap = FALSE; + bool swapByteOrder = mParent->indexSwapByteOrder(); if (mParent->indexStreamBasePtr()) { if (g_chunk) free(g_chunk); @@ -725,15 +766,21 @@ } MsgPartType type; - short l; + Q_UINT16 l; while(g_chunk_offset < mIndexLength) { - COPY_HEADER_TYPE(type); + Q_UINT32 tmp; + COPY_HEADER_TYPE(tmp); + type = (MsgPartType) tmp; COPY_HEADER_LEN(l); + if (swapByteOrder) + l = kmail_swap_16(l); if(g_chunk_offset + l > mIndexLength) { kdDebug(5006) << "This should never happen.. " << __FILE__ << ":" << __LINE__ << endl; break; } if(type == t) { + // This works because the QString constructor does a memcpy. + // Otherwise we would need to be concerned about the alignment. if(l) ret = QString((QChar *)(g_chunk + g_chunk_offset), l/2); break; @@ -744,7 +791,25 @@ g_chunk_length = 0; g_chunk = NULL; } - swapEndian(ret); + // Normally we need to swap the byte order because the QStrings are written + // in the style of Qt2 (MSB -> network ordered). + // QStrings in Qt3 expect host ordering. + // On e.g. Intel host ordering is LSB, on e.g. Sparc it is MSB. +#ifndef BYTE_ORDER + assert(false); // Uh oh. +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN +#warning Byte order is little endian (swap is true) + bool swap_endian = true; +#else +#warning Byte order is big endian (swap is false) + bool swap_endian = false; +#endif + swap_endian = swap_endian ^ swapByteOrder; // index-file has non-native byte order. + + if (swap_endian) + swapEndian(ret); return ret; } @@ -755,6 +820,8 @@ g_chunk_offset = 0; bool using_mmap = FALSE; + int sizeOfLong = mParent->indexSizeOfLong(); + bool swapByteOrder = mParent->indexSwapByteOrder(); if (mParent->indexStreamBasePtr()) { if (g_chunk) free(g_chunk); @@ -774,18 +841,74 @@ } MsgPartType type; - short l; + Q_UINT16 l; while (g_chunk_offset < mIndexLength) { - COPY_HEADER_TYPE(type); + Q_UINT32 tmp; + COPY_HEADER_TYPE(tmp); + type = (MsgPartType) tmp; COPY_HEADER_LEN(l); + if (swapByteOrder) + l = kmail_swap_16(l); if (g_chunk_offset + l > mIndexLength) { kdDebug(5006) << "This should never happen.. " << __FILE__ << ":" << __LINE__ << endl; break; } if(type == t) { - Q_ASSERT(l == sizeof(unsigned long)); - COPY_DATA(&ret, sizeof(ret)); + assert(sizeOfLong == l); + if (sizeOfLong == sizeof(ret)) + { + COPY_DATA(&ret, sizeof(ret)); + if (swapByteOrder) + { + if (sizeof(ret) == 4) + ret = kmail_swap_32(ret); + else + ret = kmail_swap_64(ret); + } + } + else if (sizeOfLong == 4) + { + // Long is stored as 4 bytes in index file, sizeof(long) = 8 + Q_UINT32 ret_32; + COPY_DATA(&ret_32, sizeof(ret_32)); + if (swapByteOrder) + ret_32 = kmail_swap_32(ret_32); + ret = ret_32; + } + else if (sizeOfLong == 8) + { + // Long is stored as 8 bytes in index file, sizeof(long) = 4 + Q_UINT32 ret_1; + Q_UINT32 ret_2; + COPY_DATA(&ret_1, sizeof(ret_1)); + COPY_DATA(&ret_2, sizeof(ret_2)); + if (!swapByteOrder) + { + // Index file order is the same as the order of this CPU. +#if BYTE_ORDER == LITTLE_ENDIAN + // Index file order is little endian + ret = ret_1; // We drop the 4 most significant bytes +#else + // Index file order is big endian + ret = ret_2; // We drop the 4 most significant bytes +#endif + } + else + { + // Index file order is different from this CPU. +#if BYTE_ORDER == LITTLE_ENDIAN + // Index file order is big endian + ret = ret_2; // We drop the 4 most significant bytes +#else + // Index file order is little endian + ret = ret_1; // We drop the 4 most significant bytes +#endif + // We swap the result to host order. + ret = kmail_swap_32(ret); + } + + } break; } g_chunk_offset += l; @@ -817,34 +940,41 @@ length += len2 + sizeof(short) + sizeof(MsgPartType); \ } while(0) #define STORE_DATA(type, x) STORE_DATA_LEN(type, &x, sizeof(x)) +#if BYTE_ORDER == LITTLE_ENDIAN +#warning Byte order is little endian (call swapEndian) +#define SWAP_TO_NETWORK_ORDER(x) swapEndian(x) +#else +#warning Byte order is big endian +#define SWAP_TO_NETWORK_ORDER(x) +#endif unsigned long tmp; QString tmp_str; //these is at the beginning because it is queried quite often tmp_str = msgIdMD5().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgIdMD5Part, tmp_str.unicode(), tmp_str.length() * 2); tmp = status(); STORE_DATA(MsgStatusPart, tmp); //these are completely arbitrary order tmp_str = fromStrip().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgFromPart, tmp_str.unicode(), tmp_str.length() * 2); tmp_str = subject().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgSubjectPart, tmp_str.unicode(), tmp_str.length() * 2); tmp_str = toStrip().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgToPart, tmp_str.unicode(), tmp_str.length() * 2); tmp_str = replyToIdMD5().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgReplyToIdMD5Part, tmp_str.unicode(), tmp_str.length() * 2); tmp_str = xmark().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgXMarkPart, tmp_str.unicode(), tmp_str.length() * 2); tmp_str = fileName().stripWhiteSpace(); - swapEndian(tmp_str); + SWAP_TO_NETWORK_ORDER(tmp_str); STORE_DATA_LEN(MsgFilePart, tmp_str.unicode(), tmp_str.length() * 2); tmp = msgSize(); STORE_DATA(MsgSizePart, tmp); Index: kmmsgdict.cpp =================================================================== RCS file: /home/kde/kdenetwork/kmail/kmmsgdict.cpp,v retrieving revision 1.10 diff -u -r1.10 kmmsgdict.cpp --- kmmsgdict.cpp 2002/01/04 11:06:28 1.10 +++ kmmsgdict.cpp 2002/02/02 02:05:36 @@ -15,10 +15,29 @@ #include +#include + +#if HAVE_BYTESWAP_H +#include +#endif + +// We define functions as kmail_swap_NN so that we don't get compile errors +// on platforms where bswap_NN happens to be a function instead of a define. + +/* Swap bytes in 32 bit value. */ +#ifdef bswap_32 +#define kmail_swap_32(x) bswap_32(x) +#else +#define kmail_swap_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#endif + + //----------------------------------------------------------------------------- // Current version of the .index.ids files -#define IDS_VERSION 1001 +#define IDS_VERSION 1002 // The asterisk at the end is important #define IDS_HEADER "# KMail-Index-IDs V%d\n*" @@ -283,17 +302,27 @@ fclose(fp); return -1; } + + bool swapByteOrder; + Q_UINT32 byte_order; + if (!fread(&byte_order, sizeof(byte_order), 1, fp)) { + fclose(fp); + return -1; + } + swapByteOrder = (byte_order == 0x78563412); - int count; + Q_UINT32 count; if (!fread(&count, sizeof(count), 1, fp)) { fclose(fp); return -1; } + if (swapByteOrder) + count = kmail_swap_32(count); KMMsgDictREntry *rentry = new KMMsgDictREntry(count); for (int index = 0; index < count; index++) { - unsigned long msn; + Q_UINT32 msn; if (!fread(&msn, sizeof(msn), 1, fp)) { for (int i = 0; i < index; i++) { @@ -304,6 +333,8 @@ fclose(fp); return -1; } + if (swapByteOrder) + msn = kmail_swap_32(msn); //if (!msn) //kdDebug(5006) << "Dict found zero serial number in folder " << folder->label() << endl; @@ -366,8 +397,14 @@ FILE *fp = rentry->fp; // kdDebug(5006) << "Dict writing for folder " << folder->label() << endl; + Q_UINT32 byteOrder = 0x12345678; + if (!fwrite(&byteOrder, sizeof(byteOrder), 1, fp)) { + kdDebug(5006) << "Dict cannot write byteOrder with folder " << folder->label() << ": " + << strerror(errno) << " (" << errno << ")" << endl; + return -1; + } - int count = rentry->getRealSize(); + Q_UINT32 count = rentry->getRealSize(); if (!fwrite(&count, sizeof(count), 1, fp)) { kdDebug(5006) << "Dict cannot write count with folder " << folder->label() << ": " << strerror(errno) << " (" << errno << ")" << endl; @@ -375,7 +412,7 @@ } for (int index = 0; index < count; index++) { - unsigned long msn = rentry->getMsn(index); + Q_UINT32 msn = rentry->getMsn(index); if (!fwrite(&msn, sizeof(msn), 1, fp)) return -1; } --------------Boundary-00=_R5XVX7G4AHBQWXJT86NQ-- _______________________________________________ kmail Developers mailing list kmail@mail.kde.org http://mail.kde.org/mailman/listinfo/kmail