aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog17
-rw-r--r--camel/camel-movemail.c250
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c21
-rw-r--r--camel/providers/mbox/camel-mbox-summary.c11
4 files changed, 292 insertions, 7 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 7eddc455a8..fbd9dcb092 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,20 @@
+2000-05-16 NotZed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-folder.c (mbox_delete_message_by_uid):
+ Implement.
+
+2000-05-12 NotZed <NotZed@HelixCode.com>
+
+ * camel-movemail.c (camel_movemail): Open the destination with
+ O_APPEND, so we dont blow away a partially transferred mbox.
+ (camel_movemail): Loop if we get errno=INTR, and not fail.
+
+2000-05-11 NotZed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-summary.c (summary_rebuild): Update
+ the summarised file size, if everything went ok.
+ (camel_mbox_summary_expunge): Clear header flags after updating.
+
2000-05-16 Chris Toshok <toshok@helixcode.com>
* providers/nntp/camel-nntp-folder.c:
diff --git a/camel/camel-movemail.c b/camel/camel-movemail.c
index e15e26e7ae..3ba3ee9efb 100644
--- a/camel/camel-movemail.c
+++ b/camel/camel-movemail.c
@@ -26,16 +26,28 @@
#include <config.h>
#include <sys/stat.h>
+#include <sys/uio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
+#include <string.h>
#include "camel-movemail.h"
#include "camel-exception.h"
+#include "camel-mime-parser.h"
+#include "camel-mime-filter.h"
+#include "camel-mime-filter-from.h"
+
+#define d(x)
+
+/* these could probably be exposed as a utility? (but only mbox needs it) */
+static int camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, CamelMimeFilter *filter);
+static int camel_movemail_copy(int fromfd, int tofd, off_t start, size_t bytes);
+
/**
* camel_movemail: Copy an mbox file from a shared spool directory to a
* new folder in a Camel store
@@ -91,7 +103,7 @@ camel_movemail (const char *source, const char *dest, CamelException *ex)
return -1;
}
- dfd = open (dest, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ dfd = open (dest, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
if (dfd == -1) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Could not open temporary mail "
@@ -199,6 +211,8 @@ camel_movemail (const char *source, const char *dest, CamelException *ex)
if (nread == 0)
break;
else if (nread == -1) {
+ if (errno == EINTR)
+ continue;
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Error reading mail file: %s",
g_strerror (errno));
@@ -209,6 +223,8 @@ camel_movemail (const char *source, const char *dest, CamelException *ex)
while (nread) {
nwrote = write (dfd, buf + written, nread);
if (nwrote == -1) {
+ if (errno == EINTR)
+ continue; /* continues inner loop */
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Error writing "
"mail temp file: %s",
@@ -250,3 +266,235 @@ camel_movemail (const char *source, const char *dest, CamelException *ex)
return error ? -1 : 1;
}
+
+static int
+camel_movemail_copy(int fromfd, int tofd, off_t start, size_t bytes)
+{
+ char buffer[4096];
+ int written = 0;
+
+ d(printf("writing %d bytes ... ", bytes));
+
+ if (lseek(fromfd, start, SEEK_SET) != start)
+ return -1;
+
+ while (bytes>0) {
+ int toread, towrite;
+
+ toread = bytes;
+ if (bytes>4096)
+ toread = 4096;
+ else
+ toread = bytes;
+ do {
+ towrite = read(fromfd, buffer, toread);
+ } while (towrite == -1 && errno == EINTR);
+
+ if (towrite == -1)
+ return -1;
+
+ /* check for 'end of file' */
+ if (towrite == 0) {
+ d(printf("end of file?\n"));
+ break;
+ }
+
+ do {
+ toread = write(tofd, buffer, towrite);
+ } while (toread == -1 && errno == EINTR);
+
+ if (toread == -1)
+ return -1;
+
+ written += toread;
+ bytes -= toread;
+ }
+
+ d(printf("written %d bytes\n", written));
+
+ return written;
+}
+
+#define PRE_SIZE (32)
+
+static int
+camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, CamelMimeFilter *filter)
+{
+ char buffer[4096+PRE_SIZE];
+ int written = 0;
+ char *filterbuffer;
+ int filterlen, filterpre;
+
+ d(printf("writing %d bytes ... ", bytes));
+
+ camel_mime_filter_reset(filter);
+
+ if (lseek(fromfd, start, SEEK_SET) != start)
+ return -1;
+
+ while (bytes>0) {
+ int toread, towrite;
+
+ toread = bytes;
+ if (bytes>4096)
+ toread = 4096;
+ else
+ toread = bytes;
+ do {
+ towrite = read(fromfd, buffer+PRE_SIZE, toread);
+ } while (towrite == -1 && errno == EINTR);
+
+ if (towrite == -1)
+ return -1;
+
+ /* check for 'end of file' */
+ if (towrite == 0) {
+ d(printf("end of file?\n"));
+ camel_mime_filter_complete(filter, buffer+PRE_SIZE, towrite, PRE_SIZE,
+ &filterbuffer, &filterlen, &filterpre);
+ towrite = filterlen;
+ if (towrite == 0)
+ break;
+ } else {
+ camel_mime_filter_filter(filter, buffer+PRE_SIZE, towrite, PRE_SIZE,
+ &filterbuffer, &filterlen, &filterpre);
+ towrite = filterlen;
+ }
+
+ do {
+ toread = write(tofd, filterbuffer, towrite);
+ } while (toread == -1 && errno == EINTR);
+
+ if (toread == -1)
+ return -1;
+
+ written += toread;
+ bytes -= toread;
+ }
+
+ d(printf("written %d bytes\n", written));
+
+ return written;
+}
+
+/* write the headers back out again, but not he Content-Length header, because we dont
+ want to maintain it! */
+static int
+solaris_header_write(int fd, struct _header_raw *header)
+{
+ struct iovec iv[4];
+ int outlen = 0, len;
+
+ iv[1].iov_base = ":";
+ iv[1].iov_len = 1;
+ iv[3].iov_base = "\n";
+ iv[3].iov_len = 1;
+
+ while (header) {
+ if (strcasecmp(header->name, "Content-Length")) {
+ iv[0].iov_base = header->name;
+ iv[0].iov_len = strlen(header->name);
+ iv[2].iov_base = header->value;
+ iv[2].iov_len = strlen(header->value);
+
+ do {
+ len = writev(fd, iv, 4);
+ } while (len == -1 && errno == EINTR);
+
+ if (len == -1)
+ return -1;
+ outlen += len;
+ }
+ header = header->next;
+ }
+
+ do {
+ len = write(fd, "\n", 1);
+ } while (len == -1 && errno == EINTR);
+
+ if (len == -1)
+ return -1;
+
+ outlen += 1;
+
+ d(printf("Wrote %d bytes of headers\n", outlen));
+
+ return outlen;
+}
+
+/* Well, since Solaris is a tad broken wrt its 'mbox' folder format,
+ we must convert it to a real mbox format. Thankfully this is
+ mostly pretty easy */
+static int
+camel_movemail_solaris (int sfd, int dfd, CamelException *ex)
+{
+ CamelMimeParser *mp;
+ char *buffer;
+ int len;
+ CamelMimeFilterFrom *ffrom;
+ int ret = 1;
+
+ mp = camel_mime_parser_new();
+ camel_mime_parser_scan_from(mp, TRUE);
+ camel_mime_parser_init_with_fd(mp, sfd);
+
+ ffrom = camel_mime_filter_from_new();
+
+ while (camel_mime_parser_step(mp, &buffer, &len) == HSCAN_FROM) {
+ if (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_FROM_END) {
+ const char *cl;
+ int length;
+ int start, body;
+ off_t newpos;
+
+ ret = 0;
+
+ start = camel_mime_parser_tell_start_from(mp);
+ body = camel_mime_parser_tell(mp);
+
+ /* write out headers, but NOT content-length header */
+ solaris_header_write(dfd, camel_mime_parser_headers_raw(mp));
+
+ cl = camel_mime_parser_header(mp, "content-length", NULL);
+ if (cl == NULL) {
+ g_warning("Required Content-Length header is missing from solaris mail box @ %d", (int)camel_mime_parser_tell(mp));
+ camel_mime_parser_drop_step(mp);
+ camel_mime_parser_drop_step(mp);
+ camel_mime_parser_step(mp, &buffer, &len);
+ camel_mime_parser_unstep(mp);
+ length = camel_mime_parser_tell_start_from(mp) - body;
+ newpos = -1;
+ } else {
+ length = atoi(cl);
+ camel_mime_parser_drop_step(mp);
+ camel_mime_parser_drop_step(mp);
+ newpos = length+body;
+ }
+ /* copy body->length converting From lines */
+ if (camel_movemail_copy_filter(sfd, dfd, body, length, (CamelMimeFilter *)ffrom) == -1)
+ goto fail;
+ if (newpos != -1)
+ camel_mime_parser_seek(mp, newpos, SEEK_SET);
+ } else {
+ g_error("Inalid parser state: %d", camel_mime_parser_state(mp));
+ }
+ }
+
+ gtk_object_unref((GtkObject *)mp);
+ gtk_object_unref((GtkObject *)ffrom);
+
+ return ret;
+
+fail:
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ "Error copying "
+ "mail temp file: %s",
+ g_strerror (errno));
+
+
+ gtk_object_unref((GtkObject *)mp);
+ gtk_object_unref((GtkObject *)ffrom);
+
+ return -1;
+}
+
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index 3403271e40..9d405bd1db 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -79,6 +79,8 @@ static void _copy_message_to (CamelFolder *folder, CamelMimeMessage *message, Ca
static const gchar *_get_message_uid (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex);
#endif
+static void mbox_delete_message_by_uid(CamelFolder *folder, const gchar *uid, CamelException *ex);
+
GPtrArray *summary_get_message_info (CamelFolder *folder, int first, int count);
static const CamelMessageInfo *mbox_summary_get_by_uid(CamelFolder *f, const char *uid);
@@ -110,11 +112,9 @@ camel_mbox_folder_class_init (CamelMboxFolderClass *camel_mbox_folder_class)
camel_folder_class->append_message = mbox_append_message;
camel_folder_class->get_uid_list = mbox_get_uid_list;
camel_folder_class->expunge = mbox_expunge;
-#if 0
- camel_folder_class->copy_message_to = _copy_message_to;
- camel_folder_class->get_message_uid = _get_message_uid;
-#endif
+
camel_folder_class->get_message_by_uid = mbox_get_message_by_uid;
+ camel_folder_class->delete_message_by_uid = mbox_delete_message_by_uid;
camel_folder_class->search_by_expression = mbox_search_by_expression;
@@ -824,6 +824,19 @@ mbox_get_message_by_number (CamelFolder *folder, gint number, CamelException *ex
return mbox_get_message_by_uid (folder, info->info.uid, ex);
}
+static void
+mbox_delete_message_by_uid(CamelFolder *folder, const gchar *uid, CamelException *ex)
+{
+ CamelMessageInfo *info;
+ CamelMboxFolder *mf = (CamelMboxFolder *)folder;
+
+ info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, uid);
+ if (info) {
+ info->flags |= CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_FOLDER_FLAGGED;
+ camel_folder_summary_touch((CamelFolderSummary *)mf->summary);
+ }
+}
+
/* track flag changes in the summary */
static void
message_changed(CamelMimeMessage *m, int type, CamelMboxFolder *mf)
diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c
index 56ff1cb198..dac2694f4c 100644
--- a/camel/providers/mbox/camel-mbox-summary.c
+++ b/camel/providers/mbox/camel-mbox-summary.c
@@ -299,6 +299,7 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset)
} else {
gtk_object_unref((GtkObject *)mp);
/* end of file - no content? */
+ printf("We radn out of file?\n");
return 0;
}
}
@@ -308,6 +309,7 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset)
info = camel_folder_summary_add_from_parser((CamelFolderSummary *)mbs, mp);
if (info == NULL) {
+ printf("Could not build info from file?\n");
ok = -1;
break;
}
@@ -315,6 +317,10 @@ summary_rebuild(CamelMboxSummary *mbs, off_t offset)
g_assert(camel_mime_parser_step(mp, NULL, NULL) == HSCAN_FROM_END);
}
+ /* update the file size in the summary */
+ if (ok != -1)
+ mbs->folder_size = camel_mime_parser_seek(mp, 0, SEEK_CUR);
+ printf("updating folder size = %d\n", mbs->folder_size);
gtk_object_unref((GtkObject *)mp);
return ok;
@@ -631,7 +637,7 @@ camel_mbox_summary_expunge(CamelMboxSummary *mbs)
}
xevok = TRUE;
}
- xevnew = header_evolution_encode(strtoul(info->info.uid, NULL, 10), info->info.flags);
+ xevnew = header_evolution_encode(strtoul(info->info.uid, NULL, 10), info->info.flags & 0xffff);
if (quick) {
if (!xevok) {
g_error("The summary told me I had an X-Evolution header, but i dont!");
@@ -664,6 +670,7 @@ camel_mbox_summary_expunge(CamelMboxSummary *mbs)
info->frompos = frompos;
offset = bodypos - info->info.content->bodypos;
}
+ info->info.flags &= 0xffff;
g_free(xevnew); xevnew = NULL;
camel_mime_parser_drop_step(mp);
camel_mime_parser_drop_step(mp);
@@ -703,7 +710,7 @@ camel_mbox_summary_expunge(CamelMboxSummary *mbs)
if (stat(mbs->folder_path, &st) == -1)
goto error;
- s->flags |= CAMEL_SUMMARY_DIRTY;
+ camel_folder_summary_touch(s);
s->time = st.st_mtime;
mbs->folder_size = st.st_size;
camel_folder_summary_save(s);