diff options
-rw-r--r-- | camel/ChangeLog | 65 | ||||
-rw-r--r-- | camel/camel-data-wrapper.h | 3 | ||||
-rw-r--r-- | camel/camel-folder-search.c | 133 | ||||
-rw-r--r-- | camel/camel-folder-search.h | 1 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 52 | ||||
-rw-r--r-- | camel/camel-object.c | 6 | ||||
-rw-r--r-- | camel/camel-store.c | 26 | ||||
-rw-r--r-- | camel/camel-store.h | 7 | ||||
-rw-r--r-- | camel/camel-stream-mem.h | 10 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 7 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 50 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.h | 5 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-store.c | 69 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-summary.c | 10 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-folder.c | 21 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-folder.h | 2 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-store.c | 8 | ||||
-rw-r--r-- | camel/providers/mh/camel-mh-summary.c | 7 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 2 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 4 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-store.c | 4 |
21 files changed, 348 insertions, 144 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index df450614e7..682a67a5d6 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,68 @@ +2000-10-18 Not Zed <NotZed@HelixCode.com> + + * camel-mime-part.c (add_header): No, we must not encode the + headers here. These interfaces ARE raw interfaces as they are + defined in camel_medium. Also removed a bogus/meaningless FIXME. + (set_header): Likewise here, we must not. + (process_header): Removed another bogus comment. + + * camel-object.c (shared_is_of_type): Comment out the spitting of + a big warning when we're trying to determine types from code. + + * providers/mbox/camel-mbox-summary.c + (message_info_new_from_parser): Only call ibex funcitons if we + have an index. + + * providers/mh/camel-mh-summary.c (camel_mh_summary_add): Only + call ibex functions if we have an index. + (remove_summary): Likewise. + (camel_mh_summary_check): Likewise. + + * providers/nntp/camel-nntp-store.c (nntp_store_get_folder): + get_folder -> flags argument. + + * providers/vee/camel-vee-store.c (vee_get_folder): create->flags. + + * providers/pop3/camel-pop3-store.c (get_folder): Changed create + -> flags. + + * providers/imap/camel-imap-store.c (get_folder): Added flags + argument. + + * providers/mh/camel-mh-folder.c (camel_mh_folder_new): Added + flags argument, and fixed code appropriately. + + * providers/mh/camel-mh-store.c (get_folder): Added flags argument. + + * camel-folder-search.c (message_body_contains): Perform a regex + match on the contents of messages. This wont quite work yet as + message contents are encoded when written to a stream. + (build_match_regex): Converts a number of strings into a regex + matching pattern, escaping special chars. + (match_message): match a single message from a folder, by uid. + Slow. + (search_body_contains): Changed to support matching where no index + is supplied. Matches are performed by retrieving message + contents, etc. + () WTF? camel should not be including any widget headers. + + * providers/mbox/camel-mbox-folder.c (camel_mbox_folder_new): + Added flags argument. + (mbox_refresh_info): Changed into a NOP, the refresh info code + moved into the new function. + (camel_mbox_folder_new): If we have an index requested, build one, + otherwise, remove an old one, or just dont do anything. + + * providers/mbox/camel-mbox-store.c (get_folder): Changed create + to flags, changed code to suit. + + * camel-store.c (camel_store_get_folder): Changed create to flags. + (get_folder_internal): And here. + (get_folder): And here too. + + * camel-store.h (camel_store_get_folder): Change the create + argument to be a flags argument. + 2000-10-17 Dan Winship <danw@helixcode.com> * providers/imap/camel-imap-folder.c (imap_refresh_info): Remove diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index 4a3074ae20..ff4dda649f 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -86,8 +86,7 @@ GMimeContentField * camel_data_wrapper_get_mime_type_field (CamelDataWrappe void camel_data_wrapper_set_mime_type_field (CamelDataWrapper *data_wrapper, GMimeContentField *mime_type); -int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, - CamelStream *stream); +int camel_data_wrapper_construct_from_stream (CamelDataWrapper *data_wrapper, CamelStream *stream); #ifdef __cplusplus } diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c index 7c1f117ea4..6687067d13 100644 --- a/camel/camel-folder-search.c +++ b/camel/camel-folder-search.c @@ -26,11 +26,19 @@ #include <stdio.h> #include <string.h> #include <glib.h> +#include <regex.h> #include <gal/widgets/e-unicode.h> #include "camel-folder-search.h" #include "string-utils.h" +#include "camel-exception.h" +#include "camel-medium.h" +#include "camel-multipart.h" +#include "camel-mime-message.h" +#include "gmime-content-field.h" +#include "camel-stream-mem.h" + #define d(x) x #define r(x) x @@ -436,11 +444,112 @@ g_lib_sux_htor(char *key, int value, struct _glib_sux_donkeys *fuckup) g_ptr_array_add(fuckup->uids, key); } +/* performs a 'slow' content-based match */ +static gboolean +message_body_contains(CamelDataWrapper *object, regex_t *pattern) +{ + CamelDataWrapper *containee; + int truth = FALSE; + int parts, i; + + containee = camel_medium_get_content_object(CAMEL_MEDIUM(object)); + + if (containee == NULL) + return FALSE; + + /* TODO: I find it odd that get_part and get_content_object do not + add a reference, probably need fixing for multithreading */ + + /* using the object types is more accurate than using the mime/types */ + if (CAMEL_IS_MULTIPART(containee)) { + parts = camel_multipart_get_number(CAMEL_MULTIPART(containee)); + for (i=0;i<parts && truth==FALSE;i++) { + CamelDataWrapper *part = (CamelDataWrapper *)camel_multipart_get_part(CAMEL_MULTIPART(containee), i); + if (part) { + truth = message_body_contains(part, pattern); + } + } + } else if (CAMEL_IS_MIME_MESSAGE(containee)) { + /* for messages we only look at its contents */ + truth = message_body_contains((CamelDataWrapper *)containee, pattern); + } else if (gmime_content_field_is_type(CAMEL_DATA_WRAPPER(containee)->mime_type, "text", "*")) { + /* for all other text parts, we look inside, otherwise we dont care */ + CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new(); + + camel_data_wrapper_write_to_stream(containee, (CamelStream *)mem); + camel_stream_write((CamelStream *)mem, "", 1); + truth = regexec(pattern, mem->buffer->data, 0, NULL, 0) == 0; + camel_object_unref((CamelObject *)mem); + } + return truth; +} + +/* builds the regex into pattern */ +static int +build_match_regex(regex_t *pattern, int argc, struct _ESExpResult **argv) +{ + GString *match = g_string_new(""); + int c, i, count=0, err; + char *word; + + /* build a regex pattern we can use to match the words, we OR them together */ + if (argc>1) + g_string_append_c(match, '('); + for (i=0;i<argc;i++) { + if (argv[i]->type == ESEXP_RES_STRING) { + if (count > 0) + g_string_append_c(match, '|'); + /* escape any special chars (not sure if this list is complete) */ + word = argv[i]->value.string; + while ((c = *word++)) { + if (strchr("*\\.()[]^$+", c) != NULL) { + g_string_append_c(match, '\\'); + } + g_string_append_c(match, c); + } + count++; + } else { + g_warning("Invalid type passed to body-contains match function"); + } + } + if (argc>1) + g_string_append_c(match, ')'); + err = regcomp(pattern, match->str, REG_EXTENDED|REG_ICASE|REG_NOSUB); + if (err != 0) { + char buffer[1024]; /* dont really care if its longer than this ... */ + + regerror(err, pattern, buffer, 1023); + g_warning("Internal error with search pattern: %s: %s", match->str, buffer); + regfree(pattern); + } + d(printf("Built regex: '%s'\n", match->str)); + g_string_free(match, TRUE); + return err; +} + +static int +match_message(CamelFolder *folder, const char *uid, regex_t *pattern) +{ + CamelMimeMessage *msg; + int truth = FALSE; + CamelException *ex; + + ex = camel_exception_new(); + msg = camel_folder_get_message(folder, uid, ex); + if (!camel_exception_is_set(ex) && msg!=NULL) { + truth = message_body_contains((CamelDataWrapper *)msg, pattern); + camel_object_unref((CamelObject *)msg); + } + camel_exception_free(ex); + return truth; +} + static ESExpResult * search_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *search) { ESExpResult *r; int i, j; + regex_t pattern; if (search->current) { int truth = FALSE; @@ -454,8 +563,14 @@ search_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, Cam g_warning("Invalid type passed to body-contains match function"); } } + } else if (search->folder) { + /* we do a 'slow' direct search */ + if (build_match_regex(&pattern, argc, argv) == 0) { + truth = match_message(search->folder, search->current->uid, &pattern); + regfree(&pattern); + } } else { - g_warning("Cannot perform indexed body query with no index"); + g_warning("Cannot perform indexed body query with no index or folder set"); } r->value.bool = truth; } else { @@ -487,7 +602,23 @@ search_body_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, Cam r->value.ptrarray = lambdafoo.uids; g_hash_table_destroy(ht); } + } else if (search->folder) { + /* do a slow search */ + r->value.ptrarray = g_ptr_array_new(); + if (build_match_regex(&pattern, argc, argv) == 0) { + if (search->summary) { + for (i=0;i<search->summary->len;i++) { + CamelMessageInfo *info = g_ptr_array_index(search->summary, i); + + if (match_message(search->folder, info->uid, &pattern)) + g_ptr_array_add(r->value.ptrarray, info->uid); + } + } /* else? we could always get the summary from the folder, but then + we need to free it later somehow */ + regfree(&pattern); + } } else { + g_warning("Cannot perform indexed body query with no index or folder set"); r->value.ptrarray = g_ptr_array_new(); } } diff --git a/camel/camel-folder-search.h b/camel/camel-folder-search.h index fbea5c4cca..f74813e6f7 100644 --- a/camel/camel-folder-search.h +++ b/camel/camel-folder-search.h @@ -46,6 +46,7 @@ struct _CamelFolderSearch { CamelFolder *folder; /* folder for current search */ GPtrArray *summary; /* summary array for current search */ CamelMessageInfo *current; /* current message info, when searching one by one */ + CamelMimeMessage *current_message; /* cache of current message, if required */ ibex *body_index; }; diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 955a3a7738..cb60d688a0 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -187,8 +187,6 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ /* known, the job is done in the parsing routine. If not, */ /* we simply add the header in a raw fashion */ - /* FIXME: MUST check fields for validity before adding them! */ - header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, header_name); switch (header_type) { case HEADER_DESCRIPTION: /* raw header->utf8 conversion */ @@ -197,7 +195,7 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ mime_part->description = g_strstrip (text); break; case HEADER_DISPOSITION: - set_disposition (mime_part, header_value); + set_disposition(mime_part, header_value); break; case HEADER_CONTENT_ID: text = header_msgid_decode(header_value); @@ -214,7 +212,7 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ mime_part->content_MD5 = g_strdup(header_value); break; case HEADER_CONTENT_TYPE: - gmime_content_field_construct_from_string (mime_part->content_type, header_value); + gmime_content_field_construct_from_string(mime_part->content_type, header_value); break; default: return FALSE; @@ -225,37 +223,39 @@ process_header(CamelMedium *medium, const char *header_name, const char *header_ /* Note: It is my understanding that we need to encode the values here as they are not being encoded at the header_raw_* level. */ +/* + NO: This is absolutely wrong. The medium interface is entirely raw. + You cannot just go blingingly encoding headers because it depends entirely + on the header being encoded. process_header decodes and mirrors the + known headers, appropriately, and we just add this raw header to our + list. + + Please read the comments, they explained it already!!!!!!! +*/ + static void set_header (CamelMedium *medium, const char *header_name, const void *header_value) { CamelMimePart *part = CAMEL_MIME_PART (medium); - char *encoded_value = header_encode_string (header_value); - process_header (medium, header_name, encoded_value); - header_raw_replace (&part->headers, header_name, encoded_value, -1); - - g_free (encoded_value); + process_header(medium, header_name, header_value); + header_raw_replace(&part->headers, header_name, header_value, -1); } static void add_header (CamelMedium *medium, const char *header_name, const void *header_value) { CamelMimePart *part = CAMEL_MIME_PART (medium); - char *encoded_value = header_encode_string (header_value); /* Try to parse the header pair. If it corresponds to something */ /* known, the job is done in the parsing routine. If not, */ /* we simply add the header in a raw fashion */ - /* FIXME: MUST check fields for validity before adding them! */ - /* If it was one of the headers we handled, it must be unique, set it instead of add */ - if (process_header (medium, header_name, encoded_value)) - header_raw_replace (&part->headers, header_name, encoded_value, -1); + if (process_header(medium, header_name, header_value)) + header_raw_replace(&part->headers, header_name, header_value, -1); else - header_raw_append (&part->headers, header_name, encoded_value, -1); - - g_free (encoded_value); + header_raw_append(&part->headers, header_name, header_value, -1); } static void @@ -473,10 +473,10 @@ set_content_object (CamelMedium *medium, CamelDataWrapper *content) /**********************************************************************/ static int -write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) +write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) { - CamelMimePart *mp = CAMEL_MIME_PART (data_wrapper); - CamelMedium *medium = CAMEL_MEDIUM (data_wrapper); + CamelMimePart *mp = CAMEL_MIME_PART(data_wrapper); + CamelMedium *medium = CAMEL_MEDIUM(data_wrapper); CamelDataWrapper *content; int total = 0; int count; @@ -494,12 +494,10 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) while (h) { if (h->value == NULL){ - g_warning ("h->value is NULL here for %s", h->name); + g_warning("h->value is NULL here for %s", h->name); count = 0; } else { - count = camel_stream_printf( - stream, "%s%s%s\n", h->name, - isspace(h->value[0]) ? ":" : ": ", h->value); + count = camel_stream_printf(stream, "%s%s%s\n", h->name, isspace(h->value[0]) ? ":" : ": ", h->value); } if (count == -1) return -1; @@ -508,12 +506,12 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) } } - count = camel_stream_write (stream, "\n", 1); + count = camel_stream_write(stream, "\n", 1); if (count == -1) return -1; total += count; - content = camel_medium_get_content_object (medium); + content = camel_medium_get_content_object(medium); if (content) { /* I dont really like this here, but i dont know where else it might go ... */ #define CAN_THIS_GO_ELSEWHERE @@ -569,7 +567,7 @@ write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) } #endif - count = camel_data_wrapper_write_to_stream (content, stream); + count = camel_data_wrapper_write_to_stream(content, stream); if (filter_stream) { camel_stream_flush((CamelStream *)filter_stream); camel_object_unref((CamelObject *)filter_stream); diff --git a/camel/camel-object.c b/camel/camel-object.c index 7805546c9e..75c14b8978 100644 --- a/camel/camel-object.c +++ b/camel/camel-object.c @@ -925,10 +925,12 @@ shared_is_of_type (CamelObjectShared * sh, CamelType ctype, gboolean is_obj) parent)); } - g_warning + /* this isn't an error, e.g. CAMEL_IS_FOLDER(folder), its upto the + caller to handle the false case */ + /*g_warning ("shared_is_of_type: %s of `%s' (@%p) is not also %s of `%s'", targtype, camel_type_to_name (sh->type), sh, targtype, - camel_type_to_name (ctype)); + camel_type_to_name (ctype));*/ camel_type_lock_down (); return FALSE; diff --git a/camel/camel-store.c b/camel/camel-store.c index cb2f73f79b..fd3e7c83cf 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -37,7 +37,7 @@ static CamelServiceClass *parent_class = NULL; #define CS_CLASS(so) CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex); + guint32 flags, CamelException *ex); static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder (CamelStore *store, const char *old_name, @@ -130,11 +130,10 @@ camel_store_get_type (void) static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex) +get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - g_warning ("CamelStore::get_folder not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); + g_warning("CamelStore::get_folder not implemented for `%s'", + camel_type_to_name(CAMEL_OBJECT_GET_TYPE(store))); return NULL; } @@ -242,21 +241,19 @@ uncache_folder (CamelStore *store, CamelFolder *folder) static CamelFolder * -get_folder_internal (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex) +get_folder_internal(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { CamelFolder *folder = NULL; /* Try cache first. */ - folder = CS_CLASS (store)->lookup_folder (store, folder_name); + folder = CS_CLASS(store)->lookup_folder(store, folder_name); if (!folder) { - folder = CS_CLASS (store)->get_folder (store, folder_name, - create, ex); + folder = CS_CLASS(store)->get_folder(store, folder_name, flags, ex); if (!folder) return NULL; - CS_CLASS (store)->cache_folder (store, folder_name, folder); + CS_CLASS(store)->cache_folder(store, folder_name, folder); } return folder; @@ -280,15 +277,14 @@ get_folder_internal (CamelStore *store, const char *folder_name, * Return value: the folder **/ CamelFolder * -camel_store_get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex) +camel_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { char *name; CamelFolder *folder = NULL; - name = CS_CLASS (store)->get_folder_name (store, folder_name, ex); + name = CS_CLASS(store)->get_folder_name(store, folder_name, ex); if (name) { - folder = get_folder_internal (store, name, create, ex); + folder = get_folder_internal(store, name, flags, ex); g_free (name); } return folder; diff --git a/camel/camel-store.h b/camel/camel-store.h index 57c45f4769..2be350bca5 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -64,13 +64,16 @@ struct _CamelStore }; +/* open mode for folder */ +#define CAMEL_STORE_FOLDER_CREATE (1<<0) +#define CAMEL_STORE_FOLDER_BODY_INDEX (1<<1) typedef struct { CamelServiceClass parent_class; CamelFolder * (*get_folder) (CamelStore *store, const char *folder_name, - gboolean create, + guint32 flags, CamelException *ex); void (*delete_folder) (CamelStore *store, @@ -122,7 +125,7 @@ CamelType camel_store_get_type (void); /* public methods */ CamelFolder * camel_store_get_folder (CamelStore *store, const char *folder_name, - gboolean create, + guint32 flags, CamelException *ex); CamelFolder * camel_store_get_root_folder (CamelStore *store, CamelException *ex); diff --git a/camel/camel-stream-mem.h b/camel/camel-stream-mem.h index b27503efb6..422d05426c 100644 --- a/camel/camel-stream-mem.h +++ b/camel/camel-stream-mem.h @@ -60,13 +60,13 @@ struct _CamelStreamMemClass { CamelType camel_stream_mem_get_type (void); /* public methods */ -CamelStream *camel_stream_mem_new (void); -CamelStream *camel_stream_mem_new_with_byte_array (GByteArray *buffer); -CamelStream *camel_stream_mem_new_with_buffer (const char *buffer, size_t len); +CamelStream *camel_stream_mem_new(void); +CamelStream *camel_stream_mem_new_with_byte_array(GByteArray *buffer); +CamelStream *camel_stream_mem_new_with_buffer(const char *buffer, size_t len); /* these are really only here for implementing classes */ -void camel_stream_mem_set_byte_array (CamelStreamMem *, GByteArray *buffer); -void camel_stream_mem_set_buffer (CamelStreamMem *, const char *buffer, size_t len); +void camel_stream_mem_set_byte_array(CamelStreamMem *, GByteArray *buffer); +void camel_stream_mem_set_buffer(CamelStreamMem *, const char *buffer, size_t len); #ifdef __cplusplus } diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index ae4c13c150..80dc8dcd3c 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -57,8 +57,7 @@ static gboolean imap_connect (CamelService *service, CamelException *ex); static gboolean imap_disconnect (CamelService *service, CamelException *ex); static GList *query_auth_types_generic (CamelService *service, CamelException *ex); static GList *query_auth_types_connected (CamelService *service, CamelException *ex); -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboolean create, - CamelException *ex); +static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); static char *get_root_folder_name (CamelStore *store, CamelException *ex); @@ -420,7 +419,7 @@ imap_create (CamelImapStore *store, const char *folder_path, CamelException *ex) } static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelFolder *new_folder = NULL; @@ -429,7 +428,7 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelEx folder_path = camel_imap_store_folder_path (imap_store, folder_name); if (!imap_folder_exists (imap_store, folder_path, &selectable, ex)) { - if (!create) { + if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { g_free (folder_path); return NULL; } diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index 163de6784f..55e2916ed4 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -171,11 +171,13 @@ CamelType camel_mbox_folder_get_type(void) } CamelFolder * -camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, CamelException *ex) +camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) { CamelFolder *folder; CamelMboxFolder *mbox_folder; const char *root_dir_path, *name; + struct stat st; + int forceindex; folder = CAMEL_FOLDER (camel_object_new (CAMEL_MBOX_FOLDER_TYPE)); mbox_folder = (CamelMboxFolder *)folder; @@ -195,39 +197,41 @@ camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, CamelExce mbox_folder->folder_dir_path = g_strdup_printf("%s/%s.sdb", root_dir_path, full_name); mbox_folder->index_file_path = g_strdup_printf("%s/%s.ibex", root_dir_path, full_name); - mbox_refresh_info (folder, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - folder = NULL; - } - - return folder; -} - -static void -mbox_refresh_info (CamelFolder *folder, CamelException *ex) -{ - CamelMboxFolder *mbox_folder = (CamelMboxFolder *) folder; - struct stat st; - int forceindex; - /* if we have no index file, force it */ forceindex = stat(mbox_folder->index_file_path, &st) == -1; + if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) { - mbox_folder->index = ibex_open(mbox_folder->index_file_path, O_CREAT | O_RDWR, 0600); - if (mbox_folder->index == NULL) { - /* yes, this isn't fatal at all */ - g_warning("Could not open/create index file: %s: indexing not performed", strerror(errno)); + mbox_folder->index = ibex_open(mbox_folder->index_file_path, O_CREAT | O_RDWR, 0600); + if (mbox_folder->index == NULL) { + /* yes, this isn't fatal at all */ + g_warning("Could not open/create index file: %s: indexing not performed", strerror(errno)); + forceindex = FALSE; + } + } else { + /* if we do have an index file, remove it */ + if (forceindex == FALSE) { + unlink(mbox_folder->index_file_path); + } + forceindex = FALSE; } - /* no summary (disk or memory), and we're proverbially screwed */ mbox_folder->summary = camel_mbox_summary_new(mbox_folder->summary_file_path, mbox_folder->folder_file_path, mbox_folder->index); if (mbox_folder->summary == NULL || camel_mbox_summary_load(mbox_folder->summary, forceindex) == -1) { camel_exception_set(ex, CAMEL_EXCEPTION_FOLDER_INVALID, /* FIXME: right error code */ "Could not create summary"); - return; + camel_object_unref (CAMEL_OBJECT (folder)); + return NULL; } + + return folder; +} + +static void +mbox_refresh_info (CamelFolder *folder, CamelException *ex) +{ + /* we are always in a consistent state, or fix it when we need to */ + return; } static void diff --git a/camel/providers/mbox/camel-mbox-folder.h b/camel/providers/mbox/camel-mbox-folder.h index 4cc91eda75..d6e8b0682c 100644 --- a/camel/providers/mbox/camel-mbox-folder.h +++ b/camel/providers/mbox/camel-mbox-folder.h @@ -69,10 +69,11 @@ typedef struct { /* public methods */ -CamelFolder *camel_mbox_folder_new (CamelStore *parent_store, const char *full_name, CamelException *ex); +/* flags are taken from CAMEL_STORE_FOLDER_* flags */ +CamelFolder *camel_mbox_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); /* Standard Camel function */ -CamelType camel_mbox_folder_get_type (void); +CamelType camel_mbox_folder_get_type(void); #ifdef __cplusplus } diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c index 6ad729ce7d..2625722134 100644 --- a/camel/providers/mbox/camel-mbox-store.c +++ b/camel/providers/mbox/camel-mbox-store.c @@ -39,14 +39,11 @@ #define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) #define CMBOXF_CLASS(so) CAMEL_MBOX_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) -static char *get_name (CamelService *service, gboolean brief); -static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex); -static void delete_folder (CamelStore *store, const char *folder_name, - CamelException *ex); +static char *get_name(CamelService *service, gboolean brief); +static CamelFolder *get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); +static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); +static char *get_folder_name(CamelStore *store, const char *folder_name, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, gboolean subscribed_only, @@ -109,55 +106,53 @@ camel_mbox_store_get_toplevel_dir (CamelMboxStore *store) } static CamelFolder * -get_folder (CamelStore *store, const char *folder_name, gboolean create, - CamelException *ex) +get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { char *name; struct stat st; - name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path, - folder_name); + name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name); - if (stat (name, &st) == -1) { + if (stat(name, &st) == -1) { int fd; if (errno != ENOENT) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not open file `%s':" - "\n%s", name, - g_strerror (errno)); - g_free (name); + camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, + "Could not open file `%s':" + "\n%s", name, + g_strerror(errno)); + g_free(name); return NULL; } - if (!create) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - "Folder `%s' does not exist.", - folder_name); - g_free (name); + if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { + camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "Folder `%s' does not exist.", + folder_name); + g_free(name); return NULL; } - fd = open (name, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); + fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0600); if (fd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not create file `%s':" - "\n%s", name, - g_strerror (errno)); - g_free (name); + camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, + "Could not create file `%s':" + "\n%s", name, + g_strerror(errno)); + g_free(name); return NULL; } - g_free (name); - close (fd); - } else if (!S_ISREG (st.st_mode)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - "`%s' is not a regular file.", - name); - g_free (name); + g_free(name); + close(fd); + } else if (!S_ISREG(st.st_mode)) { + camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, + "`%s' is not a regular file.", + name); + g_free(name); return NULL; } else - g_free (name); + g_free(name); - return camel_mbox_folder_new (store, folder_name, ex); + return camel_mbox_folder_new(store, folder_name, flags, ex); } static void diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c index 18d889ee84..c037b6000e 100644 --- a/camel/providers/mbox/camel-mbox-summary.c +++ b/camel/providers/mbox/camel-mbox-summary.c @@ -228,10 +228,10 @@ message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp) mbi->frompos = camel_mime_parser_tell_start_from(mp); /* do we want to index this message as we add it, as well? */ - if (mbs->index_force - || (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 - || !ibex_contains_name(mbs->index, mi->uid)) { - + if (mbs->index + && (mbs->index_force + || (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0 + || !ibex_contains_name(mbs->index, mi->uid))) { camel_folder_summary_set_index(s, mbs->index); } else { camel_folder_summary_set_index(s, NULL); @@ -387,7 +387,7 @@ camel_mbox_summary_load(CamelMboxSummary *mbs, int forceindex) for (i = 0; i < camel_folder_summary_count(s); i++) { CamelMessageInfo *mi = camel_folder_summary_index(s, i); - if (!ibex_contains_name(mbs->index, mi->uid)) { + if (mbs->index && !ibex_contains_name(mbs->index, mi->uid)) { minstart = ((CamelMboxMessageInfo *) mi)->frompos; printf("Found unindexed message: %s\n", mi->uid); break; diff --git a/camel/providers/mh/camel-mh-folder.c b/camel/providers/mh/camel-mh-folder.c index c8b0503e95..ccd9d717e9 100644 --- a/camel/providers/mh/camel-mh-folder.c +++ b/camel/providers/mh/camel-mh-folder.c @@ -158,7 +158,7 @@ CamelType camel_mh_folder_get_type(void) } CamelFolder * -camel_mh_folder_new(CamelStore *parent_store, const char *full_name, CamelException *ex) +camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex) { CamelFolder *folder; CamelMhFolder *mh_folder; @@ -185,11 +185,20 @@ camel_mh_folder_new(CamelStore *parent_store, const char *full_name, CamelExcept /* if we have no index file, force it */ forceindex = stat(mh_folder->index_file_path, &st) == -1; - - mh_folder->index = ibex_open(mh_folder->index_file_path, O_CREAT | O_RDWR, 0600); - if (mh_folder->index == NULL) { - /* yes, this isn't fatal at all */ - g_warning("Could not open/create index file: %s: indexing not performed", strerror(errno)); + /* check if we need to setup an index */ + if (flags & CAMEL_STORE_FOLDER_BODY_INDEX) { + mh_folder->index = ibex_open(mh_folder->index_file_path, O_CREAT | O_RDWR, 0600); + if (mh_folder->index == NULL) { + /* yes, this isn't fatal at all */ + g_warning("Could not open/create index file: %s: indexing not performed", strerror(errno)); + forceindex = FALSE; + } + } else { + /* if we do have an index file, remove it */ + if (forceindex == FALSE) { + unlink(mh_folder->index_file_path); + } + forceindex = FALSE; } /* no summary (disk or memory), and we're proverbially screwed */ diff --git a/camel/providers/mh/camel-mh-folder.h b/camel/providers/mh/camel-mh-folder.h index 90f2324d11..bdb1588811 100644 --- a/camel/providers/mh/camel-mh-folder.h +++ b/camel/providers/mh/camel-mh-folder.h @@ -62,7 +62,7 @@ typedef struct { } CamelMhFolderClass; /* public methods */ -CamelFolder *camel_mh_folder_new(CamelStore *parent_store, const char *full_name, CamelException *ex); +CamelFolder *camel_mh_folder_new(CamelStore *parent_store, const char *full_name, guint32 flags, CamelException *ex); /* Standard Camel function */ CamelType camel_mh_folder_get_type(void); diff --git a/camel/providers/mh/camel-mh-store.c b/camel/providers/mh/camel-mh-store.c index c169d878fd..ead6e4f340 100644 --- a/camel/providers/mh/camel-mh-store.c +++ b/camel/providers/mh/camel-mh-store.c @@ -41,7 +41,7 @@ #define CMHF_CLASS(so) CAMEL_MH_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) static char *get_name(CamelService * service, gboolean brief); -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboolean create, CamelException * ex); +static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex); static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex); @@ -102,7 +102,7 @@ const gchar *camel_mh_store_get_toplevel_dir(CamelMhStore * store) return url->path; } -static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboolean create, CamelException * ex) +static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex) { char *name; struct stat st; @@ -118,7 +118,7 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo g_free (name); return NULL; } - if (!create) { + if ((flags & CAMEL_STORE_FOLDER_CREATE) == 0) { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, "Folder `%s' does not exist.", folder_name); g_free (name); @@ -141,7 +141,7 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo } g_free(name); - return camel_mh_folder_new (store, folder_name, ex); + return camel_mh_folder_new(store, folder_name, flags, ex); } static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex) diff --git a/camel/providers/mh/camel-mh-summary.c b/camel/providers/mh/camel-mh-summary.c index 5d304b4a42..ce1d597012 100644 --- a/camel/providers/mh/camel-mh-summary.c +++ b/camel/providers/mh/camel-mh-summary.c @@ -161,7 +161,7 @@ int camel_mh_summary_add(CamelMhSummary * mhs, const char *name, int forceindex mp = camel_mime_parser_new(); camel_mime_parser_scan_from(mp, FALSE); camel_mime_parser_init_with_fd(mp, fd); - if (forceindex || !ibex_contains_name(mhs->index, (char *)name)) { + if (mhs->index && (forceindex || !ibex_contains_name(mhs->index, (char *)name))) { d(printf("forcing indexing of message content\n")); camel_folder_summary_set_index((CamelFolderSummary *)mhs, mhs->index); } else { @@ -180,7 +180,8 @@ static void remove_summary(char *key, CamelMessageInfo *info, CamelMhSummary *mhs) { d(printf("removing message %s from summary\n", key)); - ibex_unindex(mhs->index, info->uid); + if (mhs->index) + ibex_unindex(mhs->index, info->uid); camel_folder_summary_remove((CamelFolderSummary *)mhs, info); } @@ -219,7 +220,7 @@ int camel_mh_summary_check(CamelMhSummary * mhs, int forceindex) } if (c==0) { info = camel_folder_summary_uid((CamelFolderSummary *)mhs, d->d_name); - if (info == NULL || (!ibex_contains_name(mhs->index, d->d_name))) { + if (info == NULL || (mhs->index && (!ibex_contains_name(mhs->index, d->d_name)))) { /* need to add this file to the summary */ if (info != NULL) { g_hash_table_remove(left, info->uid); diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 44b5fc102f..c75acbce44 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -315,7 +315,7 @@ nntp_store_query_auth_types_connected (CamelService *service, CamelException *ex static CamelFolder * nntp_store_get_folder (CamelStore *store, const gchar *folder_name, - gboolean get_folder, CamelException *ex) + guint32 flags, CamelException *ex) { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index c5159eda1d..57af24b7f3 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -74,7 +74,7 @@ static GList *query_auth_types_connected (CamelService *service, CamelException static GList *query_auth_types_generic (CamelService *service, CamelException *ex); static CamelFolder *get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex); + guint32 flags, CamelException *ex); static char *get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); static char *get_root_folder_name (CamelStore *store, CamelException *ex); @@ -544,7 +544,7 @@ pop3_disconnect (CamelService *service, CamelException *ex) static CamelFolder * get_folder (CamelStore *store, const char *folder_name, - gboolean create, CamelException *ex) + guint32 flags, CamelException *ex) { return camel_pop3_folder_new (store, ex); } diff --git a/camel/providers/vee/camel-vee-store.c b/camel/providers/vee/camel-vee-store.c index 201c4b1fd8..7acc127542 100644 --- a/camel/providers/vee/camel-vee-store.c +++ b/camel/providers/vee/camel-vee-store.c @@ -22,7 +22,7 @@ #include "camel-vee-store.h" #include "camel-vee-folder.h" -static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex); +static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static char *vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); struct _CamelVeeStorePrivate { @@ -89,7 +89,7 @@ camel_vee_store_new (void) } static CamelFolder * -vee_get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelException *ex) +vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { return camel_vee_folder_new (store, folder_name, ex); } |