aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorbertrand <bertrand@helixcode.com>2000-01-17 13:25:36 +0800
committerBertrand Guiheneuf <bertrand@src.gnome.org>2000-01-17 13:25:36 +0800
commit79cda322e2840620d98411c9d7ec9226c365b922 (patch)
tree5da152767dff8836c01d41f17cb9d3e2d7693c29 /camel/providers
parent21cc1d3aeeb1c2b44d1f2e40f39369f5ba8222a4 (diff)
downloadgsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar.gz
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar.bz2
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar.lz
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar.xz
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.tar.zst
gsoc2013-evolution-79cda322e2840620d98411c9d7ec9226c365b922.zip
A bunch of new funcs to handle x-evolution private header field.
2000-01-17 bertrand <bertrand@helixcode.com> * camel/providers/mbox/camel-mbox-utils.c (camel_mbox_write_xev): (copy_file_chunk): (camel_mbox_xev_write_header_content): (camel_mbox_xev_parse_header_content): (string_to_flag): (flag_to_string): (string_to_uid): (uid_to_string): A bunch of new funcs to handle x-evolution private header field. Various others modifications and fixes. svn path=/trunk/; revision=1576
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/mbox/Makefile.am6
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c3
-rw-r--r--camel/providers/mbox/camel-mbox-parser.c35
-rw-r--r--camel/providers/mbox/camel-mbox-parser.h10
-rw-r--r--camel/providers/mbox/camel-mbox-utils.c313
-rw-r--r--camel/providers/mbox/camel-mbox-utils.h59
6 files changed, 412 insertions, 14 deletions
diff --git a/camel/providers/mbox/Makefile.am b/camel/providers/mbox/Makefile.am
index 3943cd7a8c..247ce55f1d 100644
--- a/camel/providers/mbox/Makefile.am
+++ b/camel/providers/mbox/Makefile.am
@@ -14,12 +14,14 @@ INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir) \
libcamelmbox_la_SOURCES = \
camel-mbox-folder.c \
camel-mbox-store.c \
- camel-mbox-parser.c
+ camel-mbox-parser.c \
+ camel-mbox-utils.c
libcamelmboxinclude_HEADERS = \
camel-mbox-folder.h \
camel-mbox-store.h \
- camel-mbox-parser.h
+ camel-mbox-parser.h \
+ camel-mbox-utils.h
libcamelmbox_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index 674f56c193..c502a190fd 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -3,7 +3,7 @@
/*
*
- * Copyright (C) 1999 Bertrand Guiheneuf <bertrand@helixcode.com> .
+ * Copyright (C) 1999 Helix Code .
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -21,6 +21,7 @@
* USA
*/
+/* Author : Bertrand Guiheneuf <bertrand@helixcode.com> */
#include <config.h>
diff --git a/camel/providers/mbox/camel-mbox-parser.c b/camel/providers/mbox/camel-mbox-parser.c
index 2509a5a49a..87752be417 100644
--- a/camel/providers/mbox/camel-mbox-parser.c
+++ b/camel/providers/mbox/camel-mbox-parser.c
@@ -63,7 +63,7 @@
typedef struct {
int fd; /* file descriptor of the mbox file */
- guint real_position; /* real position in the file */
+ glong real_position; /* real position in the file */
gchar *message_delimiter; /* message delimiter string */
@@ -96,12 +96,20 @@ static void
clear_message_info (CamelMboxParserMessageInfo *preparsing_info)
{
preparsing_info->message_position = 0;
+ preparsing_info->size = 0;
preparsing_info->from = NULL;
preparsing_info->date = NULL;
preparsing_info->subject = NULL;
preparsing_info->status = NULL;
preparsing_info->priority = NULL;
preparsing_info->references = NULL;
+ preparsing_info->body_summary = NULL;
+ preparsing_info->end_of_headers_offset = 0;
+
+ preparsing_info->x_evolution = NULL;
+ preparsing_info->x_evolution_offset = 0;
+ /* reparsing_info->x_evolution_length = 0; */
+
}
@@ -153,7 +161,7 @@ new_parser (int fd,
* information array, i.e. the preparsed_messages
* field.
**/
-void
+static void
parser_free (CamelMboxPreParser *parser)
{
g_free (parser->buffer);
@@ -177,7 +185,7 @@ parser_free (CamelMboxPreParser *parser)
**/
static void
initialize_buffer (CamelMboxPreParser *parser,
- guint first_position)
+ glong first_position)
{
gint seek_res;
gint buf_nb_read;
@@ -390,7 +398,6 @@ new_message_detected (CamelMboxPreParser *parser)
* after the "\n" at the end of the header content.
*
**/
-*/
static void
read_header (CamelMboxPreParser *parser, gchar **header_content)
{
@@ -548,7 +555,7 @@ read_message_begining (CamelMboxPreParser *parser, gchar **message_summary)
GArray *
camel_mbox_parse_file (int fd,
const gchar *message_delimiter,
- guint start_position,
+ glong start_position,
gboolean get_message_summary,
camel_mbox_preparser_status_callback *status_callback,
double status_interval,
@@ -559,7 +566,7 @@ camel_mbox_parse_file (int fd,
gchar c;
struct stat stat_buf;
gint fstat_result;
- guint total_file_size;
+ glong total_file_size;
int last_status = 0;
int real_interval;
gboolean newline;
@@ -672,11 +679,20 @@ camel_mbox_parse_file (int fd,
MBOX_PARSER_X_EVOLUTION_KW,
MBOX_PARSER_X_EVOLUTION_KW_SZ) == 0) {
+ /* in the case of the evolution private field, we store
+ the field position as well as its length because
+ we will have to change them */
+ parser->current_message_info.x_evolution_offset = parser->real_position
+ - parser->current_message_info.message_position;
advance_n_chars (parser, MBOX_PARSER_X_EVOLUTION_KW_SZ);
read_header (parser, (gchar **) ((gchar *)parser +
G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info) +
G_STRUCT_OFFSET (CamelMboxParserMessageInfo, x_evolution)));
+ /*
+ parser->current_message_info.x_evolution_length =
+ parser->real_position - parser->current_message_info.x_evolution_position;
+ */
newline = TRUE;
continue;
}
@@ -687,6 +703,9 @@ camel_mbox_parse_file (int fd,
/* is it an empty line ? */
if (parser->buffer[parser->current_position] == '\n') {
+ parser->current_message_info.end_of_headers_offset =
+ parser->real_position - parser->current_message_info.message_position;
+
goto_next_char (parser);
if (get_message_summary)
newline = read_message_begining (parser, (gchar **) ((gchar *)parser +
@@ -708,9 +727,8 @@ camel_mbox_parse_file (int fd,
G_STRUCT_OFFSET (CamelMboxPreParser, current_message_info), 1);
}
-
-
return_value = parser->preparsed_messages;
+
/* free the parser */
parser_free (parser);
@@ -756,6 +774,7 @@ main (int argc, char **argv)
test_file_fd = open (argv[1], O_RDONLY);
message_positions = camel_mbox_parse_file (test_file_fd,
"From ",
+
0,
TRUE,
status,
diff --git a/camel/providers/mbox/camel-mbox-parser.h b/camel/providers/mbox/camel-mbox-parser.h
index b8d2e93dc6..a4b3af9aff 100644
--- a/camel/providers/mbox/camel-mbox-parser.h
+++ b/camel/providers/mbox/camel-mbox-parser.h
@@ -28,8 +28,8 @@
typedef struct {
- guint message_position;
- guint size;
+ glong message_position;
+ glong size;
gchar *from;
gchar *date;
gchar *subject;
@@ -37,7 +37,11 @@ typedef struct {
gchar *priority;
gchar *references;
gchar *body_summary;
+ gshort end_of_headers_offset;
+
gchar *x_evolution;
+ gshort x_evolution_offset;
+ /* gshort x_evolution_length; */
} CamelMboxParserMessageInfo;
@@ -48,7 +52,7 @@ typedef void camel_mbox_preparser_status_callback (double percentage_done, gpoin
GArray *
camel_mbox_parse_file (int fd,
const gchar *message_delimiter,
- guint start_position,
+ glong start_position,
gboolean get_message_summary,
camel_mbox_preparser_status_callback *status_callback,
double status_interval,
diff --git a/camel/providers/mbox/camel-mbox-utils.c b/camel/providers/mbox/camel-mbox-utils.c
new file mode 100644
index 0000000000..9eb4bd1f0d
--- /dev/null
+++ b/camel/providers/mbox/camel-mbox-utils.c
@@ -0,0 +1,313 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Various utilities for the mbox provider */
+
+/*
+ * Authors :
+ * Bertrand Guiheneuf <bertrand@helixcode.com>
+ *
+ * Copyright (C) 1999 Helix Code.
+ *
+ * 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
+ */
+
+
+/* "xev" stands for x-evolution, which is the name of the
+ * evolution specific header where are stored informations
+ * like :
+ * - mail status
+ * - mail uid
+ * ...
+ *
+ *
+ * The evolution line ha10s the following format :
+ *
+ * X-Evolution:XXXXX-X
+ * \___/ \/
+ * UID ---' `- Status
+ *
+ * the UID is internally used as a 32 bits long integer, but only the first 24 bits are
+ * used. The UID is coded as a string on 4 characters. Each character is a 6 bits
+ * integer coded using the b64 alphabet.
+ *
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#include <glib.h>
+#include "camel-mbox-utils.h"
+#include "camel-mbox-parser.h"
+
+
+
+static gchar b64_alphabet[64] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+
+
+static void
+uid_to_string (guint32 uid, gchar string[4])
+{
+
+ string [0] = b64_alphabet [(uid >> 18) & 0x3f];
+ string [1] = b64_alphabet [(uid >> 12) & 0x3f];
+ string [2] = b64_alphabet [(uid >> 6) & 0x3f];
+ string [3] = b64_alphabet [(uid ) & 0x3f];
+}
+
+
+static guint32
+string_to_uid (gchar *string)
+{
+ guint32 i;
+
+ i =
+ (((string [0] >= 97) ? ( string [0] - 71 ) :
+ ((string [0] >= 65) ? ( string [0] - 65 ) :
+ ((string [0] >= 48) ? ( string [0] + 4 ) :
+ ((string [0] == 43) ? 62 : 63 )))) << 18)
+
+ + (((string [1] >= 97) ? ( string [1] - 71 ) :
+ ((string [1] >= 65) ? ( string [1] - 65 ) :
+ ((string [1] >= 48) ? ( string [1] + 4 ) :
+ ((string [1] == 43) ? 62 : 63 )))) << 12)
+
+
+ + ((((string [2] >= 97) ? ( string [2] - 71 ) :
+ ((string [2] >= 65) ? ( string [2] - 65 ) :
+ ((string [2] >= 48) ? ( string [2] + 4 ) :
+ ((string [2] == 43) ? 62 : 63 ))))) << 6)
+
+
+ + (((string [3] >= 97) ? ( string [3] - 71 ) :
+ ((string [3] >= 65) ? ( string [3] - 65 ) :
+ ((string [3] >= 48) ? ( string [3] + 4 ) :
+ ((string [3] == 43) ? 62 : 63 )))));
+
+ return i;
+
+}
+
+
+static gchar
+flag_to_string (guchar status)
+{
+ return b64_alphabet [status & 0x3f];
+}
+
+
+static guchar
+string_to_flag (gchar string)
+{
+ return (string >= 97) ? ( string - 71 ) :
+ ((string >= 65) ? ( string - 65 ) :
+ ((string >= 48) ? ( string + 4 ) :
+ ((string == 43) ? 62 : 63 )));
+}
+
+
+
+
+
+void
+camel_mbox_xev_parse_header_content (gchar header_content[6],
+ guint32 *uid,
+ guchar status)
+{
+
+ /* we assume that the first 4 characters of the header content
+ are actually the uid stuff. If somebody messed with it ...
+ toooo bad.
+ */
+ *uid = string_to_uid (header_content);
+ status = string_to_flag (header_content[5]);
+}
+
+void
+camel_mbox_xev_write_header_content (gchar header_content[6],
+ guint32 uid,
+ guchar status)
+{
+ uid_to_string (uid, header_content);
+ header_content[5] = flag_to_string (status);
+ header_content[4] = '-';
+}
+
+
+
+
+
+
+static void
+copy_file_chunk (gint fd_src,
+ gint fd_dest,
+ glong nb_bytes,
+ CamelException *ex)
+{
+ gchar buffer [1000];
+ glong nb_to_read;
+ glong nb_read, v;
+
+
+ nb_to_read = nb_bytes;
+ while (nb_to_read > 0) {
+
+ do {
+ nb_read = read (fd_src, buffer, MAX (1000, nb_to_read));
+ } while (nb_read == -1 && errno == EINTR);
+
+ if (nb_read == -1) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
+ "could read from the mbox file");
+ return;
+ }
+
+
+ nb_to_read -= nb_read;
+
+ do {
+ v = write (fd_dest, buffer, nb_read);
+ } while (v == -1 && errno == EINTR);
+
+ if (v == -1) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
+ "could write to the mbox copy file");
+ return;
+ }
+
+
+ }
+
+
+
+}
+
+
+glong
+camel_mbox_write_xev (gchar *mbox_file_name,
+ GArray *summary_information,
+ glong next_uid,
+ CamelException *ex)
+{
+ gint cur_msg;
+ CamelMboxParserMessageInfo *cur_msg_info;
+ gint fd1, fd2;
+ guint bytes_to_copy = 0;
+ glong next_free_uid;
+ gchar xev_header[20] = "X-Evolution:XXXX-X\n";
+ gchar *tmp_file_name;
+ gchar *tmp_file_name_secure;
+ gint rename_result;
+ gint unlink_result;
+
+ 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_RDWR);
+
+ next_free_uid = next_uid;
+ for (cur_msg = 0; cur_msg < summary_information->len; cur_msg++) {
+
+ cur_msg_info = (CamelMboxParserMessageInfo *)(summary_information->data) + cur_msg;
+ if (cur_msg_info->x_evolution) {
+
+ bytes_to_copy += cur_msg_info->size;
+ } else {
+
+ bytes_to_copy += cur_msg_info->end_of_headers_offset;
+ copy_file_chunk (fd1, fd2, bytes_to_copy, ex);
+ if (camel_exception_get_id (ex)) {
+ close (fd1);
+ close (fd2);
+ goto end;
+ }
+
+ camel_mbox_xev_write_header_content (xev_header + 12, next_free_uid++, 0);
+ write (fd2, xev_header, 19);
+ bytes_to_copy = cur_msg_info->size - cur_msg_info->end_of_headers_offset;
+ cur_msg_info->size += 19;
+ cur_msg_info->x_evolution_offset = cur_msg_info->end_of_headers_offset;
+ cur_msg_info->x_evolution = g_strdup_printf ("%.6s", xev_header + 12);
+ cur_msg_info->end_of_headers_offset += 19;
+ }
+ }
+
+ if (bytes_to_copy > 0)
+ copy_file_chunk (fd1, fd2, bytes_to_copy, ex);
+
+
+ /* close the original file as well as the
+ newly created one */
+ close (fd1);
+ close (fd2);
+
+
+
+ /* replace the mbox file with the temporary
+ file we just created */
+
+ /* first rename the old mbox file to a temporary file */
+ rename_result = rename (mbox_file_name, tmp_file_name_secure);
+ if (rename_result == -1) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
+ "could not rename the mbox file to a temporary file");
+ goto end;
+ }
+
+ /* then rename the newly created mbox file to the name
+ of the original one */
+ rename_result = rename (tmp_file_name, mbox_file_name);
+ if (rename_result == -1) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
+ "could not rename the X-Evolution fed file to the mbox file");
+ goto end;
+ }
+
+ /* finally, remove the old renamed mbox file */
+ unlink_result = unlink (tmp_file_name_secure);
+ if (unlink_result == -1) {
+ camel_exception_set (ex,
+ CAMEL_EXCEPTION_FOLDER_INSUFFICIENT_PERMISSION,
+ "could not remove the saved original mbox file");
+ goto end;
+ }
+
+
+ end: /* free everything and return */
+
+ g_free (tmp_file_name);
+ g_free (tmp_file_name_secure);
+ return next_free_uid;
+}
+
+
+
+
+
+
+
+
diff --git a/camel/providers/mbox/camel-mbox-utils.h b/camel/providers/mbox/camel-mbox-utils.h
new file mode 100644
index 0000000000..cacabd2f19
--- /dev/null
+++ b/camel/providers/mbox/camel-mbox-utils.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Various utilities for the mbox provider */
+
+/*
+ * Authors :
+ * Bertrand Guiheneuf <bertrand@helixcode.com>
+ *
+ * Copyright (C) 1999 Helix Code.
+ *
+ * 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_MBOX_UTILS_H
+#define CAMEL_MBOX_UTILS_H 1
+
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus }*/
+
+
+#include "camel-exception.h"
+
+void
+camel_mbox_xev_parse_header_content (gchar header_content[6],
+ guint32 *uid,
+ guchar status);
+
+void
+camel_mbox_xev_write_header_content (gchar header_content[6],
+ guint32 uid,
+ guchar status);
+
+glong
+camel_mbox_write_xev (gchar *mbox_file_name,
+ GArray *summary_information,
+ glong last_uid,
+ CamelException *ex);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CAMEL_MBOX_UTILS_H */