aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog30
-rw-r--r--camel/camel-store.c40
-rw-r--r--camel/camel-store.h9
-rw-r--r--camel/camel-url.c22
-rw-r--r--camel/camel-url.h9
-rw-r--r--camel/providers/mbox/camel-mbox-store.c50
-rw-r--r--camel/providers/mh/camel-mh-folder.c3
-rw-r--r--camel/providers/mh/camel-mh-store.c55
-rw-r--r--camel/providers/mh/camel-mh-summary.c6
9 files changed, 212 insertions, 12 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 63ee2758fd..ec58af3dcd 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,33 @@
+2000-08-07 Not Zed <NotZed@HelixCode.com>
+
+ * providers/mh/camel-mh-folder.c (mh_append_message): Only retry
+ another uid if we had a name clash, otherwise fail.
+
+2000-08-04 Not Zed <NotZed@HelixCode.com>
+
+ * camel-url.c (camel_url_set_protocol):
+ (camel_url_set_host):
+ (camel_url_set_path):
+ (camel_url_set_port): Url editing functions.
+
+2000-08-02 Not Zed <NotZed@HelixCode.com>
+
+ * providers/mh/camel-mh-summary.c (camel_mh_summary_sync): Expunge
+ from the end, so the index isn't messed up when you remove a
+ message.
+
+ * providers/mh/camel-mh-folder.c (mh_append_message): Fix a bug
+ where it would never open an output file/uid.
+
+ * providers/mbox/camel-mbox-store.c (rename_folder):
+ Implementation for mbox as well.
+
+ * camel-store.c (camel_store_rename_folder): New method to rename folders.
+ (rename_folder): Default implementation.
+
+ * providers/mh/camel-mh-store.c (delete_folder): Implement this.
+ (rename_folder): Implement a rename operation.
+
2000-08-07 Jeffrey Stedfast <fejj@helixcode.com>
* providers/imap/camel-imap-folder.c
diff --git a/camel/camel-store.c b/camel/camel-store.c
index d729bf10e7..3be983e081 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -38,6 +38,8 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name,
gboolean create, CamelException *ex);
static void delete_folder (CamelStore *store, const char *folder_name,
CamelException *ex);
+static void rename_folder (CamelStore *store, const char *old_name,
+ const char *new_name, CamelException *ex);
static char *get_folder_name (CamelStore *store, const char *folder_name,
CamelException *ex);
@@ -62,6 +64,7 @@ camel_store_class_init (CamelStoreClass *camel_store_class)
/* virtual method definition */
camel_store_class->get_folder = get_folder;
camel_store_class->delete_folder = delete_folder;
+ camel_store_class->rename_folder = rename_folder;
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_root_folder_name = get_root_folder_name;
camel_store_class->get_default_folder_name = get_default_folder_name;
@@ -138,6 +141,16 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
gtk_type_name (GTK_OBJECT_TYPE (store)));
}
+static void rename_folder (CamelStore *store, const char *old_name,
+ const char *new_name, CamelException *ex)
+{
+ g_warning ("CamelStore::rename_folder not implemented for `%s'",
+ gtk_type_name (GTK_OBJECT_TYPE (store)));
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "rename folder unimplemented for: %s",
+ gtk_type_name (GTK_OBJECT_TYPE (store)));
+}
+
/* CamelStore::get_folder_name should:
* a) make sure that the provided name is valid
@@ -287,6 +300,33 @@ camel_store_delete_folder (CamelStore *store, const char *folder_name,
}
}
+/**
+ * camel_store_rename_folder:
+ * @store:
+ * @old_name:
+ * @new_name:
+ * @ex:
+ *
+ * Rename a named folder to a new name.
+ **/
+void camel_store_rename_folder (CamelStore *store,
+ const char *old_name,
+ const char *new_name,
+ CamelException *ex)
+{
+ char *old, *new;
+
+ old = CS_CLASS (store)->get_folder_name(store, old_name, ex);
+ if (old) {
+ new = CS_CLASS (store)->get_folder_name(store, new_name, ex);
+ if (new) {
+ CS_CLASS (store)->rename_folder(store, old, new, ex);
+ g_free(new);
+ }
+ g_free(old);
+ }
+}
+
/**
* camel_store_get_root_folder: return the top-level folder
diff --git a/camel/camel-store.h b/camel/camel-store.h
index 6d2d9e53e9..3fc029d8c9 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -63,7 +63,10 @@ typedef struct {
void (*delete_folder) (CamelStore *store,
const char *folder_name,
CamelException *ex);
-
+ void (*rename_folder) (CamelStore *store,
+ const char *old_name,
+ const char *new_name,
+ CamelException *ex);
char * (*get_folder_name) (CamelStore *store,
const char *folder_name,
CamelException *ex);
@@ -99,6 +102,10 @@ CamelFolder * camel_store_get_default_folder (CamelStore *store,
void camel_store_delete_folder (CamelStore *store,
const char *folder_name,
CamelException *ex);
+void camel_store_rename_folder (CamelStore *store,
+ const char *old_name,
+ const char *new_name,
+ CamelException *ex);
#ifdef __cplusplus
}
diff --git a/camel/camel-url.c b/camel/camel-url.c
index 60385008c4..e52645c8e2 100644
--- a/camel/camel-url.c
+++ b/camel/camel-url.c
@@ -233,6 +233,28 @@ camel_url_free (CamelURL *url)
g_free (url);
}
+void camel_url_set_protocol(CamelURL *url, const char *p)
+{
+ g_free(url->protocol);
+ url->protocol = g_strdup(p);
+}
+
+void camel_url_set_host(CamelURL *url, const char *h)
+{
+ g_free(url->host);
+ url->host = g_strdup(h);
+}
+
+void camel_url_set_port(CamelURL *url, int port)
+{
+ url->port = port;
+}
+void camel_url_set_path(CamelURL *url, const char *p)
+{
+ g_free(url->path);
+ url->path = g_strdup(p);
+}
+
/**
* camel_url_encode:
diff --git a/camel/camel-url.h b/camel/camel-url.h
index bea1c439b2..aba903c08b 100644
--- a/camel/camel-url.h
+++ b/camel/camel-url.h
@@ -53,10 +53,15 @@ CamelURL *camel_url_new (const char *url_string, CamelException *ex);
char *camel_url_to_string (CamelURL *url, gboolean show_password);
void camel_url_free (CamelURL *url);
-char *camel_url_encode (char *part, gboolean escape_unsafe,
- char *escape_extra);
+char *camel_url_encode (char *part, gboolean escape_unsafe, char *escape_extra);
void camel_url_decode (char *part);
+/* for editing url's */
+void camel_url_set_protocol(CamelURL *url, const char *);
+void camel_url_set_host(CamelURL *url, const char *);
+void camel_url_set_port(CamelURL *url, int port);
+void camel_url_set_path(CamelURL *url, const char *);
+
/* for putting url's into hash tables */
guint camel_url_hash (const void *v);
int camel_url_equal(const void *v, const void *v2);
diff --git a/camel/providers/mbox/camel-mbox-store.c b/camel/providers/mbox/camel-mbox-store.c
index 19b7c54612..e3396a7965 100644
--- a/camel/providers/mbox/camel-mbox-store.c
+++ b/camel/providers/mbox/camel-mbox-store.c
@@ -44,6 +44,7 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name,
gboolean create, CamelException *ex);
static void delete_folder (CamelStore *store, const char *folder_name,
CamelException *ex);
+static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
static char *get_folder_name (CamelStore *store, const char *folder_name,
CamelException *ex);
@@ -58,6 +59,7 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class)
camel_store_class->get_folder = get_folder;
camel_store_class->delete_folder = delete_folder;
+ camel_store_class->rename_folder = rename_folder;
camel_store_class->get_folder_name = get_folder_name;
}
@@ -169,8 +171,7 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
struct stat st;
int status;
- name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path,
- folder_name);
+ name = g_strdup_printf ("%s%s", CAMEL_SERVICE (store)->url->path, folder_name);
if (stat (name, &st) == -1) {
if (errno == ENOENT) {
/* file doesn't exist - it's kinda like deleting it ;-) */
@@ -220,6 +221,51 @@ delete_folder (CamelStore *store, const char *folder_name, CamelException *ex)
}
}
+static int xrename(char *oldp, char *newp, char *prefix, char *suffix, CamelException *ex)
+{
+ struct stat st;
+ char *old = g_strconcat(prefix, oldp, suffix, 0);
+ char *new = g_strconcat(prefix, newp, suffix, 0);
+ int ret = -1;
+
+ printf("renaming %s%s to %s%s\n", oldp, suffix, newp, suffix);
+
+ /* FIXME: this has races ... */
+ if (!(stat(new, &st) == -1 && errno==ENOENT)) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not rename folder %s to %s: destination exists",
+ old, new);
+ } else if (rename(old, new) == 0 || errno==ENOENT) {
+ ret = 0;
+ } else if (stat(old, &st) == -1 && errno==ENOENT && stat(new, &st) == 0) {
+ /* for nfs, check if the rename worked anyway ... */
+ ret = 0;
+ }
+ printf("success = %d\n", ret);
+
+ g_free(old);
+ g_free(new);
+ return ret;
+}
+
+static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex)
+{
+ char *path = CAMEL_SERVICE (store)->url->path;
+
+ /* try to rollback failures, has obvious races */
+ if (xrename(old, new, path, ".ibex", ex)) {
+ return;
+ }
+ if (xrename(old, new, path, "-ev-summary", ex)) {
+ xrename(new, old, path, ".ibex", ex);
+ return;
+ }
+ if (xrename(old, new, path, "", ex)) {
+ xrename(new, old, path, "-ev-summary", ex);
+ xrename(new, old, path, ".ibex", ex);
+ }
+}
+
static char *
get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex)
{
diff --git a/camel/providers/mh/camel-mh-folder.c b/camel/providers/mh/camel-mh-folder.c
index 1961c62dd9..6f85fb756a 100644
--- a/camel/providers/mh/camel-mh-folder.c
+++ b/camel/providers/mh/camel-mh-folder.c
@@ -268,7 +268,6 @@ static gint mh_get_unread_message_count(CamelFolder * folder)
return count;
}
-/* FIXME: this may need some tweaking for performance? */
static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message, guint32 flags, CamelException * ex)
{
CamelMhFolder *mh_folder = CAMEL_MH_FOLDER(folder);
@@ -285,7 +284,7 @@ static void mh_append_message(CamelFolder * folder, CamelMimeMessage * message,
uid = camel_folder_summary_next_uid_string((CamelFolderSummary *)mh_folder->summary);
name = g_strdup_printf("%s/%s", mh_folder->folder_file_path, uid);
output_stream = camel_stream_fs_new_with_name(name, O_WRONLY|O_CREAT|O_EXCL, 0600);
- } while (output_stream == NULL || errno != EEXIST);
+ } while (output_stream == NULL && errno == EEXIST);
if (output_stream == NULL)
goto fail;
diff --git a/camel/providers/mh/camel-mh-store.c b/camel/providers/mh/camel-mh-store.c
index 6ae885ac27..5ab4bcc59d 100644
--- a/camel/providers/mh/camel-mh-store.c
+++ b/camel/providers/mh/camel-mh-store.c
@@ -43,6 +43,7 @@
static char *get_name(CamelService * service, gboolean brief);
static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboolean create, CamelException * ex);
static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex);
+static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex);
static void camel_mh_store_class_init(CamelMhStoreClass * camel_mh_store_class)
@@ -55,6 +56,7 @@ static void camel_mh_store_class_init(CamelMhStoreClass * camel_mh_store_class)
camel_store_class->get_folder = get_folder;
camel_store_class->delete_folder = delete_folder;
+ camel_store_class->rename_folder = rename_folder;
camel_store_class->get_folder_name = get_folder_name;
}
@@ -107,8 +109,11 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo
name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name);
+ printf("getting folder: %s\n", name);
if (stat(name, &st) == -1) {
int fd;
+
+ printf("doesn't exist ...\n");
if (errno != ENOENT) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
@@ -120,12 +125,15 @@ static CamelFolder *get_folder(CamelStore * store, const char *folder_name, gboo
"Folder `%s' does not exist.", folder_name);
goto done;
}
+ printf("creating ...\n");
- if (mkdir (name, 0600) != 0) {
+ if (mkdir(name, 0700) != 0) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
"Could not create folder `%s':" "\n%s", folder_name, g_strerror(errno));
goto done;
}
+ printf("created ok?\n");
+
} else if (!S_ISDIR(st.st_mode)) {
camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, "`%s' is not a directory.", name);
goto done;
@@ -142,13 +150,54 @@ done:
static void delete_folder(CamelStore * store, const char *folder_name, CamelException * ex)
{
char *name;
+ struct stat st;
+ char *str;
name = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, folder_name);
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- "Could not delete folder `%s':\n%s", folder_name, "not implemented");
+ if (stat(name, &st) == -1) {
+ if (errno != ENOENT)
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not delete folder `%s': %s", folder_name, strerror(errno));
+ } else {
+ /* this will 'fail' if there are still messages in the directory -
+ but only the metadata is lost */
+ str = g_strdup_printf("%s/ev-summary", name);
+ unlink(str);
+ g_free(str);
+ str = g_strdup_printf("%s/ev-index.ibex", name);
+ unlink(str);
+ g_free(str);
+ if (rmdir(name) == -1) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not delete folder `%s': %s", folder_name, strerror(errno));
+ }
+ }
g_free(name);
}
+static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex)
+{
+ char *old, *new;
+ struct stat st;
+
+ old = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, old_name);
+ new = g_strdup_printf("%s%s", CAMEL_SERVICE(store)->url->path, new_name);
+ if (stat(new, &st) == -1 && errno == ENOENT) {
+ if (stat(old, &st) == 0 && S_ISDIR(st.st_mode)) {
+ if (rename(old, new) != 0) {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not rename folder `%s': %s", old_name, strerror(errno));
+ }
+ } else {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not rename folder `%s': %s", old_name, strerror(errno));
+ }
+ } else {
+ camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
+ "Could not rename folder `%s': %s exists", old_name, new_name);
+ }
+}
+
static char *get_folder_name(CamelStore * store, const char *folder_name, CamelException * ex)
{
/* For now, we don't allow hieararchy. FIXME. */
diff --git a/camel/providers/mh/camel-mh-summary.c b/camel/providers/mh/camel-mh-summary.c
index 83f2113445..36bfd2f2cf 100644
--- a/camel/providers/mh/camel-mh-summary.c
+++ b/camel/providers/mh/camel-mh-summary.c
@@ -258,15 +258,17 @@ int camel_mh_summary_sync(CamelMhSummary * mhs, int expunge, CamelException *ex
CamelMessageInfo *info;
char *name;
+ printf("summary_sync(expunge=%s)\n", expunge?"true":"false");
+
if (!expunge)
return 0;
count = camel_folder_summary_count((CamelFolderSummary *)mhs);
- for (i=0;i<count;i++) {
+ for (i=count-1;i>=0;i--) {
info = camel_folder_summary_index((CamelFolderSummary *)mhs, i);
if (info && info->flags & CAMEL_MESSAGE_DELETED) {
name = g_strdup_printf("%s/%s", mhs->mh_path, info->uid);
- d(printf("deleting %s\n", name));
+ (printf("deleting %s\n", name));
if (unlink(name) == 0 || errno==ENOENT) {
camel_folder_summary_remove((CamelFolderSummary *)mhs, info);
}