diff options
Diffstat (limited to 'camel/providers/mbox/camel-mbox-utils.c')
-rw-r--r-- | camel/providers/mbox/camel-mbox-utils.c | 204 |
1 files changed, 194 insertions, 10 deletions
diff --git a/camel/providers/mbox/camel-mbox-utils.c b/camel/providers/mbox/camel-mbox-utils.c index 1b16941148..52f28b9fa6 100644 --- a/camel/providers/mbox/camel-mbox-utils.c +++ b/camel/providers/mbox/camel-mbox-utils.c @@ -58,8 +58,10 @@ #include "camel-mbox-utils.h" #include "camel-mbox-parser.h" #include "camel-mbox-summary.h" - - +#include "camel-mime-message.h" +#include "camel/camel-mime-part.h" +#include "camel/camel-multipart.h" +#include "camel/camel-stream-fs.h" static gchar b64_alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -209,9 +211,180 @@ camel_mbox_copy_file_chunk (gint fd_src, } +typedef void (*index_data_callback)(ibex *index, char *text, int len, int *left); + +/* + needs to handle encoding? +*/ +static void +index_text(ibex *index, char *text, int len, int *left) +{ + /*printf("indexing %.*s\n", len, text);*/ + + ibex_index_buffer(index, "message", text, len, left); +/* + if (left) { + printf("%d bytes left from indexing\n", *left); + } +*/ +} + +/* + index html data, ignore tags for now. + could also index attribute values? + should also handle encoding types ... + should convert everything to utf8 +*/ +static void +index_html(ibex *index, char *text, int len, int *left) +{ + static int state = 0; + char indexbuf[128]; + char *out = indexbuf, *outend = indexbuf+128; + char *in, *inend; + int c; + + in = text; + inend = text+len; + + /*printf("indexing html: %d %d %.*s\n", state, len, len, text);*/ + + while (in<inend) { + c = *in++; + switch (state) { + case 0: /* no tag */ + if (c=='<') + state = 1; + else { + *out++ = c; + if (out==outend) { + index_text(index, indexbuf, out-indexbuf, left); + memcpy(indexbuf, indexbuf+(out-indexbuf)-*left, *left); + out = indexbuf+*left; + printf("** %d bytes left\n", *left); + } + } + break; + case 1: + if (c=='>') + state = 0; +#if 0 + else if (c=='"') + state = 2; + break; + case 2: + if (c=='"') { + state = 1; + } +#endif + break; + } + } + index_text(index, indexbuf, out-indexbuf, left); +} + +static void +index_message_content(ibex *index, CamelDataWrapper *object) +{ + CamelDataWrapper *containee; + CamelStream *stream; + int parts, i; + int len; + int left; + char buffer[128]; + + containee = camel_medium_get_content_object(CAMEL_MEDIUM(object)); + + if (containee) { + char *type = gmime_content_field_get_mime_type(containee->mime_type); + index_data_callback callback = NULL; + + /*printf("type = %s\n", type);*/ + + if (!strcasecmp(type, "text/plain")) { + callback = index_text; + } else if (!strcasecmp(type, "text/html")) { + callback = index_html; + } else if (!strncasecmp(type, "multipart/", 10)) { + parts = camel_multipart_get_number (CAMEL_MULTIPART(containee)); + /*printf("multipart message, scanning contents %d parts ...\n", parts);*/ + for (i=0;i<parts;i++) { + index_message_content(index, camel_multipart_get_part(CAMEL_MULTIPART(containee), i)); + } + } else { + /*printf("\nunknwon format, ignored\n");*/ + } + + if (callback) { + int total=0; + + /*printf("reading containee\n"); + + printf("containee = %p\n", containee);*/ + + stream = camel_data_wrapper_get_output_stream(containee); + left = 0; + + if (stream) { + /*printf("stream = %p\n", stream);*/ + while ( (len = camel_stream_read(stream, buffer+left, sizeof(buffer)-left)) > 0) { + total = len+left; + callback(index, buffer, total, &left); + if (left>0) { + memcpy(buffer, buffer+total-left, left); + } + } + callback(index, buffer+total-left, left, NULL); + + /*camel_stream_close(stream);*/ + /*printf("\n");*/ + } else { + g_warning("cannot get stream for message?"); + } + } + + g_free(type); + } else { + printf("no containee?\n"); + } +} + + +static void +index_message(ibex *index, int fd, CamelMboxParserMessageInfo *mi) +{ + off_t pos; + CamelStream *stream; + CamelMimeMessage *message; + int newfd; + int i; + + if (index != NULL) { + /*printf("indexing message\n %s\n %d for %d bytes\n", mi->from, mi->message_position, mi->size);*/ + pos = lseek(fd, 0, SEEK_CUR); + + /* the stream will close the fd we have */ + newfd = dup(fd); + stream = camel_stream_fs_new_with_fd_and_bounds(newfd, mi->message_position, mi->message_position + mi->size); + message = camel_mime_message_new_with_session( (CamelSession *)NULL); + + camel_data_wrapper_set_input_stream ( + CAMEL_DATA_WRAPPER (message), stream); + + index_message_content(index, message); + + /* printf("messageid = '%s'\n", message->message_uid);*/ + + gtk_object_unref (message); + gtk_object_unref (GTK_OBJECT (stream)); + + lseek(fd, pos, SEEK_SET); + } +} guint32 -camel_mbox_write_xev (gchar *mbox_file_name, +camel_mbox_write_xev (CamelMboxFolder *folder, + gchar *mbox_file_name, GArray *summary_information, guint32 *file_size, guint32 next_uid, @@ -230,14 +403,15 @@ camel_mbox_write_xev (gchar *mbox_file_name, gchar *tmp_file_name_secure; gint rename_result; gint unlink_result; - + int changed = FALSE; + tmp_file_name = g_strdup_printf ("%s__.ev_tmp", mbox_file_name); tmp_file_name_secure = g_strdup_printf ("%s__.ev_tmp_secure", mbox_file_name); fd1 = open (mbox_file_name, O_RDONLY); fd2 = open (tmp_file_name, O_WRONLY | O_CREAT | O_TRUNC , - S_IRUSR | S_IWUSR, 0600); + 0600); if (fd2 == -1) { camel_exception_setv (ex, @@ -264,7 +438,11 @@ camel_mbox_write_xev (gchar *mbox_file_name, cur_pos = cur_msg_info->message_position + cur_msg_info->end_of_headers_offset; - + + cur_msg_info->uid = next_free_uid; + index_message(folder->index, fd1, cur_msg_info); + changed = TRUE; + camel_mbox_copy_file_chunk (fd1, fd2, bytes_to_copy, ex); if (camel_exception_get_id (ex)) { close (fd1); @@ -272,8 +450,8 @@ camel_mbox_write_xev (gchar *mbox_file_name, goto end; } - cur_msg_info->uid = next_free_uid; cur_msg_info->status = 0; + camel_mbox_xev_write_header_content (xev_header + 12, next_free_uid, 0); next_free_uid++; write (fd2, xev_header, 19); @@ -283,10 +461,16 @@ camel_mbox_write_xev (gchar *mbox_file_name, cur_msg_info->x_evolution = g_strdup_printf ("%.6s", xev_header + 12); cur_msg_info->end_of_headers_offset += 19; *file_size += 19; - } - cur_msg_info->message_position += cur_offset; + cur_msg_info->message_position += cur_offset; + } else { + cur_msg_info->message_position += cur_offset; + } + } + + /* make sure the index is in sync */ + if (changed) { + ibex_write(folder->index); } - bytes_to_copy = end_of_last_message - cur_pos; camel_mbox_copy_file_chunk (fd1, fd2, bytes_to_copy, ex); |