From 05636d92cf8083ccce3f8b24dd351b3c41aecd15 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Thu, 11 Dec 2003 01:41:27 +0000 Subject: Modified to simply copy mbox files from one place to another (and the 2003-12-10 Jeffrey Stedfast * em-migrate.c (em_migrate_dir): Modified to simply copy mbox files from one place to another (and the summary files) rather than going thru camel so as to bypass the need for parsing MIME. svn path=/trunk/; revision=23919 --- mail/ChangeLog | 6 ++ mail/em-migrate.c | 271 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 215 insertions(+), 62 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index dfe7aa34bc..a2db32a3b8 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -2,6 +2,12 @@ * em-format-html.c: add text/x-patch as a plain type. +2003-12-10 Jeffrey Stedfast + + * em-migrate.c (em_migrate_dir): Modified to simply copy mbox + files from one place to another (and the summary files) rather + than going thru camel so as to bypass the need for parsing MIME. + 2003-12-10 Jeffrey Stedfast * em-migrate.c (get_local_store): Fixed a leak. diff --git a/mail/em-migrate.c b/mail/em-migrate.c index a43cc8b4fd..a3efe4eb26 100644 --- a/mail/em-migrate.c +++ b/mail/em-migrate.c @@ -231,11 +231,10 @@ is_mail_folder (const char *metadata) return FALSE; } -static CamelStore * -get_local_store (CamelSession *session, const char *dirname, const char *metadata, char **namep, int *index, CamelException *ex) +static char * +get_local_store_uri (const char *dirname, const char *metadata, char **namep, int *index, CamelException *ex) { char *protocol, *name, *buf; - CamelStore *store; struct stat st; xmlNodePtr node; xmlDocPtr doc; @@ -274,15 +273,10 @@ get_local_store (CamelSession *session, const char *dirname, const char *metadat buf = g_strdup_printf ("%s:%s", protocol, dirname); xmlFree (protocol); - if ((store = camel_session_get_store (session, buf, ex))) - *namep = g_strdup (name); - else - *namep = NULL; - + *namep = g_strdup (name); xmlFree (name); - g_free (buf); - return store; + return buf; } node = node->next; @@ -295,6 +289,111 @@ get_local_store (CamelSession *session, const char *dirname, const char *metadat return NULL; } +static int +cp (const char *src, const char *dest, gboolean show_progress) +{ + unsigned char readbuf[4096]; + ssize_t nread, nwritten; + int errnosav, fd[2]; + size_t total = 0; + struct stat st; + + if (stat (src, &st) == -1) + return -1; + + if ((fd[0] = open (src, O_RDONLY)) == -1) + return -1; + + if ((fd[1] = open (dest, O_WRONLY | O_CREAT | O_APPEND, 0666)) == -1) { + errnosav = errno; + close (fd[0]); + errno = errnosav; + return -1; + } + + do { + do { + nread = read (fd[0], readbuf, sizeof (readbuf)); + } while (nread == -1 && errno == EINTR); + + if (nread == 0) + break; + else if (nread < 0) + goto exception; + + do { + nwritten = write (fd[1], readbuf, nread); + } while (nwritten == -1 && errno == EINTR); + + if (nwritten < nread) + goto exception; + + total += nwritten; + + if (show_progress) + em_migrate_set_progress (((double) total) / ((double) st.st_size)); + } while (total < st.st_size); + + if (fsync (fd[1]) == -1) + goto exception; + + close (fd[0]); + close (fd[1]); + + return 0; + + exception: + + errnosav = errno; + + close (fd[0]); + close (fd[1]); + unlink (dest); + + errno = errnosav; + + return -1; +} + +static GString * +mbox_build_filename (const char *toplevel_dir, const char *full_name) +{ + const char *start, *inptr = full_name; + int subdirs = 0; + GString *path; + + while (*inptr != '\0') { + if (*inptr == '/') + subdirs++; + inptr++; + } + + path = g_string_new (toplevel_dir); + g_string_append_c (path, '/'); + + inptr = full_name; + while (*inptr != '\0') { + start = inptr; + while (*inptr != '/' && *inptr != '\0') + inptr++; + + g_string_append_len (path, start, inptr - start); + + if (*inptr == '/') { + g_string_append (path, ".sbd/"); + inptr++; + + /* strip extranaeous '/'s */ + while (*inptr == '/') + inptr++; + } + } + + return path; +} + +#define mbox_store_build_filename(s,n) mbox_build_filename (((CamelService *) s)->url->path, n) + static void em_migrate_dir (EMMigrateSession *session, const char *dirname, const char *full_name) { @@ -303,7 +402,7 @@ em_migrate_dir (EMMigrateSession *session, const char *dirname, const char *full CamelStore *local_store; struct dirent *dent; CamelException ex; - char *path, *name; + char *path, *name, *uri; GPtrArray *uids; struct stat st; int index, i; @@ -327,7 +426,7 @@ em_migrate_dir (EMMigrateSession *session, const char *dirname, const char *full /* get old store & folder */ path = g_strdup_printf ("%s/local-metadata.xml", dirname); - if (!(local_store = get_local_store ((CamelSession *) session, dirname, path, &name, &index, &ex))) { + if (!(uri = get_local_store_uri (dirname, path, &name, &index, &ex))) { g_warning ("error opening old store for `%s': %s", full_name, ex.desc); camel_exception_clear (&ex); g_free (path); @@ -338,70 +437,118 @@ em_migrate_dir (EMMigrateSession *session, const char *dirname, const char *full g_free (path); - if (!(old_folder = camel_store_get_folder (local_store, name, 0, &ex))) { - g_warning ("error opening old folder `%s': %s", full_name, ex.desc); - camel_object_unref (local_store); - camel_exception_clear (&ex); + em_migrate_set_folder_name (full_name); + + if (!strncmp (uri, "mbox:", 5)) { + GString *src, *dest; + char *p; + + src = g_string_new (""); + g_string_append_printf (src, "%s/%s", uri + 5, name); g_free (name); - /* try subfolders anyway? */ - goto try_subdirs; - } - - g_free (name); - - flags |= (index ? CAMEL_STORE_FOLDER_BODY_INDEX : 0); - if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, &ex))) { - g_warning ("error creating new mbox folder `%s': %s", full_name, ex.desc); - camel_object_unref (local_store); - camel_object_unref (old_folder); - camel_exception_clear (&ex); + dest = mbox_store_build_filename (session->store, full_name); + p = strrchr (dest->str, '/'); + *p = '\0'; - /* try subfolders anyway? */ - goto try_subdirs; - } - - em_migrate_set_folder_name (full_name); - - uids = camel_folder_get_uids (old_folder); - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *message; - CamelMessageInfo *info; + if (camel_mkdir (dest->str, 0777) == -1 && errno != EEXIST) { + g_string_free (dest, TRUE); + g_string_free (src, TRUE); + goto try_subdirs; + } - if (!(info = camel_folder_get_message_info (old_folder, uids->pdata[i]))) - continue; + *p = '/'; + if (cp (src->str, dest->str, TRUE) == -1) { + g_string_free (dest, TRUE); + g_string_free (src, TRUE); + goto try_subdirs; + } - if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], &ex))) { - camel_folder_free_message_info (old_folder, info); - break; + g_string_append (src, ".ev-summary"); + g_string_append (dest, ".ev-summary"); + if (cp (src->str, dest->str, FALSE) == -1) { + g_string_free (dest, TRUE); + g_string_free (src, TRUE); + goto try_subdirs; } - camel_folder_append_message (new_folder, message, info, NULL, &ex); - camel_folder_free_message_info (old_folder, info); - camel_object_unref (message); + g_string_free (dest, TRUE); + g_string_free (src, TRUE); + } else { + if (!(local_store = camel_session_get_store ((CamelSession *) session, uri, &ex))) { + g_warning ("error opening old store for `%s': %s", full_name, ex.desc); + camel_exception_clear (&ex); + g_free (name); + g_free (uri); + + /* try subfolders anyway? */ + goto try_subdirs; + } - if (camel_exception_is_set (&ex)) - break; + if (!(old_folder = camel_store_get_folder (local_store, name, 0, &ex))) { + g_warning ("error opening old folder `%s': %s", full_name, ex.desc); + camel_object_unref (local_store); + camel_exception_clear (&ex); + g_free (name); + + /* try subfolders anyway? */ + goto try_subdirs; + } - em_migrate_set_progress (((double) i + 1) / ((double) uids->len)); - } - camel_folder_free_uids (old_folder, uids); + g_free (name); + + flags |= (index ? CAMEL_STORE_FOLDER_BODY_INDEX : 0); + if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, &ex))) { + g_warning ("error creating new mbox folder `%s': %s", full_name, ex.desc); + camel_object_unref (local_store); + camel_object_unref (old_folder); + camel_exception_clear (&ex); + + /* try subfolders anyway? */ + goto try_subdirs; + } - if (camel_exception_is_set (&ex)) { - g_warning ("error migrating folder `%s': %s", full_name, ex.desc); - camel_object_unref (local_store); + uids = camel_folder_get_uids (old_folder); + for (i = 0; i < uids->len; i++) { + CamelMimeMessage *message; + CamelMessageInfo *info; + + if (!(info = camel_folder_get_message_info (old_folder, uids->pdata[i]))) + continue; + + if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], &ex))) { + camel_folder_free_message_info (old_folder, info); + break; + } + + camel_folder_append_message (new_folder, message, info, NULL, &ex); + camel_folder_free_message_info (old_folder, info); + camel_object_unref (message); + + if (camel_exception_is_set (&ex)) + break; + + em_migrate_set_progress (((double) i + 1) / ((double) uids->len)); + } + + camel_folder_free_uids (old_folder, uids); + + if (camel_exception_is_set (&ex)) { + g_warning ("error migrating folder `%s': %s", full_name, ex.desc); + camel_object_unref (local_store); + camel_object_unref (old_folder); + camel_object_unref (new_folder); + camel_exception_clear (&ex); + + /* try subfolders anyway? */ + goto try_subdirs; + } + + /*camel_object_unref (local_store);*/ camel_object_unref (old_folder); camel_object_unref (new_folder); - camel_exception_clear (&ex); - - /* try subfolders anyway? */ - goto try_subdirs; } - /*camel_object_unref (local_store);*/ - camel_object_unref (old_folder); - camel_object_unref (new_folder); - try_subdirs: path = g_strdup_printf ("%s/subfolders", dirname); -- cgit v1.2.3