changeset 104:a6d7ed739926 HEAD

added index->lookup_field_raw() and update_field_raw(), changed mbox to save the offsets in raw uoff_t instead of hex encoded.
author Timo Sirainen <tss@iki.fi>
date Sat, 31 Aug 2002 23:12:59 +0300
parents 08186ac2784e
children 31034993473c
files src/lib-index/mail-index-data.c src/lib-index/mail-index-update.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-index.c src/lib-index/mbox/mbox-append.c src/lib-index/mbox/mbox-index.c src/lib-index/mbox/mbox-open.c src/lib-index/mbox/mbox-sync.c
diffstat 9 files changed, 84 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index-data.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mail-index-data.c	Sat Aug 31 23:12:59 2002 +0300
@@ -381,6 +381,8 @@
 	int i;
 
 	if (rec->full_field_size > INT_MAX) {
+		/* we already check that the full_field_size is within file,
+		   so this can happen only if the file really is huge.. */
 		INDEX_MARK_CORRUPTED(data->index);
 		index_set_error(data->index, "Error in data file %s: "
 				"full_field_size > INT_MAX", data->filepath);
--- a/src/lib-index/mail-index-update.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mail-index-update.c	Sat Aug 31 23:12:59 2002 +0300
@@ -20,7 +20,7 @@
 	MailIndexRecord *rec;
 
 	unsigned int updated_fields;
-	char *fields[FIELD_TYPE_MAX_BITS];
+	void *fields[FIELD_TYPE_MAX_BITS];
 	unsigned int field_sizes[FIELD_TYPE_MAX_BITS];
 	unsigned int field_extra_sizes[FIELD_TYPE_MAX_BITS];
 };
@@ -254,17 +254,15 @@
 	return !failed;
 }
 
-void mail_index_update_field(MailIndexUpdate *update, MailField field,
-			     const char *value, unsigned int extra_space)
+static void update_field_full(MailIndexUpdate *update, MailField field,
+			      const void *value, unsigned int size,
+			      unsigned int extra_space)
 {
-	unsigned int size;
 	int index;
 
 	index = mail_field_get_index(field);
 	i_assert(index >= 0);
 
-	size = strlen(value)+1;
-
 	update->updated_fields |= field;
 	update->field_sizes[index] = size;
 	update->field_extra_sizes[index] = extra_space;
@@ -272,6 +270,18 @@
 	memcpy(update->fields[index], value, size);
 }
 
+void mail_index_update_field(MailIndexUpdate *update, MailField field,
+			     const char *value, unsigned int extra_space)
+{
+	update_field_full(update, field, value, strlen(value)+1, extra_space);
+}
+
+void mail_index_update_field_raw(MailIndexUpdate *update, MailField field,
+				 const void *value, unsigned int size)
+{
+	update_field_full(update, field, value, size, 0);
+}
+
 static MailField mail_header_get_field(const char *str, unsigned int len)
 {
 	if (len == 7 && strncasecmp(str, "Subject", 7) == 0)
--- a/src/lib-index/mail-index.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mail-index.c	Sat Aug 31 23:12:59 2002 +0300
@@ -997,8 +997,8 @@
 	return NULL;
 }
 
-const char *mail_index_lookup_field(MailIndex *index, MailIndexRecord *rec,
-				    MailField field)
+static MailIndexDataRecord *
+index_lookup_data_field(MailIndex *index, MailIndexRecord *rec, MailField field)
 {
 	MailIndexDataRecord *datarec;
 
@@ -1031,6 +1031,18 @@
 		return NULL;
 	}
 
+	return datarec;
+}
+
+const char *mail_index_lookup_field(MailIndex *index, MailIndexRecord *rec,
+				    MailField field)
+{
+	MailIndexDataRecord *datarec;
+
+	datarec = index_lookup_data_field(index, rec, field);
+	if (datarec == NULL)
+		return NULL;
+
 	if (!mail_index_data_record_verify(index->data, datarec)) {
 		/* index is corrupted, it will be rebuilt */
 		return NULL;
@@ -1039,6 +1051,21 @@
 	return datarec->data;
 }
 
+const void *mail_index_lookup_field_raw(MailIndex *index, MailIndexRecord *rec,
+					MailField field, unsigned int *size)
+{
+	MailIndexDataRecord *datarec;
+
+	datarec = index_lookup_data_field(index, rec, field);
+	if (datarec == NULL) {
+		*size = 0;
+		return NULL;
+	}
+
+	*size = datarec->full_field_size;
+	return datarec->data;
+}
+
 unsigned int mail_index_get_sequence(MailIndex *index, MailIndexRecord *rec)
 {
 	MailIndexRecord *seekrec;
--- a/src/lib-index/mail-index.h	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mail-index.h	Sat Aug 31 23:12:59 2002 +0300
@@ -200,10 +200,15 @@
 					     unsigned int first_uid,
 					     unsigned int last_uid);
 
-	/* Find field from specified record, or NULL if it's not in index. */
+	/* Find field from specified record, or NULL if it's not in index.
+	   Makes sure that the field ends with \0. */
 	const char *(*lookup_field)(MailIndex *index, MailIndexRecord *rec,
 				    MailField field);
 
+	/* Find field from specified record, or NULL if it's not in index. */
+	const void *(*lookup_field_raw)(MailIndex *index, MailIndexRecord *rec,
+					MailField field, unsigned int *size);
+
 	/* Returns sequence for given message, or 0 if failed. */
 	unsigned int (*get_sequence)(MailIndex *index, MailIndexRecord *rec);
 
@@ -256,6 +261,8 @@
 
 	void (*update_field)(MailIndexUpdate *update, MailField field,
 			     const char *value, unsigned int extra_space);
+	void (*update_field_raw)(MailIndexUpdate *update, MailField field,
+				 const void *value, unsigned int size);
 
 	/* Returns last error message */
 	const char *(*get_last_error)(MailIndex *index);
@@ -328,6 +335,8 @@
 					     unsigned int last_uid);
 const char *mail_index_lookup_field(MailIndex *index, MailIndexRecord *rec,
 				    MailField field);
+const void *mail_index_lookup_field_raw(MailIndex *index, MailIndexRecord *rec,
+					MailField field, unsigned int *size);
 unsigned int mail_index_get_sequence(MailIndex *index, MailIndexRecord *rec);
 int mail_index_expunge(MailIndex *index, MailIndexRecord *rec,
 		       unsigned int seq, int external_change);
@@ -340,6 +349,8 @@
 int mail_index_update_end(MailIndexUpdate *update);
 void mail_index_update_field(MailIndexUpdate *update, MailField field,
 			     const char *value, unsigned int extra_space);
+void mail_index_update_field_raw(MailIndexUpdate *update, MailField field,
+				 const void *value, unsigned int size);
 const char *mail_index_get_last_error(MailIndex *index);
 int mail_index_is_inconsistency_error(MailIndex *index);
 
--- a/src/lib-index/maildir/maildir-index.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/maildir/maildir-index.c	Sat Aug 31 23:12:59 2002 +0300
@@ -212,6 +212,7 @@
 	mail_index_next,
         mail_index_lookup_uid_range,
 	mail_index_lookup_field,
+	mail_index_lookup_field_raw,
 	mail_index_get_sequence,
 	maildir_open_mail,
 	mail_index_expunge,
@@ -220,6 +221,7 @@
 	mail_index_update_begin,
 	mail_index_update_end,
 	mail_index_update_field,
+	mail_index_update_field_raw,
 	mail_index_get_last_error,
 	mail_index_is_inconsistency_error,
 
--- a/src/lib-index/mbox/mbox-append.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mbox/mbox-append.c	Sat Aug 31 23:12:59 2002 +0300
@@ -99,7 +99,6 @@
 	uoff_t abs_start_offset, stop_offset, old_size;
 	unsigned char *data, md5_digest[16];
 	unsigned int size, pos, virtual_size;
-	const char *location;
 
 	/* get the From-line */
 	pos = 0;
@@ -142,10 +141,9 @@
 
 	update = index->update_begin(index, rec);
 
-	/* location = offset to beginning of message */
-	location = binary_to_hex((unsigned char *) &abs_start_offset,
-				 sizeof(abs_start_offset));
-	index->update_field(update, FIELD_TYPE_LOCATION, location, 0);
+	/* location = offset to beginning of headers in message */
+	index->update_field_raw(update, FIELD_TYPE_LOCATION,
+				&abs_start_offset, sizeof(uoff_t));
 
 	/* parse the header and cache wanted fields. get the message flags
 	   from Status and X-Status fields. temporarily limit the buffer size
--- a/src/lib-index/mbox/mbox-index.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mbox/mbox-index.c	Sat Aug 31 23:12:59 2002 +0300
@@ -182,6 +182,7 @@
 	mail_index_next,
         mail_index_lookup_uid_range,
 	mail_index_lookup_field,
+	mail_index_lookup_field_raw,
 	mail_index_get_sequence,
 	mbox_open_mail,
 	mail_index_expunge,
@@ -190,6 +191,7 @@
 	mail_index_update_begin,
 	mail_index_update_end,
 	mail_index_update_field,
+	mail_index_update_field_raw,
 	mail_index_get_last_error,
 	mail_index_is_inconsistency_error,
 
--- a/src/lib-index/mbox/mbox-open.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mbox/mbox-open.c	Sat Aug 31 23:12:59 2002 +0300
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "iobuffer.h"
-#include "hex-binary.h"
 #include "mbox-index.h"
 #include "mail-index-util.h"
 
@@ -12,15 +11,17 @@
 
 IOBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec)
 {
-	const char *location;
+	const uoff_t *location;
 	uoff_t offset, stop_offset;
 	off_t pos;
+	unsigned int size;
 	char buf[7], *p;
 	int fd, ret, failed;
 
 	i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
 
-	location = index->lookup_field(index, rec, FIELD_TYPE_LOCATION);
+	location = index->lookup_field_raw(index, rec, FIELD_TYPE_LOCATION,
+					   &size);
 	if (location == NULL) {
                 INDEX_MARK_CORRUPTED(index);
 		index_set_error(index, "Corrupted index file %s: "
@@ -29,17 +30,16 @@
 		return NULL;
 	}
 
-	/* location = offset in hex */
-	if (strlen(location) != sizeof(offset)*2 ||
-	    hex_to_binary(location, (unsigned char *) &offset) <= 0 ||
-	    offset > OFF_T_MAX) {
-                INDEX_MARK_CORRUPTED(index);
+	/* location = offset to beginning of headers in message */
+	if (size != sizeof(uoff_t) || *location > OFF_T_MAX) {
+		INDEX_MARK_CORRUPTED(index);
 		index_set_error(index, "Corrupted index file %s: "
 				"Invalid location field for record %u",
 				index->filepath, rec->uid);
 		return NULL;
 	}
 
+	offset = *location;
 	stop_offset = offset + rec->header_size + rec->body_size;
 
 	fd = open(index->mbox_path, O_RDONLY);
--- a/src/lib-index/mbox/mbox-sync.c	Sat Aug 31 19:02:07 2002 +0300
+++ b/src/lib-index/mbox/mbox-sync.c	Sat Aug 31 23:12:59 2002 +0300
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "iobuffer.h"
-#include "hex-binary.h"
 #include "mbox-index.h"
 #include "mail-index-util.h"
 
@@ -14,8 +13,9 @@
 static uoff_t get_indexed_mbox_size(MailIndex *index)
 {
 	MailIndexRecord *rec, *prev;
-	const char *location;
-	uoff_t size;
+	const uoff_t *location;
+	uoff_t offset;
+	unsigned int size;
 
 	if (index->lock_type == MAIL_LOCK_UNLOCK) {
 		if (!mail_index_set_lock(index, MAIL_LOCK_SHARED))
@@ -35,38 +35,36 @@
 		rec = prev;
 	}
 
-	size = 0;
+	offset = 0;
 	if (rec != NULL) {
 		/* get the offset + size of last message, which tells the
 		   last known mbox file size */
-		location = index->lookup_field(index, rec, FIELD_TYPE_LOCATION);
+		location = index->lookup_field_raw(index, rec,
+						   FIELD_TYPE_LOCATION, &size);
 		if (location == NULL) {
 			INDEX_MARK_CORRUPTED(index);
 			index_set_error(index, "Corrupted index file %s: "
 					"Missing location field for record %u",
 					index->filepath, rec->uid);
-		} else if (strlen(location) != sizeof(size)*2 ||
-			   hex_to_binary(location,
-					 (unsigned char *) &size) <= 0) {
-			size = 0;
+		} else if (size != sizeof(uoff_t) || *location > OFF_T_MAX) {
 			INDEX_MARK_CORRUPTED(index);
 			index_set_error(index, "Corrupted index file %s: "
 					"Invalid location field for record %u",
 					index->filepath, rec->uid);
 		} else {
-			size += rec->header_size + rec->body_size;
+			offset = *location + rec->header_size + rec->body_size;
 		}
 	}
 
 	if (index->lock_type == MAIL_LOCK_SHARED)
 		(void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
 
-	if (size > OFF_T_MAX) {
+	if (offset > OFF_T_MAX) {
 		/* too large to fit in off_t */
 		return 0;
 	}
 
-	return size;
+	return offset;
 }
 
 static int mbox_check_new_mail(MailIndex *index)