aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2010-08-05 09:34:25 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2010-08-05 09:34:25 +0000
commit9b7007098c2b9f7c7243af0547c5743e45101077 (patch)
treede030439de3b197298967f32632bc66ab95bb88d /src
parent29d50219202f293966474cb1e823750ec32cf4a2 (diff)
implemented the import feature of Outlook Express mailboxes (dbx).
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2659 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src')
-rw-r--r--src/import.c180
1 files changed, 177 insertions, 3 deletions
diff --git a/src/import.c b/src/import.c
index 955d9982..b0a4c21c 100644
--- a/src/import.c
+++ b/src/import.c
@@ -1,6 +1,6 @@
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2010 Hiroyuki Yamamoto
*
* 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
@@ -41,6 +41,8 @@
#include <gtk/gtkprogressbar.h>
#include <gtk/gtkmenu.h>
+#include <stdio.h>
+
#include "main.h"
#include "inc.h"
#include "mbox.h"
@@ -59,7 +61,8 @@
enum
{
IMPORT_MBOX,
- IMPORT_EML_FOLDER
+ IMPORT_EML_FOLDER,
+ IMPORT_DBX
};
static GtkWidget *window;
@@ -80,6 +83,8 @@ static void import_create (void);
static gint import_do (void);
static gint import_eml_folder (FolderItem *dest,
const gchar *path);
+static gint import_dbx (FolderItem *dest,
+ const gchar *file);
static void import_format_menu_cb (GtkWidget *widget,
gpointer data);
@@ -180,7 +185,7 @@ static gint import_do(void)
filename = g_filename_from_utf8(utf8filename, -1, NULL, NULL, NULL);
if (!filename) {
- g_warning("faild to convert character set.");
+ g_warning("failed to convert character set.");
filename = g_strdup(utf8filename);
}
if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
@@ -219,6 +224,8 @@ static gint import_do(void)
folder_set_ui_func(dest->folder, NULL, NULL);
} else if (type == IMPORT_EML_FOLDER) {
ok = import_eml_folder(dest, filename);
+ } else if (type == IMPORT_DBX) {
+ ok = import_dbx(dest, filename);
}
progress_dialog_set_label(progress, _("Scanning folder..."));
@@ -291,6 +298,170 @@ static gint import_eml_folder(FolderItem *dest, const gchar *path)
return ok;
}
+static gint32 read_dword(FILE *fp, off_t offset)
+{
+ gint32 dw;
+
+ if (fseek(fp, offset, SEEK_SET) < 0) {
+ perror("read_dword: fseek");
+ return 0;
+ }
+
+ if (fread(&dw, sizeof(dw), 1, fp) != 1)
+ return 0;
+
+ dw = GINT32_FROM_LE(dw);
+
+ return dw;
+}
+
+static void get_dbx_index(FILE *fp, gint32 table_pos, GArray *array)
+{
+ gint32 another_pos, data_pos;
+ gint32 num_index, num_elems;
+ gint i;
+
+ debug_print("get_dbx_index(%08x)\n", table_pos);
+
+ another_pos = read_dword(fp, table_pos + 0x08);
+ num_elems = read_dword(fp, table_pos + 0x11) & 0x00ffffff;
+ num_index = read_dword(fp, table_pos + 0x14);
+ debug_print("table_pos: %08x another_pos: %08x num_elems: %08x num_index: %08x\n", table_pos, another_pos, num_elems, num_index);
+ if (another_pos > 0 && num_index > 0)
+ get_dbx_index(fp, another_pos, array);
+
+ table_pos += 0x18;
+ for (i = 0; i < num_elems; i++) {
+ data_pos = read_dword(fp, table_pos);
+ if (data_pos == 0) {
+ g_warning("get_dbx_index: null data_pos at %08x",
+ table_pos);
+ break;
+ }
+ g_array_append_val(array, data_pos);
+ another_pos = read_dword(fp, table_pos + 0x04);
+ num_index = read_dword(fp, table_pos + 0x08);
+ debug_print("data_pos: %08x another_pos: %08x num_index: %08x\n", data_pos, another_pos, num_index);
+ table_pos += 0x0c;
+ if (another_pos > 0 && num_index > 0)
+ get_dbx_index(fp, another_pos, array);
+ }
+
+ debug_print("get_dbx_index end\n");
+}
+
+static gint get_dbx_data(FILE *fp, gint32 data_pos, FolderItem *dest)
+{
+ gchar *tmp;
+ FILE *outfp;
+ gint32 mail_flag, news_flag;
+ gint32 data_ptr, data_len, next_ptr;
+ MsgFlags flags = {MSG_NEW|MSG_UNREAD, MSG_RECEIVED};
+ gint ok = 0;
+
+ debug_print("get_dbx_data(%08x)\n", data_pos);
+
+ mail_flag = read_dword(fp, data_pos + 0x18);
+ news_flag = read_dword(fp, data_pos + 0x1c);
+ if ((news_flag & 0x0f) == 4)
+ data_ptr = news_flag;
+ else if ((mail_flag & 0x0f) == 4)
+ data_ptr = mail_flag;
+ else
+ return 0;
+
+ if ((data_ptr & 0xff) >= 0x80)
+ data_ptr >>= 8;
+ else {
+ guchar b1 = (guchar)(data_ptr >>= 8);
+ guchar b2 = (guchar)read_dword(fp, data_pos + 0x0a);
+ data_ptr = read_dword(fp, data_pos + 0x0c + b2 * 4 + b1);
+ }
+ if (data_ptr == 0) {
+ g_warning("get_dbx_data(%08x): could not get data_ptr.", data_pos);
+ return 0;
+ }
+
+ tmp = get_tmp_file();
+ if ((outfp = g_fopen(tmp, "wb")) == NULL) {
+ FILE_OP_ERROR(tmp, "fopen");
+ ok = -1;
+ goto finish;
+ }
+
+ while (data_ptr) {
+ data_len = read_dword(fp, data_ptr + 0x08);
+ next_ptr = read_dword(fp, data_ptr + 0x0c);
+ if (append_file_part(fp, data_ptr + 0x10, data_len, outfp) < 0) {
+ fclose(outfp);
+ g_unlink(tmp);
+ ok = -1;
+ goto finish;
+ }
+ data_ptr = next_ptr;
+ }
+
+ if (fclose(outfp) == EOF) {
+ FILE_OP_ERROR(tmp, "fclose");
+ g_unlink(tmp);
+ ok = -1;
+ goto finish;
+ }
+
+ if (folder_item_add_msg(dest, tmp, &flags, TRUE) < 0) {
+ g_warning("get_dbx_data: folder_item_add_msg() failed.");
+ g_unlink(tmp);
+ ok = -1;
+ }
+
+finish:
+ g_free(tmp);
+ return ok;
+}
+
+static gint import_dbx(FolderItem *dest, const gchar *file)
+{
+ FILE *fp;
+ gint32 dw;
+ gint32 table_pos;
+ gint count = 0;
+ GArray *array;
+ gint i;
+
+ g_return_val_if_fail(dest != NULL, -1);
+ g_return_val_if_fail(file != NULL, -1);
+
+ if ((fp = g_fopen(file, "rb")) == NULL) {
+ FILE_OP_ERROR(file, "fopen");
+ return -1;
+ }
+
+ if ((dw = read_dword(fp, 0xc4)) == 0) {
+ fclose(fp);
+ return -1;
+ }
+
+ array = g_array_sized_new(FALSE, FALSE, sizeof(gint32), 1024);
+
+ table_pos = read_dword(fp, 0xe4);
+ if (table_pos > 0)
+ get_dbx_index(fp, table_pos, array);
+
+ for (i = 0; i < array->len; i++) {
+ proc_mbox_func(dest->folder, dest, GINT_TO_POINTER(count + 1));
+ if (get_dbx_data(fp, g_array_index(array, gint32, i), dest) < 0)
+ break;
+ count++;
+ }
+
+ debug_print("import_dbx: %d imported\n", count);
+
+ g_array_free(array, TRUE);
+ fclose(fp);
+
+ return 0;
+}
+
static void import_create(void)
{
GtkWidget *vbox;
@@ -358,6 +529,9 @@ static void import_create(void)
MENUITEM_ADD(menu, menuitem, _("eml (folder)"), IMPORT_EML_FOLDER);
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(import_format_menu_cb), NULL);
+ MENUITEM_ADD(menu, menuitem, _("Outlook Express (dbx)"), IMPORT_DBX);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(import_format_menu_cb), NULL);
gtk_option_menu_set_menu(GTK_OPTION_MENU(format_optmenu), menu);