aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog34
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-folder-search.c8
-rw-r--r--camel/camel-folder-summary.c1041
-rw-r--r--camel/camel-folder-summary.h181
-rw-r--r--camel/camel-folder.c1
-rw-r--r--camel/camel-folder.h13
-rw-r--r--camel/camel-mime-filter-index.c12
-rw-r--r--camel/camel-mime-filter-index.h1
-rw-r--r--camel/camel-mime-parser.c288
-rw-r--r--camel/camel-mime-parser.h1
-rw-r--r--camel/camel-mime-part-utils.c8
-rw-r--r--camel/camel-mime-part.c8
-rw-r--r--camel/camel-mime-utils.c36
-rw-r--r--camel/providers/mbox/camel-mbox-summary.c10
15 files changed, 1597 insertions, 47 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 39846f46ca..5a655a3aa7 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,25 @@
+2000-05-04 NotZed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-summary.c: Yes, and anotherone.
+
+ * camel-mime-utils.c: And another one.
+
+ * camel-mime-part.c: And another one.
+
+ * camel-mime-part-utils.c: And another one.
+
+ * camel-folder-search.c: And another one.
+
+ * camel-mime-parser.c: Reverted a change wihtout a ChangeLog entry.
+
+2000-05-04 NotZed <NotZed@HelixCode.com>
+
+ * camel-folder-summary.[hc]: Yes, CamelFolderSummary is back ...
+ ... re-usable class to summarise and index any stream or message
+ and to manage/load/save the created summaries.
+
+ * camel-folder.c: Include string.h to kill a warning.
+
2000-05-03 Jason Leach <leach@wam.umd.edu>
* Makefile.am (INCLUDES): add $(UNICODE_CFLAGS) to the INCLUDES,
@@ -6,6 +28,18 @@
2000-05-03 NotZed <NotZed@HelixCode.com>
+ * camel-folder.h: Added pos/bodypos/endpos to the basic message
+ content info object. Size to be removed? Moved the
+ messageconentinfo and messageinfo back to camel-folder-summary.h.
+
+ * camel-mime-filter-index.c (camel_mime_filter_index_set_ibex):
+ New function to (re)set the index to use on a filter.
+
+ * camel-mime-parser.c (camel_mime_parser_scan_from): Whole bunch
+ of inline docs.
+ (camel_mime_parser_drop_step): New function to drop a state from
+ the parser. Needs more testing.
+
* camel-mime-utils.c (rfc2047_decode_word): If the iconv handle is
-1, then dont try and convert (crashes unicode_iconv?).
(rfc2047_decode_word): Use alloca for variables instead of
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 81914c5950..513cd25648 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -38,6 +38,7 @@ libcamel_la_SOURCES = \
camel-exception.c \
camel-folder.c \
camel-folder-search.c \
+ camel-folder-summary.c \
camel-medium.c \
camel-marshal-utils.c \
camel-mime-message.c \
@@ -81,6 +82,7 @@ libcamelinclude_HEADERS = \
camel-exception.h \
camel-folder.h \
camel-folder-search.h \
+ camel-folder-summary.h \
camel-marshal-utils.h \
camel-medium.h \
camel-mime-message.h \
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 9d6f80d256..8a58d9a6ef 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -358,15 +358,15 @@ search_header_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, C
/* only a subset of headers are supported .. */
headername = argv[0]->value.string;
- if (!g_strcasecmp(headername, "subject")) {
+ if (!strcasecmp(headername, "subject")) {
header = search->current->subject;
- } else if (!g_strcasecmp(headername, "date")) {
+ } else if (!strcasecmp(headername, "date")) {
/* FIXME: not a very useful form of the date */
sprintf(strbuf, "%d", (int)search->current->date_sent);
header = strbuf;
- } else if (!g_strcasecmp(headername, "from")) {
+ } else if (!strcasecmp(headername, "from")) {
header = search->current->from;
- } else if (!g_strcasecmp(headername, "to")) {
+ } else if (!strcasecmp(headername, "to")) {
header = search->current->from;
} else {
g_warning("Performing query on unknown header: %s", headername);
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
new file mode 100644
index 0000000000..c54100375f
--- /dev/null
+++ b/camel/camel-folder-summary.c
@@ -0,0 +1,1041 @@
+/*
+ * Copyright (C) 2000 Helix Code Inc.
+ *
+ * Authors: Michael Zucchi <notzed@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <unistd.h>
+#include <netinet/in.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "camel-folder-summary.h"
+
+#include <camel/camel-mime-filter.h>
+#include <camel/camel-mime-filter-index.h>
+#include <camel/camel-mime-filter-charset.h>
+#include <camel/camel-mime-filter-save.h>
+#include <camel/camel-mime-filter-basic.h>
+#include "hash-table-utils.h"
+
+#define d(x)
+
+#define CAMEL_FOLDER_SUMMARY_VERSION (3)
+
+struct _CamelFolderSummaryPrivate {
+ GHashTable *filter_charset; /* CamelMimeFilterCharset's indexed by source charset */
+
+ CamelMimeFilterIndex *filter_index;
+ CamelMimeFilterBasic *filter_64;
+ CamelMimeFilterBasic *filter_qp;
+ CamelMimeFilterSave *filter_save;
+
+ ibex *index;
+};
+
+#define _PRIVATE(o) (((CamelFolderSummary *)(o))->priv)
+
+/* trivial lists, just because ... */
+struct _node {
+ struct _node *next;
+};
+
+static struct _node *my_list_append(struct _node **list, struct _node *n);
+static int my_list_size(struct _node **list);
+
+static int summary_header_load(CamelFolderSummary *, FILE *);
+static int summary_header_save(CamelFolderSummary *, FILE *);
+
+static CamelMessageInfo * message_info_new(CamelFolderSummary *, struct _header_raw *);
+static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
+static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
+static int message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
+static void message_info_free(CamelFolderSummary *, CamelMessageInfo *);
+
+static CamelMessageContentInfo * content_info_new(CamelFolderSummary *, struct _header_raw *);
+static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
+static CamelMessageContentInfo * content_info_load(CamelFolderSummary *, FILE *);
+static int content_info_save(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
+static void content_info_free(CamelFolderSummary *, CamelMessageContentInfo *);
+
+static CamelMessageContentInfo * summary_build_content_info(CamelFolderSummary *s, CamelMimeParser *mp);
+
+static void camel_folder_summary_class_init (CamelFolderSummaryClass *klass);
+static void camel_folder_summary_init (CamelFolderSummary *obj);
+static void camel_folder_summary_finalise (GtkObject *obj);
+
+static GtkObjectClass *camel_folder_summary_parent;
+
+enum SIGNALS {
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+guint
+camel_folder_summary_get_type (void)
+{
+ static guint type = 0;
+
+ if (!type) {
+ GtkTypeInfo type_info = {
+ "CamelFolderSummary",
+ sizeof (CamelFolderSummary),
+ sizeof (CamelFolderSummaryClass),
+ (GtkClassInitFunc) camel_folder_summary_class_init,
+ (GtkObjectInitFunc) camel_folder_summary_init,
+ (GtkArgSetFunc) NULL,
+ (GtkArgGetFunc) NULL
+ };
+
+ type = gtk_type_unique (gtk_object_get_type (), &type_info);
+ }
+
+ return type;
+}
+
+static void
+camel_folder_summary_class_init (CamelFolderSummaryClass *klass)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *) klass;
+
+ camel_folder_summary_parent = gtk_type_class (gtk_object_get_type ());
+
+ object_class->finalize = camel_folder_summary_finalise;
+
+ klass->summary_header_load = summary_header_load;
+ klass->summary_header_save = summary_header_save;
+
+ klass->message_info_new = message_info_new;
+ klass->message_info_new_from_parser = message_info_new_from_parser;
+ klass->message_info_load = message_info_load;
+ klass->message_info_save = message_info_save;
+ klass->message_info_free = message_info_free;
+
+ klass->content_info_new = content_info_new;
+ klass->content_info_new_from_parser = content_info_new_from_parser;
+ klass->content_info_load = content_info_load;
+ klass->content_info_save = content_info_save;
+ klass->content_info_free = content_info_free;
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+}
+
+static void
+camel_folder_summary_init (CamelFolderSummary *s)
+{
+ struct _CamelFolderSummaryPrivate *p;
+
+ p = _PRIVATE(s) = g_malloc0(sizeof(*p));
+
+ p->filter_charset = g_hash_table_new(g_strcase_hash, g_strcase_equal);
+
+ s->message_info_size = sizeof(CamelMessageInfo);
+ s->content_info_size = sizeof(CamelMessageContentInfo);
+
+ s->version = CAMEL_FOLDER_SUMMARY_VERSION;
+ s->flags = 0;
+ s->time = 0;
+ s->nextuid = 1;
+
+ s->messages = g_ptr_array_new();
+ s->messages_uid = g_hash_table_new(g_str_hash, g_str_equal);
+}
+
+static void
+camel_folder_summary_finalise (GtkObject *obj)
+{
+ struct _CamelFolderSummaryPrivate *p;
+ CamelFolderSummary *s = (CamelFolderSummary *)obj;
+
+ p = _PRIVATE(obj);
+
+ /* FIXME: free contents */
+ g_ptr_array_free(s->messages, TRUE);
+
+ g_hash_table_destroy(s->messages_uid);
+
+ /* FIXME: free contents */
+ g_hash_table_destroy(p->filter_charset);
+ g_free(p);
+
+ ((GtkObjectClass *)(camel_folder_summary_parent))->finalize((GtkObject *)obj);
+}
+
+/**
+ * camel_folder_summary_new:
+ *
+ * Create a new CamelFolderSummary object.
+ *
+ * Return value: A new CamelFolderSummary widget.
+ **/
+CamelFolderSummary *
+camel_folder_summary_new (void)
+{
+ CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( gtk_type_new (camel_folder_summary_get_type ()));
+ return new;
+}
+
+
+void camel_folder_summary_set_filename(CamelFolderSummary *s, const char *name)
+{
+ g_free(s->summary_path);
+ s->summary_path = g_strdup(name);
+}
+
+void camel_folder_summary_set_index(CamelFolderSummary *s, ibex *index)
+{
+ struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+
+ if (p->index)
+ ibex_write(p->index);
+ p->index = index;
+}
+
+void camel_folder_summary_set_build_content(CamelFolderSummary *s, gboolean state)
+{
+ s->build_content = state;
+}
+
+int
+camel_folder_summary_count(CamelFolderSummary *s)
+{
+ return s->messages->len;
+}
+
+CamelMessageInfo *
+camel_folder_summary_index(CamelFolderSummary *s, int i)
+{
+ if (i<s->messages->len)
+ return g_ptr_array_index(s->messages, i);
+ return NULL;
+}
+
+CamelMessageInfo *
+camel_folder_summary_uid(CamelFolderSummary *s, const char *uid)
+{
+ return g_hash_table_lookup(s->messages_uid, uid);
+}
+
+void
+camel_folder_summary_set_uid(CamelFolderSummary *s, guint32 base)
+{
+ if (s->nextuid <= base)
+ s->nextuid = base+1;
+}
+
+guint32 camel_folder_summary_next_uid(CamelFolderSummary *s)
+{
+ guint32 uid = s->nextuid++;
+
+ /* FIXME: sync this to disk */
+/* summary_header_save(s);*/
+ return uid;
+}
+
+/* loads the content descriptions, recursively */
+static CamelMessageContentInfo *
+perform_content_info_load(CamelFolderSummary *s, FILE *in)
+{
+ int i;
+ guint32 count;
+ CamelMessageContentInfo *ci, *part;
+
+ ci = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->content_info_load(s, in);
+ camel_folder_summary_decode_uint32(in, &count);
+ for (i=0;i<count;i++) {
+ part = perform_content_info_load(s, in);
+ if (part) {
+ my_list_append((struct _node **)&ci->childs, (struct _node *)ci);
+ ci->parent = ci;
+ } else {
+ g_warning("Summary file format messed up?");
+ }
+ }
+ return ci;
+}
+
+int
+camel_folder_summary_load(CamelFolderSummary *s)
+{
+ FILE *in;
+ int i;
+ CamelMessageInfo *mi;
+
+ g_assert(s->summary_path);
+
+ in = fopen(s->summary_path, "r");
+ if ( in == NULL ) {
+ return -1;
+ }
+
+ if ( ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->summary_header_load(s, in) == -1) {
+ fclose(in);
+ return -1;
+ }
+
+ /* now read in each message ... */
+ /* FIXME: check returns */
+ for (i=0;i<s->saved_count;i++) {
+ mi = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->message_info_load(s, in);
+
+ if (s->build_content) {
+ mi->content = content_info_load(s, in);
+ }
+ }
+
+ /* FIXME: check error return */
+ return 0;
+}
+
+/* saves the content descriptions, recursively */
+static int
+perform_content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *ci)
+{
+ CamelMessageContentInfo *part;
+
+ ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->content_info_save(s, out, ci);
+ camel_folder_summary_encode_uint32(out, my_list_size((struct _node **)&ci->childs));
+ part = ci->childs;
+ while (part) {
+ perform_content_info_save(s, out, part);
+ part = part->next;
+ }
+ return 0;
+}
+
+int
+camel_folder_summary_save(CamelFolderSummary *s)
+{
+ FILE *out;
+ int fd;
+ int i;
+ guint32 count;
+ CamelMessageInfo *mi;
+
+ g_assert(s->summary_path);
+
+ fd = open(s->summary_path, O_RDWR|O_CREAT, 0600);
+ if (fd == -1)
+ return -1;
+ out = fdopen(fd, "w");
+ if ( out == NULL ) {
+ close(fd);
+ return -1;
+ }
+
+ if ( ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->summary_header_save(s, out) == -1) {
+ fclose(out);
+ return -1;
+ }
+
+ /* now write out each message ... */
+ /* FIXME: check returns */
+ count = camel_folder_summary_count(s);
+ for (i=0;i<count;i++) {
+ mi = camel_folder_summary_index(s, i);
+ ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->message_info_save(s, out, mi);
+
+ if (s->build_content) {
+ perform_content_info_save(s, out, mi->content);
+ }
+ }
+ return fclose(out);
+}
+
+void camel_folder_summary_add(CamelFolderSummary *s, CamelMessageInfo *info)
+{
+ if (info == NULL)
+ return;
+retry:
+ if (info->uid == NULL) {
+ info->uid = g_strdup_printf("%u", s->nextuid++);
+ }
+ if (g_hash_table_lookup(s->messages_uid, info->uid)) {
+ g_warning("Trying to insert message with clashing uid. new uid re-assigned");
+ g_free(info->uid);
+ info->uid = NULL;
+ goto retry;
+ }
+
+ g_ptr_array_add(s->messages, info);
+ g_hash_table_insert(s->messages_uid, info->uid, info);
+ s->flags |= CAMEL_SUMMARY_DIRTY;
+}
+
+void camel_folder_summary_add_from_header(CamelFolderSummary *s, struct _header_raw *h)
+{
+ CamelMessageInfo *info;
+
+ info = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->message_info_new(s, h);
+ camel_folder_summary_add(s, info);
+}
+
+void camel_folder_summary_add_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
+{
+ CamelMessageInfo *info;
+ char *buffer;
+ int len;
+ struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+
+ /* should this check the parser is in the right state, or assume it is?? */
+
+ if (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_EOF) {
+ info = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->message_info_new_from_parser(s, mp);
+
+ camel_mime_parser_unstep(mp);
+
+ /* FIXME: better uid assignment method? */
+ if (info->uid == NULL) {
+ info->uid = g_strdup_printf("%u", s->nextuid++);
+ }
+
+ if (p->index) {
+ if (p->filter_index == NULL)
+ p->filter_index = camel_mime_filter_index_new_ibex(p->index);
+ camel_mime_filter_index_set_name(p->filter_index, info->uid);
+ ibex_unindex(p->index, info->uid);
+ }
+
+ /* build the content info, if we're supposed to */
+ if (s->build_content) {
+ info->content = summary_build_content_info(s, mp);
+ if (info->content->pos != -1)
+ info->size = info->content->endpos - info->content->pos;
+ } else {
+ camel_mime_parser_drop_step(mp);
+ }
+
+ camel_folder_summary_add(s, info);
+ }
+}
+
+int
+camel_folder_summary_encode_uint32(FILE *out, guint32 value)
+{
+ int i;
+
+ for (i=28;i>0;i-=7) {
+ if (value >= (1<<i)) {
+ unsigned int c = (value>>i) & 0x7f;
+ if (fputc(c, out) == -1)
+ return -1;
+ }
+ }
+ return fputc(value | 0x80, out);
+}
+
+int
+camel_folder_summary_decode_uint32(FILE *in, guint32 *dest)
+{
+ gint32 value=0, v;
+
+ /* until we get the last byte, keep decoding 7 bits at a time */
+ while ( ((v = fgetc(in)) & 0x80) == 0 && v!=EOF) {
+ value |= v;
+ value <<= 7;
+ }
+ if (v == EOF) {
+ *dest = value>>7;
+ return 01;
+ }
+ *dest = value | (v&0x7f);
+ return 0;
+}
+
+int
+camel_folder_summary_encode_fixed_int32(FILE *out, gint32 value)
+{
+ guint32 save;
+
+ save = htonl(value);
+ return fwrite(&save, sizeof(save), 1, out);
+}
+
+int
+camel_folder_summary_decode_fixed_int32(FILE *in, gint32 *dest)
+{
+ guint32 save;
+
+ if (fread(&save, sizeof(save), 1, in) != -1) {
+ *dest = ntohl(save);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/* should be sorted, for binary search */
+/* This is a tokenisation mechanism for strings written to the
+ summary - to save space.
+ This list can have at most 31 words. */
+static char * tokens[] = {
+ "7bit",
+ "8bit",
+ "alternative",
+ "application",
+ "base64",
+ "boundary",
+ "charset",
+ "filename",
+ "html",
+ "image",
+ "iso-8859-1",
+ "iso-8859-8",
+ "message",
+ "mixed",
+ "multipart",
+ "name",
+ "octet-stream",
+ "parallel",
+ "plain",
+ "quoted-printable",
+ "rfc822",
+ "text",
+ "us-ascii", /* 23 words */
+};
+
+#define tokens_len (sizeof(tokens)/sizeof(tokens[0]))
+
+/* baiscally ...
+ 0 = null
+ 1-tokens_len == tokens[id-1]
+ >=32 string, length = n-32
+*/
+
+int
+camel_folder_summary_encode_token(FILE *out, char *str)
+{
+ if (str == NULL) {
+ return camel_folder_summary_encode_uint32(out, 0);
+ } else {
+ int len = strlen(str);
+ int i, token=-1;
+
+ if (len <= 16) {
+ char lower[32];
+
+ for (i=0;i<len;i++)
+ lower[i] = tolower(str[i]);
+ lower[i] = 0;
+ for (i=0;i<tokens_len;i++) {
+ if (!strcmp(tokens[i], lower)) {
+ token = i;
+ break;
+ }
+ }
+ }
+ if (token != -1) {
+ return camel_folder_summary_encode_uint32(out, token+1);
+ } else {
+ if (camel_folder_summary_encode_uint32(out, len+32) == -1)
+ return -1;
+ return fwrite(str, len, 1, out);
+ }
+ }
+ return 0;
+}
+
+int
+camel_folder_summary_decode_token(FILE *in, char **str)
+{
+ char *ret;
+ int len;
+
+ if (camel_folder_summary_decode_uint32(in, &len) == -1) {
+ *str = NULL;
+ return -1;
+ }
+
+ if (len<32) {
+ if (len <= 0) {
+ ret = NULL;
+ } else if (len<= tokens_len) {
+ ret = g_strdup(tokens[len-1]);
+ } else {
+ g_warning("Invalid token encountered: %d", len);
+ *str = NULL;
+ return -1;
+ }
+ } else if (len > 10240) {
+ g_warning("Got broken string header length: %d bytes", len);
+ *str = NULL;
+ return -1;
+ } else {
+ len -= 32;
+ ret = g_malloc(len+1);
+ if (fread(ret, len, 1, in) == -1) {
+ g_free(ret);
+ *str = NULL;
+ return -1;
+ }
+ ret[len]=0;
+ }
+
+ *str = ret;
+ return 0;
+}
+
+int
+camel_folder_summary_encode_string(FILE *out, char *str)
+{
+ register int len;
+
+ if (str == NULL)
+ return camel_folder_summary_encode_uint32(out, 0);
+
+ len = strlen(str);
+ if (camel_folder_summary_encode_uint32(out, len+1) == -1)
+ return -1;
+ return fwrite(str, len, 1, out);
+}
+
+
+int
+camel_folder_summary_decode_string(FILE *in, char **str)
+{
+ int len;
+ register char *ret;
+
+ if (camel_folder_summary_decode_uint32(in, &len) == -1) {
+ *str = NULL;
+ return -1;
+ }
+
+ len--;
+ if (len < 0) {
+ *str = NULL;
+ return -1;
+ }
+
+ ret = g_malloc(len+1);
+ if (fread(ret, len, 1, in) == -1) {
+ g_free(ret);
+ *str = NULL;
+ return -1;
+ }
+
+ ret[len] = 0;
+ *str = ret;
+ return 0;
+}
+
+void
+camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset)
+{
+ content->pos += offset;
+ content->bodypos += offset;
+ content->endpos += offset;
+ content = content->childs;
+ while (content) {
+ camel_folder_summary_offset_content(content, offset);
+ content = content->next;
+ }
+}
+
+static struct _node *
+my_list_append(struct _node **list, struct _node *n)
+{
+ struct _node *ln = (struct _node *)list;
+ while (ln->next)
+ ln = ln->next;
+ n->next = 0;
+ ln->next = n;
+ return n;
+}
+
+static int
+my_list_size(struct _node **list)
+{
+ int len = 0;
+ struct _node *ln = (struct _node *)list;
+ while (ln->next) {
+ ln = ln->next;
+ len++;
+ }
+ return len;
+}
+
+static int
+summary_header_load(CamelFolderSummary *s, FILE *in)
+{
+ guint32 version, flags, nextuid, count;
+ time_t time;
+
+ fseek(in, 0, SEEK_SET);
+
+ if (camel_folder_summary_decode_fixed_int32(in, &version) == -1
+ || camel_folder_summary_decode_fixed_int32(in, &flags) == -1
+ || camel_folder_summary_decode_fixed_int32(in, &nextuid) == -1
+ || camel_folder_summary_decode_fixed_int32(in, &time) == -1 /* TODO: yes i know this warns, to be fixed later */
+ || camel_folder_summary_decode_fixed_int32(in, &count) == -1) {
+ return -1;
+ }
+
+ s->nextuid = nextuid;
+ s->flags = flags;
+ s->time = time;
+ s->saved_count = count;
+ if (s->version != version) {
+ g_warning("Summary header version mismatch");
+ return -1;
+ }
+ return 0;
+}
+
+static int
+summary_header_save(CamelFolderSummary *s, FILE *out)
+{
+ fseek(out, 0, SEEK_SET);
+
+ camel_folder_summary_encode_fixed_int32(out, s->version);
+ camel_folder_summary_encode_fixed_int32(out, s->flags);
+ camel_folder_summary_encode_fixed_int32(out, s->nextuid);
+ camel_folder_summary_encode_fixed_int32(out, s->time);
+ return camel_folder_summary_encode_fixed_int32(out, camel_folder_summary_count(s));
+}
+
+/* are these even useful for anything??? */
+static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
+{
+ CamelMessageInfo *mi = NULL;
+ int state;
+
+ state = camel_mime_parser_state(mp);
+ switch (state) {
+ case HSCAN_HEADER:
+ case HSCAN_MESSAGE:
+ case HSCAN_MULTIPART:
+ mi = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->message_info_new(s, camel_mime_parser_headers_raw(mp));
+ break;
+ default:
+ g_error("Invalid parser state");
+ }
+
+ return mi;
+}
+
+static CamelMessageContentInfo * content_info_new_from_parser(CamelFolderSummary *s, CamelMimeParser *mp)
+{
+ CamelMessageContentInfo *ci = NULL;
+
+ switch (camel_mime_parser_state(mp)) {
+ case HSCAN_HEADER:
+ case HSCAN_MESSAGE:
+ case HSCAN_MULTIPART:
+ ci = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->content_info_new(s, camel_mime_parser_headers_raw(mp));
+ if (ci) {
+ ci->type = camel_mime_parser_content_type(mp);
+ header_content_type_ref(ci->type);
+ }
+ break;
+ default:
+ g_error("Invalid parser state");
+ }
+
+ return ci;
+}
+
+static char *
+summary_format_address(struct _header_raw *h, const char *name)
+{
+ struct _header_address *addr;
+ const char *text;
+ char *ret;
+
+ text = header_raw_find(&h, name, NULL);
+ addr = header_address_decode(text);
+ if (addr) {
+ ret = header_address_list_format(addr);
+ header_address_list_clear(&addr);
+ } else {
+ ret = g_strdup(text);
+ }
+ return ret;
+}
+
+static CamelMessageInfo *
+message_info_new(CamelFolderSummary *s, struct _header_raw *h)
+{
+ CamelMessageInfo *mi;
+
+ mi = g_malloc0(s->message_info_size);
+
+ mi->subject = header_decode_string(header_raw_find(&h, "subject", NULL));
+ mi->from = summary_format_address(h, "from");
+ mi->to = summary_format_address(h, "to");
+ mi->date_sent = header_decode_date(header_raw_find(&h, "date", NULL), NULL);
+ mi->date_received = 0;
+
+ return mi;
+}
+
+
+static CamelMessageInfo *
+message_info_load(CamelFolderSummary *s, FILE *in)
+{
+ guint32 tmp;
+ CamelMessageInfo *mi;
+
+ mi = g_malloc0(s->message_info_size);
+
+ camel_folder_summary_decode_uint32(in, &tmp);
+ mi->uid = g_strdup_printf("%u", tmp);
+ camel_folder_summary_decode_uint32(in, &mi->flags);
+ camel_folder_summary_decode_uint32(in, &mi->date_sent); /* warnings, leave them here */
+ camel_folder_summary_decode_uint32(in, &mi->date_received);
+/* ms->xev_offset = camel_folder_summary_decode_uint32(in);*/
+ camel_folder_summary_decode_string(in, &mi->subject);
+ camel_folder_summary_decode_string(in, &mi->from);
+ camel_folder_summary_decode_string(in, &mi->to);
+ mi->content = NULL;
+
+ return mi;
+}
+
+static int
+message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
+{
+ camel_folder_summary_encode_uint32(out, strtoul(mi->uid, NULL, 10));
+ camel_folder_summary_encode_uint32(out, mi->flags);
+ camel_folder_summary_encode_uint32(out, mi->date_sent);
+ camel_folder_summary_encode_uint32(out, mi->date_received);
+/* camel_folder_summary_encode_uint32(out, ms->xev_offset);*/
+ camel_folder_summary_encode_string(out, mi->subject);
+ camel_folder_summary_encode_string(out, mi->from);
+ return camel_folder_summary_encode_string(out, mi->to);
+}
+
+static void
+message_info_free(CamelFolderSummary *s, CamelMessageInfo *mi)
+{
+ g_free(mi->uid);
+ g_free(mi->subject);
+ g_free(mi->from);
+ g_free(mi->to);
+ g_free(mi);
+}
+
+static CamelMessageContentInfo *
+content_info_new(CamelFolderSummary *s, struct _header_raw *h)
+{
+ CamelMessageContentInfo *ci;
+
+ ci = g_malloc0(s->content_info_size);
+
+ ci->id = header_msgid_decode(header_raw_find(&h, "content-id", NULL));
+ ci->description = header_decode_string(header_raw_find(&h, "content-description", NULL));
+ ci->encoding = header_content_encoding_decode(header_raw_find(&h, "content-transfer-encoding", NULL));
+
+ ci->pos = -1;
+ ci->bodypos = -1;
+ ci->endpos = -1;
+ return ci;
+}
+
+static CamelMessageContentInfo *
+content_info_load(CamelFolderSummary *s, FILE *in)
+{
+ CamelMessageContentInfo *ci;
+ char *type, *subtype;
+ guint32 count, i;
+ struct _header_content_type *ct;
+
+ ci = g_malloc0(s->content_info_size);
+
+/* bs->pos = decode_int(in);
+ bs->bodypos = bs->pos + decode_int(in);
+ bs->endpos = bs->pos + decode_int(in);*/
+
+ camel_folder_summary_decode_token(in, &type);
+ camel_folder_summary_decode_token(in, &subtype);
+ ct = header_content_type_new(type, subtype);
+ g_free(type); /* can this be removed? */
+ g_free(subtype);
+ camel_folder_summary_decode_uint32(in, &count);
+ for (i=0;i<count;i++) {
+ char *name, *value;
+ camel_folder_summary_decode_token(in, &name);
+ camel_folder_summary_decode_token(in, &value);
+ header_content_type_set_param(ct, name, value);
+ /* TODO: do this so we dont have to double alloc/free */
+ g_free(name);
+ g_free(value);
+ }
+ ci->type = ct;
+
+ camel_folder_summary_decode_token(in, &ci->id);
+ camel_folder_summary_decode_token(in, &ci->description);
+ camel_folder_summary_decode_token(in, &ci->encoding);
+
+ ci->childs = NULL;
+ return ci;
+}
+
+static int
+content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *ci)
+{
+ struct _header_content_type *ct;
+ struct _header_param *hp;
+
+/* camel_folder_summary_encode_uint32(out, bs->pos);
+ camel_folder_summary_encode_uint32(out, bs->bodypos - bs->pos);
+ camel_folder_summary_encode_uint32(out, bs->endpos - bs->pos);*/
+
+ ct = ci->type;
+ if (ct) {
+ camel_folder_summary_encode_token(out, ct->type);
+ camel_folder_summary_encode_token(out, ct->subtype);
+ camel_folder_summary_encode_uint32(out, my_list_size((struct _node **)&ct->params));
+ hp = ct->params;
+ while (hp) {
+ camel_folder_summary_encode_token(out, hp->name);
+ camel_folder_summary_encode_token(out, hp->value);
+ hp = hp->next;
+ }
+ } else {
+ camel_folder_summary_encode_token(out, NULL);
+ camel_folder_summary_encode_token(out, NULL);
+ camel_folder_summary_encode_uint32(out, 0);
+ }
+ camel_folder_summary_encode_token(out, ci->id);
+ camel_folder_summary_encode_token(out, ci->description);
+ return camel_folder_summary_encode_token(out, ci->encoding);
+}
+
+static void
+content_info_free(CamelFolderSummary *s, CamelMessageContentInfo *ci)
+{
+ header_content_type_unref(ci->type);
+ g_free(ci->id);
+ g_free(ci->description);
+ g_free(ci->encoding);
+ g_free(ci);
+}
+
+/*
+ OK
+ Now this is where all the "smarts" happen, where the content info is built,
+ and any indexing and what not is performed
+*/
+
+static CamelMessageContentInfo *
+summary_build_content_info(CamelFolderSummary *s, CamelMimeParser *mp)
+{
+ int state, len;
+ char *buffer;
+ CamelMessageContentInfo *info = NULL;
+ struct _header_content_type *ct;
+ int start, body;
+ int enc_id = -1, chr_id = -1, idx_id = -1;
+ struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+ CamelMimeFilterCharset *mfc;
+ CamelMessageContentInfo *part;
+
+ /* start of this part */
+ start = camel_mime_parser_tell(mp);
+ state = camel_mime_parser_step(mp, &buffer, &len);
+ body = camel_mime_parser_tell(mp);
+
+ info = ((CamelFolderSummaryClass *)((GtkObject *)s)->klass)->content_info_new_from_parser(s, mp);
+
+ info->pos = start;
+ info->bodypos = body;
+
+ switch(state) {
+ case HSCAN_HEADER:
+ /* check content type for indexing, then read body */
+ ct = camel_mime_parser_content_type(mp);
+ if (p->index && header_content_type_is(ct, "text", "*")) {
+ char *encoding;
+ const char *charset;
+
+ encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
+ if (encoding) {
+ if (!strcasecmp(encoding, "base64")) {
+ if (p->filter_64 == NULL)
+ p->filter_64 = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
+ enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_64);
+ } else if (!strcasecmp(encoding, "quoted-printable")) {
+ if (p->filter_qp == NULL)
+ p->filter_qp = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
+ enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_qp);
+ }
+ g_free(encoding);
+ }
+
+ charset = header_content_type_param(ct, "charset");
+ if (charset!=NULL
+ && !(strcasecmp(charset, "us-ascii")==0
+ || strcasecmp(charset, "utf-8")==0)) {
+ d(printf("Adding conversion filter from %s to utf-8\n", charset));
+ mfc = g_hash_table_lookup(p->filter_charset, charset);
+ if (mfc == NULL) {
+ mfc = camel_mime_filter_charset_new_convert(charset, "utf-8");
+ if (mfc)
+ g_hash_table_insert(p->filter_charset, g_strdup(charset), mfc);
+ }
+ if (mfc) {
+ chr_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mfc);
+ } else {
+ g_warning("Cannot convert '%s' to 'utf-8', message index may be corrupt", charset);
+ }
+ }
+
+ /* and this filter actually does the indexing */
+ idx_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)p->filter_index);
+ }
+ /* and scan/index everything */
+ while (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_BODY_END)
+ ;
+ /* and remove the filters */
+ camel_mime_parser_filter_remove(mp, enc_id);
+ camel_mime_parser_filter_remove(mp, chr_id);
+ camel_mime_parser_filter_remove(mp, idx_id);
+ break;
+ case HSCAN_MULTIPART:
+ while (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_MULTIPART_END) {
+ camel_mime_parser_unstep(mp);
+ part = summary_build_content_info(s, mp);
+ if (part) {
+ part->parent = info;
+ my_list_append((struct _node **)&info->childs, (struct _node *)part);
+ } else {
+ g_error("Parsing failed: could not build part of a multipart");
+ }
+ }
+ break;
+ case HSCAN_MESSAGE:
+ part = summary_build_content_info(s, mp);
+ if (part) {
+ part->parent = info;
+ my_list_append((struct _node **)&info->childs, (struct _node *)part);
+ } else {
+ g_error("Parsing failed: no content of a message?");
+ }
+ if (!(state == HSCAN_MESSAGE_END)) {
+ g_error("Bad parser state: Expecing MESSAGE_END or MESSAGE_EOF, got: %d", state);
+ camel_mime_parser_unstep(mp);
+ }
+ break;
+ }
+
+ info->endpos = camel_mime_parser_tell(mp);
+
+ return info;
+}
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
new file mode 100644
index 0000000000..69045d6931
--- /dev/null
+++ b/camel/camel-folder-summary.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2000 Helix Code Inc.
+ *
+ * Authors: Michael Zucchi <notzed@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifndef _CAMEL_FOLDER_SUMMARY_H
+#define _CAMEL_FOLDER_SUMMARY_H
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <time.h>
+#include <camel/camel-mime-parser.h>
+#include <libibex/ibex.h>
+
+#define CAMEL_FOLDER_SUMMARY(obj) GTK_CHECK_CAST (obj, camel_folder_summary_get_type (), CamelFolderSummary)
+#define CAMEL_FOLDER_SUMMARY_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass)
+#define IS_CAMEL_FOLDER_SUMMARY(obj) GTK_CHECK_TYPE (obj, camel_folder_summary_get_type ())
+
+/*typedef struct _CamelFolderSummary CamelFolderSummary;*/
+typedef struct _CamelFolderSummaryClass CamelFolderSummaryClass;
+
+/* these structs from camel-folder-summary.h ... (remove comment after cleanup soon) */
+/* TODO: perhaps they should be full-block objects? */
+/* FIXME: rename this to something more suitable */
+typedef struct {
+ gchar *name;
+ gint nb_message; /* ick, these should be renamed to something better */
+ gint nb_unread_message;
+ gint nb_deleted_message;
+} CamelFolderInfo;
+
+/* A tree of message content info structures
+ describe the content structure of the message (if it has any) */
+typedef struct _CamelMessageContentInfo {
+ struct _CamelMessageContentInfo *next;
+
+ struct _CamelMessageContentInfo *childs;
+ struct _CamelMessageContentInfo *parent;
+
+ struct _header_content_type *type;
+ char *id;
+ char *description;
+ char *encoding;
+
+ /* information about where this object lives in the stream.
+ if pos is -1 these are all invalid */
+ off_t pos;
+ off_t bodypos;
+ off_t endpos;
+} CamelMessageContentInfo;
+
+/* information about a given object */
+typedef struct {
+ /* public fields */
+ gchar *subject;
+ gchar *to;
+ gchar *from;
+
+ gchar *uid;
+ guint32 flags;
+ guint32 size;
+
+ time_t date_sent;
+ time_t date_received;
+
+ /* tree of content description - NULL if it is not available */
+ CamelMessageContentInfo *content;
+} CamelMessageInfo;
+
+enum _CamelFolderSummaryFlags {
+ CAMEL_SUMMARY_DIRTY = 1<<0,
+};
+
+struct _CamelFolderSummary {
+ GtkObject parent;
+
+ struct _CamelFolderSummaryPrivate *priv;
+
+ /* header info */
+ guint32 version; /* version of file required, should be set by implementors */
+ guint32 flags; /* flags */
+ guint32 nextuid; /* next uid? */
+ guint32 saved_count; /* how many were saved/loaded */
+ time_t time; /* timestamp for this summary */
+
+ /* sizes of memory objects */
+ guint32 message_info_size;
+ guint32 content_info_size;
+
+ char *summary_path;
+ gboolean build_content; /* do we try and parse/index the content, or not? */
+
+ GPtrArray *messages; /* CamelMessageInfo's */
+ GHashTable *messages_uid; /* CamelMessageInfo's by uid */
+};
+
+struct _CamelFolderSummaryClass {
+ GtkObjectClass parent_class;
+
+ /* load/save the global info */
+ int (*summary_header_load)(CamelFolderSummary *, FILE *);
+ int (*summary_header_save)(CamelFolderSummary *, FILE *);
+
+ /* create/save/load an individual message info */
+ CamelMessageInfo * (*message_info_new)(CamelFolderSummary *, struct _header_raw *);
+ CamelMessageInfo * (*message_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
+ CamelMessageInfo * (*message_info_load)(CamelFolderSummary *, FILE *);
+ int (*message_info_save)(CamelFolderSummary *, FILE *, CamelMessageInfo *);
+ void (*message_info_free)(CamelFolderSummary *, CamelMessageInfo *);
+
+ /* save/load individual content info's */
+ CamelMessageContentInfo * (*content_info_new)(CamelFolderSummary *, struct _header_raw *);
+ CamelMessageContentInfo * (*content_info_new_from_parser)(CamelFolderSummary *, CamelMimeParser *);
+ CamelMessageContentInfo * (*content_info_load)(CamelFolderSummary *, FILE *);
+ int (*content_info_save)(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
+ void (*content_info_free)(CamelFolderSummary *, CamelMessageContentInfo *);
+};
+
+guint camel_folder_summary_get_type (void);
+CamelFolderSummary *camel_folder_summary_new (void);
+
+void camel_folder_summary_set_filename(CamelFolderSummary *, const char *);
+void camel_folder_summary_set_index(CamelFolderSummary *, ibex *);
+void camel_folder_summary_set_uid(CamelFolderSummary *, guint32);
+void camel_folder_summary_set_build_content(CamelFolderSummary *, gboolean state);
+
+guint32 camel_folder_summary_next_uid(CamelFolderSummary *s);
+
+/* load/save the summary in its entirety */
+int camel_folder_summary_load(CamelFolderSummary *);
+int camel_folder_summary_save(CamelFolderSummary *);
+
+/* add a new raw summary item */
+void camel_folder_summary_add(CamelFolderSummary *, CamelMessageInfo *info);
+void camel_folder_summary_add_from_header(CamelFolderSummary *, struct _header_raw *);
+void camel_folder_summary_add_from_parser(CamelFolderSummary *, CamelMimeParser *);
+
+/* removes a summary item, fixes offsets? */
+void camel_mbox_summary_remove_uid(CamelFolderSummary *s, const char *uid);
+
+/* lookup functions */
+int camel_folder_summary_count(CamelFolderSummary *);
+CamelMessageInfo *camel_folder_summary_index(CamelFolderSummary *, int);
+CamelMessageInfo *camel_folder_summary_uid(CamelFolderSummary *, const char *uid);
+
+/* utility functions */
+void camel_folder_summary_set_flags_by_uid(CamelFolderSummary *s, const char *uid, guint32 flags);
+/* shift content ... */
+void camel_folder_summary_offset_content(CamelMessageContentInfo *content, off_t offset);
+
+/* summary file loading/saving helper functions */
+int camel_folder_summary_encode_fixed_int32(FILE *, gint32);
+int camel_folder_summary_decode_fixed_int32(FILE *, gint32 *);
+
+int camel_folder_summary_encode_uint32(FILE *, guint32);
+int camel_folder_summary_decode_uint32(FILE *, guint32 *);
+
+int camel_folder_summary_encode_string(FILE *, char *);
+int camel_folder_summary_decode_string(FILE *, char **);
+
+/* basically like strings, but certain keywords can be compressed and de-cased */
+int camel_folder_summary_encode_token(FILE *, char *);
+int camel_folder_summary_decode_token(FILE *, char **);
+
+#endif /* ! _CAMEL_FOLDER_SUMMARY_H */
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index 6455fbf77b..6188c35866 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -24,6 +24,7 @@
* USA
*/
#include <config.h>
+#include <string.h>
#include "camel-folder.h"
#include "camel-exception.h"
#include "camel-store.h"
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index 713b3ced5c..5cc379be3b 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -56,11 +56,8 @@ typedef enum {
} CamelFolderOpenMode;
-typedef void (*CamelFolderAsyncCallback) ();
+#warning old summary stuff to be removed!
-/* these structs from camel-folder-summary.h ... (remove comment after cleanup soon) */
-/* TODO: perhaps they should be full-block objects? */
-/* FIXME: rename this to something more suitable */
typedef struct {
gchar *name;
gint nb_message; /* ick, these should be renamed to something better */
@@ -82,10 +79,10 @@ typedef struct _CamelMessageContentInfo {
char *encoding;
guint32 size;
+
} CamelMessageContentInfo;
-/* TODO: rename this?? */
-/* TODO: Make this an object, maybe? */
+/* information about a given object */
typedef struct {
/* public fields */
gchar *subject;
@@ -98,11 +95,13 @@ typedef struct {
time_t date_sent;
time_t date_received;
- /* tree of content description */
+ /* tree of content description - NULL if it is not available */
CamelMessageContentInfo *content;
} CamelMessageInfo;
+typedef void (*CamelFolderAsyncCallback) ();
+
struct _CamelFolder
{
GtkObject parent_object;
diff --git a/camel/camel-mime-filter-index.c b/camel/camel-mime-filter-index.c
index 24c223d4e5..53a9f72920 100644
--- a/camel/camel-mime-filter-index.c
+++ b/camel/camel-mime-filter-index.c
@@ -163,4 +163,16 @@ void camel_mime_filter_index_set_name (CamelMimeFilterIndex *mf, char *name)
mf->name = g_strdup(name);
}
+void camel_mime_filter_index_set_ibex (CamelMimeFilterIndex *mf, ibex *index)
+{
+ if (mf->index) {
+ char *out;
+ size_t outlen, outspace;
+
+ camel_mime_filter_complete((CamelMimeFilter *)mf, "", 0, 0, &out, &outlen, &outspace);
+ }
+ mf->index = index;
+}
+
+
diff --git a/camel/camel-mime-filter-index.h b/camel/camel-mime-filter-index.h
index b4ea1966f0..f480fc55c7 100644
--- a/camel/camel-mime-filter-index.h
+++ b/camel/camel-mime-filter-index.h
@@ -53,5 +53,6 @@ CamelMimeFilterIndex *camel_mime_filter_index_new_ibex (ibex *);
/* Set the match name for any indexed words */
void camel_mime_filter_index_set_name (CamelMimeFilterIndex *, char *);
+void camel_mime_filter_index_set_ibex (CamelMimeFilterIndex *mf, ibex *index);
#endif /* ! _CAMEL_MIME_FILTER_INDEX_H */
diff --git a/camel/camel-mime-parser.c b/camel/camel-mime-parser.c
index 5417fffa3a..cf81eed25b 100644
--- a/camel/camel-mime-parser.c
+++ b/camel/camel-mime-parser.c
@@ -118,6 +118,7 @@ struct _header_scan_filter {
};
static void folder_scan_step(struct _header_scan_state *s, char **databuffer, int *datalength);
+static void folder_scan_drop_step(struct _header_scan_state *s);
static int folder_scan_init_with_fd(struct _header_scan_state *s, int fd);
static int folder_scan_init_with_stream(struct _header_scan_state *s, CamelStream *stream);
static struct _header_scan_state *folder_scan_init(void);
@@ -226,6 +227,22 @@ camel_mime_parser_new (void)
}
+/**
+ * camel_mime_parser_filter_add:
+ * @m:
+ * @mf:
+ *
+ * Add a filter that will be applied to any body content before it is passed
+ * to the caller. Filters may be pipelined to perform multi-pass operations
+ * on the content, and are applied in the order they were added.
+ *
+ * Note that filters are only applied to the body content of messages, and once
+ * a filter has been set, all content returned by a filter_step() with a state
+ * of HSCAN_BODY will have passed through the filter.
+ *
+ * Return value: An id that may be passed to filter_remove() to remove
+ * the filter, or -1 if the operation failed.
+ **/
int
camel_mime_parser_filter_add(CamelMimeParser *m, CamelMimeFilter *mf)
{
@@ -248,6 +265,14 @@ camel_mime_parser_filter_add(CamelMimeParser *m, CamelMimeFilter *mf)
return new->id;
}
+/**
+ * camel_mime_parser_filter_remove:
+ * @m:
+ * @id:
+ *
+ * Remove a processing filter from the pipeline. There is no
+ * restriction on the order the filters can be removed.
+ **/
void
camel_mime_parser_filter_remove(CamelMimeParser *m, int id)
{
@@ -268,6 +293,18 @@ camel_mime_parser_filter_remove(CamelMimeParser *m, int id)
}
}
+/**
+ * camel_mime_parser_header:
+ * @m:
+ * @name: Name of header.
+ * @offset: Pointer that can receive the offset of the header in
+ * the stream from the start of parsing.
+ *
+ * Lookup a header by name.
+ *
+ * Return value: The header value, or NULL if the header is not
+ * defined.
+ **/
const char *
camel_mime_parser_header(CamelMimeParser *m, const char *name, int *offset)
{
@@ -280,6 +317,17 @@ camel_mime_parser_header(CamelMimeParser *m, const char *name, int *offset)
return NULL;
}
+/**
+ * camel_mime_parser_headers_raw:
+ * @m:
+ *
+ * Get the list of the raw headers which are defined for the
+ * current state of the parser. These headers are valid
+ * until the next call to parser_step(), or parser_drop_step().
+ *
+ * Return value: The raw headers, or NULL if there are no headers
+ * defined for the current part or state.
+ **/
struct _header_raw *
camel_mime_parser_headers_raw(CamelMimeParser *m)
{
@@ -290,6 +338,21 @@ camel_mime_parser_headers_raw(CamelMimeParser *m)
return NULL;
}
+/**
+ * camel_mime_parser_init_with_fd:
+ * @m:
+ * @fd: A valid file descriptor.
+ *
+ * Initialise the scanner with an fd. The scanner's offsets
+ * will be relative to the current file position of the file
+ * descriptor. As a result, seekable descritors should
+ * be seeked using the parser seek functions.
+ *
+ * An initial buffer will be read from the file descriptor
+ * immediately, although no parsing will occur.
+ *
+ * Return value: Returns -1 on error.
+ **/
int
camel_mime_parser_init_with_fd(CamelMimeParser *m, int fd)
{
@@ -298,6 +361,21 @@ camel_mime_parser_init_with_fd(CamelMimeParser *m, int fd)
return folder_scan_init_with_fd(s, fd);
}
+/**
+ * camel_mime_parser_init_with_stream:
+ * @m:
+ * @stream:
+ *
+ * Initialise the scanner with a source stream. The scanner's
+ * offsets will be relative to the current file position of
+ * the stream. As a result, seekable streams should only
+ * be seeked using the parser seek function.
+ *
+ * An initial buffer will be read from the stream
+ * immediately, although no parsing will occur.
+ *
+ * Return value: -1 on error.
+ **/
int
camel_mime_parser_init_with_stream(CamelMimeParser *m, CamelStream *stream)
{
@@ -306,6 +384,17 @@ camel_mime_parser_init_with_stream(CamelMimeParser *m, CamelStream *stream)
return folder_scan_init_with_stream(s, stream);
}
+/**
+ * camel_mime_parser_scan_from:
+ * @m:
+ * @scan_from: #TRUE if the scanner should scan From lines.
+ *
+ * Tell the scanner if it should scan "^From " lines or not.
+ *
+ * If the scanner is scanning from lines, two additional
+ * states HSCAN_FROM and HSCAN_FROM_END will be returned
+ * to the caller during parsing.
+ **/
void
camel_mime_parser_scan_from(CamelMimeParser *m, int scan_from)
{
@@ -313,6 +402,16 @@ camel_mime_parser_scan_from(CamelMimeParser *m, int scan_from)
s->scan_from = scan_from;
}
+/**
+ * camel_mime_parser_content_type:
+ * @m:
+ *
+ * Get the content type defined in the current part.
+ *
+ * Return value: A content_type structure, or NULL if there
+ * is no content-type defined for this part of state of the
+ * parser.
+ **/
struct _header_content_type *
camel_mime_parser_content_type(CamelMimeParser *m)
{
@@ -325,6 +424,17 @@ camel_mime_parser_content_type(CamelMimeParser *m)
return NULL;
}
+/**
+ * camel_mime_parser_unstep:
+ * @m:
+ *
+ * Cause the last step operation to repeat itself. If this is
+ * called repeated times, then the same step will be repeated
+ * that many times.
+ *
+ * Note that it is not possible to scan back using this function,
+ * only to have a way of peeking the next state.
+ **/
void camel_mime_parser_unstep(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
@@ -332,6 +442,49 @@ void camel_mime_parser_unstep(CamelMimeParser *m)
s->unstep++;
}
+/**
+ * camel_mime_parser_drop_step:
+ * @m:
+ *
+ * Drop the last step call. This should only be used
+ * in conjunction with seeking of the stream as the
+ * stream may be in an undefined state relative to the
+ * state of the parser.
+ *
+ * Use this call with care.
+ **/
+void camel_mime_parser_drop_step(CamelMimeParser *m)
+{
+ struct _header_scan_state *s = _PRIVATE(m);
+
+ s->unstep = 0;
+ folder_scan_drop_step(s);
+}
+
+/**
+ * camel_mime_parser_step:
+ * @m:
+ * @databuffer: Pointer to accept a pointer to the data
+ * associated with this step (if any).
+ * @datalength: Pointer to accept a pointer to the data
+ * length associated with this step (if any).
+ *
+ * Parse the next part of the MIME message. If _unstep()
+ * has been called, then continue to return the same state
+ * for that many calls.
+ *
+ * If the step is HSCAN_BODY then the databuffer and datalength
+ * pointers will be setup to point to the internal data buffer
+ * of the scanner and may be processed as required. Any
+ * filters will have already been applied to this data.
+ *
+ * Refer to the state diagram elsewhere for a full listing of
+ * the states an application is gauranteed to get from the
+ * scanner.
+ *
+ * Return value: The current new state of the parser
+ * is returned.
+ **/
enum _header_state
camel_mime_parser_step(CamelMimeParser *m, char **databuffer, int *datalength)
{
@@ -349,6 +502,26 @@ camel_mime_parser_step(CamelMimeParser *m, char **databuffer, int *datalength)
return s->state;
}
+/**
+ * camel_mime_parser_tell:
+ * @m:
+ *
+ * Return the current scanning offset. The meaning of this
+ * value will depend on the current state of the parser.
+ *
+ * An incomplete listing of the states:
+ *
+ * HSCAN_INITIAL, The start of the current message.
+ * HSCAN_HEADER, HSCAN_MESSAGE, HSCAN_MULTIPART, the character
+ * position immediately after the end of the header.
+ * HSCAN_BODY, Position within the message of the start
+ * of the current data block.
+ * HSCAN_*_END, The position of the character starting
+ * the next section of the scan (the last position + 1 of
+ * the respective current state).
+ *
+ * Return value: See above.
+ **/
off_t camel_mime_parser_tell(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
@@ -356,6 +529,17 @@ off_t camel_mime_parser_tell(CamelMimeParser *m)
return folder_tell(s);
}
+/**
+ * camel_mime_parser_tell_start_headers:
+ * @m:
+ *
+ * Find out the position within the file of where the
+ * headers started, this is cached by the parser
+ * at the time.
+ *
+ * Return value: The header start position, or -1 if
+ * no headers were scanned in the current state.
+ **/
off_t camel_mime_parser_tell_start_headers(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
@@ -363,6 +547,16 @@ off_t camel_mime_parser_tell_start_headers(CamelMimeParser *m)
return s->start_of_headers;
}
+/**
+ * camel_mime_parser_tell_start_from:
+ * @m:
+ *
+ * If the parser is scanning From lines, then this returns
+ * the position of the start of the From line.
+ *
+ * Return value: The start of the from line, or -1 if there
+ * was no From line, or From lines are not being scanned.
+ **/
off_t camel_mime_parser_tell_start_from(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
@@ -370,24 +564,76 @@ off_t camel_mime_parser_tell_start_from(CamelMimeParser *m)
return s->start_of_from;
}
+/**
+ * camel_mime_parser_seek:
+ * @m:
+ * @off: Number of bytes to offset the seek by.
+ * @whence: SEEK_SET, SEEK_CUR, SEEK_END
+ *
+ * Reset the source position to a known value.
+ *
+ * Note that if the source stream/descriptor was not
+ * positioned at 0 to begin with, and an absolute seek
+ * is specified (whence != SEEK_CUR), then the seek
+ * position may not match the desired seek position.
+ *
+ * Return value: The new seek offset, or -1 on
+ * an error (for example, trying to seek on a non-seekable
+ * stream or file descriptor).
+ **/
off_t camel_mime_parser_seek(CamelMimeParser *m, off_t off, int whence)
{
struct _header_scan_state *s = _PRIVATE(m);
return folder_seek(s, off, whence);
}
+/**
+ * camel_mime_parser_state:
+ * @m:
+ *
+ * Get the current parser state.
+ *
+ * Return value: The current parser state.
+ **/
enum _header_state camel_mime_parser_state(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
return s->state;
}
+/**
+ * camel_mime_parser_stream:
+ * @m:
+ *
+ * Get the stream, if any, the parser has been initialised
+ * with. May be used to setup sub-streams, but should not
+ * be read from directly (without saving and restoring
+ * the seek position in between).
+ *
+ * Return value: The stream from _init_with_stream(), or NULL
+ * if the parser is reading from a file descriptor or is
+ * uninitialised.
+ **/
CamelStream *camel_mime_parser_stream(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
return s->stream;
}
+/**
+ * camel_mime_parser_fd:
+ * @m:
+ *
+ * Return the file descriptor, if any, the parser has been
+ * initialised with.
+ *
+ * Should not be read from unless the parser it to terminate,
+ * or the seek offset can be reset before the next parse
+ * step.
+ *
+ * Return value: The file descriptor or -1 if the parser
+ * is reading from a stream or has not been initialised.
+ **/
int camel_mime_parser_fd(CamelMimeParser *m)
{
struct _header_scan_state *s = _PRIVATE(m);
@@ -1022,7 +1268,7 @@ tail_recurse:
type = HSCAN_HEADER;
if ( (content = header_raw_find(&h->headers, "Content-Type", NULL))
&& (ct = header_content_type_decode(content))) {
- if (!g_strcasecmp(ct->type, "multipart")) {
+ if (!strcasecmp(ct->type, "multipart")) {
bound = header_content_type_param(ct, "boundary");
if (bound) {
d(printf("multipart, boundary = %s\n", bound));
@@ -1037,9 +1283,9 @@ tail_recurse:
/* header_raw_replace(&h->headers, "Content-Type", "text/plain", offset);*/
g_warning("Multipart with no boundary, treating as text/plain");
}
- } else if (!g_strcasecmp(ct->type, "message")) {
- if (!g_strcasecmp(ct->subtype, "rfc822")
- /*|| !g_strcasecmp(ct->subtype, "partial")*/) {
+ } else if (!strcasecmp(ct->type, "message")) {
+ if (!strcasecmp(ct->subtype, "rfc822")
+ /*|| !strcasecmp(ct->subtype, "partial")*/) {
type = HSCAN_MESSAGE;
}
}
@@ -1138,6 +1384,38 @@ tail_recurse:
return;
}
+/* drops the current state back one */
+static void
+folder_scan_drop_step(struct _header_scan_state *s)
+{
+ switch (s->state) {
+ case HSCAN_INITIAL:
+ case HSCAN_EOF:
+ return;
+
+ case HSCAN_FROM:
+ s->state = HSCAN_INITIAL;
+ folder_pull_part(s);
+ return;
+
+ case HSCAN_MESSAGE:
+ case HSCAN_HEADER:
+ case HSCAN_MULTIPART:
+
+ case HSCAN_FROM_END:
+ case HSCAN_BODY_END:
+ case HSCAN_MULTIPART_END:
+ case HSCAN_MESSAGE_END:
+
+ s->state = s->parts->savestate;
+ folder_pull_part(s);
+ if (s->state & HSCAN_END) {
+ s->state &= ~HSCAN_END;
+ }
+ return;
+ }
+}
+
#ifdef STANDALONE
int main(int argc, char **argv)
{
@@ -1182,7 +1460,7 @@ int main(int argc, char **argv)
case HSCAN_HEADER:
if (s->parts->content_type
&& (charset = header_content_type_param(s->parts->content_type, "charset"))) {
- if (g_strcasecmp(charset, "us-ascii")) {
+ if (strcasecmp(charset, "us-ascii")) {
folder_push_filter_charset(s, "UTF-8", charset);
} else {
charset = NULL;
diff --git a/camel/camel-mime-parser.h b/camel/camel-mime-parser.h
index f8964ed86c..cbc7b6095e 100644
--- a/camel/camel-mime-parser.h
+++ b/camel/camel-mime-parser.h
@@ -89,6 +89,7 @@ void camel_mime_parser_scan_from(CamelMimeParser *, int);
/* normal interface */
enum _header_state camel_mime_parser_step(CamelMimeParser *, char **, int *);
void camel_mime_parser_unstep(CamelMimeParser *);
+void camel_mime_parser_drop_step(CamelMimeParser *m);
enum _header_state camel_mime_parser_state(CamelMimeParser *);
/* get content type for the current part/header */
diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c
index ac2c81ad0a..fa914be960 100644
--- a/camel/camel-mime-part-utils.c
+++ b/camel/camel-mime-part-utils.c
@@ -71,11 +71,11 @@ simple_data_wrapper_construct_from_parser(CamelDataWrapper *dw, CamelMimeParser
/* first, work out conversion, if any, required, we dont care about what we dont know about */
encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
if (encoding) {
- if (!g_strcasecmp(encoding, "base64")) {
+ if (!strcasecmp(encoding, "base64")) {
d(printf("Adding base64 decoder ...\n"));
fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
decid = camel_mime_parser_filter_add(mp, fdec);
- } else if (!g_strcasecmp(encoding, "quoted-printable")) {
+ } else if (!strcasecmp(encoding, "quoted-printable")) {
d(printf("Adding quoted-printable decoder ...\n"));
fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
decid = camel_mime_parser_filter_add(mp, fdec);
@@ -88,8 +88,8 @@ simple_data_wrapper_construct_from_parser(CamelDataWrapper *dw, CamelMimeParser
if (header_content_type_is(ct, "text", "*")) {
const char *charset = header_content_type_param(ct, "charset");
if (charset!=NULL
- && !(g_strcasecmp(charset, "us-ascii")==0
- || g_strcasecmp(charset, "utf-8")==0)) {
+ && !(strcasecmp(charset, "us-ascii")==0
+ || strcasecmp(charset, "utf-8")==0)) {
d(printf("Adding conversion filter from %s to utf-8\n", charset));
fch = (CamelMimeFilter *)camel_mime_filter_charset_new_convert(charset, "utf-8");
if (fch) {
diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c
index 744f2a7247..bb3abe7062 100644
--- a/camel/camel-mime-part.c
+++ b/camel/camel-mime-part.c
@@ -606,13 +606,13 @@ camel_mime_part_encoding_from_string (const gchar *string)
{
if (string == NULL)
return CAMEL_MIME_PART_ENCODING_DEFAULT;
- else if (g_strcasecmp (string, "7bit") == 0)
+ else if (strcasecmp (string, "7bit") == 0)
return CAMEL_MIME_PART_ENCODING_7BIT;
- else if (g_strcasecmp (string, "8bit") == 0)
+ else if (strcasecmp (string, "8bit") == 0)
return CAMEL_MIME_PART_ENCODING_8BIT;
- else if (g_strcasecmp (string, "base64") == 0)
+ else if (strcasecmp (string, "base64") == 0)
return CAMEL_MIME_PART_ENCODING_BASE64;
- else if (g_strcasecmp (string, "quoted-printable") == 0)
+ else if (strcasecmp (string, "quoted-printable") == 0)
return CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE;
else
/* FIXME? Spit a warning? */
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index f53531feb7..3f4c4d99d3 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -808,7 +808,7 @@ char *rfc2047_encode_word(const char *in, int len, char *type)
out = buffer;
/* if we can't convert from utf-8, just encode as utf-8 */
- if (!g_strcasecmp(type, "UTF-8")
+ if (!strcasecmp(type, "UTF-8")
|| (ic = unicode_iconv_open(type, "UTF-8")) == (unicode_iconv_t)-1) {
memcpy(buffer, in, len);
out = buffer+len;
@@ -1065,7 +1065,7 @@ header_decode_param(const char **in, char **paramp, char **valuep)
char *
header_param(struct _header_param *p, const char *name)
{
- while (p && g_strcasecmp(p->name, name) != 0)
+ while (p && strcasecmp(p->name, name) != 0)
p = p->next;
if (p)
return p->value;
@@ -1079,7 +1079,7 @@ header_set_param(struct _header_param **l, const char *name, const char *value)
while (p->next) {
pn = p->next;
- if (!g_strcasecmp(pn->name, name)) {
+ if (!strcasecmp(pn->name, name)) {
g_free(pn->value);
if (value) {
pn->value = g_strdup(value);
@@ -1135,16 +1135,16 @@ header_content_type_is(struct _header_content_type *ct, const char *type, const
{
/* no type == text/plain or text/"*" */
if (ct==NULL) {
- return (!g_strcasecmp(type, "text")
- && (!g_strcasecmp(subtype, "plain")
- || !g_strcasecmp(subtype, "*")));
+ return (!strcasecmp(type, "text")
+ && (!strcasecmp(subtype, "plain")
+ || !strcasecmp(subtype, "*")));
}
return (ct->type != NULL
- && (!g_strcasecmp(ct->type, type)
+ && (!strcasecmp(ct->type, type)
&& ((ct->subtype != NULL
- && !g_strcasecmp(ct->subtype, subtype))
- || !g_strcasecmp("*", subtype))));
+ && !strcasecmp(ct->subtype, subtype))
+ || !strcasecmp("*", subtype))));
}
void
@@ -1660,7 +1660,7 @@ header_content_type_decode(const char *in)
inptr++;
subtype = decode_token(&inptr);
}
- if (subtype == NULL && (!g_strcasecmp(type, "text"))) {
+ if (subtype == NULL && (!strcasecmp(type, "text"))) {
g_warning("text type with no subtype, resorting to text/plain: %s", in);
subtype = g_strdup("plain");
}
@@ -1713,7 +1713,7 @@ header_content_type_format(struct _header_content_type *ct)
g_warning("Content-Type with no main type");
} else if (ct->subtype == NULL) {
g_warning("Content-Type with no sub type: %s", ct->type);
- if (!g_strcasecmp(ct->type, "multipart"))
+ if (!strcasecmp(ct->type, "multipart"))
g_string_sprintfa(out, "%s/mixed", ct->type);
else
g_string_sprintfa(out, "%s", ct->type);
@@ -1879,7 +1879,7 @@ header_decode_date(const char *in, int *saveoffset)
monthname = decode_token(&inptr);
if (monthname) {
for (i=0;i<sizeof(tz_months)/sizeof(tz_months[0]);i++) {
- if (!g_strcasecmp(tz_months[i], monthname)) {
+ if (!strcasecmp(tz_months[i], monthname)) {
tm.tm_mon = i;
break;
}
@@ -1916,7 +1916,7 @@ header_decode_date(const char *in, int *saveoffset)
if (tz) {
for (i=0;i<sizeof(tz_offsets)/sizeof(tz_offsets[0]);i++) {
- if (!g_strcasecmp(tz_offsets[i].name, tz)) {
+ if (!strcasecmp(tz_offsets[i].name, tz)) {
offset = tz_offsets[i].offset;
break;
}
@@ -2031,13 +2031,13 @@ header_raw_append(struct _header_raw **list, const char *name, const char *value
/* debug */
#if 0
- if (!g_strcasecmp(name, "To")) {
+ if (!strcasecmp(name, "To")) {
printf("- Decoding To\n");
header_to_decode(value);
- } else if (!g_strcasecmp(name, "Content-type")) {
+ } else if (!strcasecmp(name, "Content-type")) {
printf("- Decoding content-type\n");
header_content_type_dump(header_content_type_decode(value));
- } else if (!g_strcasecmp(name, "MIME-Version")) {
+ } else if (!strcasecmp(name, "MIME-Version")) {
printf("- Decoding mime version\n");
header_mime_decode(value);
}
@@ -2051,7 +2051,7 @@ header_raw_find_node(struct _header_raw **list, const char *name)
l = *list;
while (l) {
- if (!g_strcasecmp(l->name, name))
+ if (!strcasecmp(l->name, name))
break;
l = l->next;
}
@@ -2103,7 +2103,7 @@ header_raw_remove(struct _header_raw **list, const char *name)
p = (struct _header_raw *)list;
l = *list;
while (l) {
- if (!g_strcasecmp(l->name, name)) {
+ if (!strcasecmp(l->name, name)) {
p->next = l->next;
header_raw_free(l);
l = p->next;
diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c
index 01deaef19a..35b7945e49 100644
--- a/camel/providers/mbox/camel-mbox-summary.c
+++ b/camel/providers/mbox/camel-mbox-summary.c
@@ -595,7 +595,7 @@ header_write(int fd, struct _header_raw *header, unsigned int uid, unsigned int
iv[3].iov_len = 1;
while (header) {
- if (g_strcasecmp(header->name, "x-evolution")) {
+ if (strcasecmp(header->name, "x-evolution")) {
int len;
iv[0].iov_base = header->name;
@@ -876,12 +876,12 @@ static int index_folder(CamelMboxSummary *s, int startoffset)
messages/message parts */
encoding = header_content_encoding_decode(camel_mime_parser_header(mp, "content-transfer-encoding", NULL));
if (encoding) {
- if (!g_strcasecmp(encoding, "base64")) {
+ if (!strcasecmp(encoding, "base64")) {
d(printf("Adding decoding filter for base64\n"));
if (mf64 == NULL)
mf64 = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_DEC);
enc_id = camel_mime_parser_filter_add(mp, (CamelMimeFilter *)mf64);
- } else if (!g_strcasecmp(encoding, "quoted-printable")) {
+ } else if (!strcasecmp(encoding, "quoted-printable")) {
d(printf("Adding decoding filter for quoted-printable\n"));
if (mfqp == NULL)
mfqp = camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_DEC);
@@ -892,8 +892,8 @@ static int index_folder(CamelMboxSummary *s, int startoffset)
charset = header_content_type_param(ct, "charset");
if (charset!=NULL
- && !(g_strcasecmp(charset, "us-ascii")==0
- || g_strcasecmp(charset, "utf-8")==0)) {
+ && !(strcasecmp(charset, "us-ascii")==0
+ || strcasecmp(charset, "utf-8")==0)) {
d(printf("Adding conversion filter from %s to utf-8\n", charset));
if (mfc == NULL)
mfc = camel_mime_filter_charset_new_convert(charset, "utf-8");