diff options
Diffstat (limited to 'camel/camel-movemail.c')
-rw-r--r-- | camel/camel-movemail.c | 141 |
1 files changed, 91 insertions, 50 deletions
diff --git a/camel/camel-movemail.c b/camel/camel-movemail.c index bd00075485..fec8e5fc10 100644 --- a/camel/camel-movemail.c +++ b/camel/camel-movemail.c @@ -59,9 +59,15 @@ static void movemail_external (const char *source, const char *dest, CamelException *ex); #endif +#ifdef HAVE_BROKEN_SPOOL +static int camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, CamelMimeFilter *filter); +static int camel_movemail_solaris (int oldsfd, int dfd, CamelException *ex); +#else /* these could probably be exposed as a utility? (but only mbox needs it) */ +static int camel_movemail_copy_file(int sfd, int dfd, CamelException *ex); +#endif + #if 0 -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); #endif @@ -86,8 +92,6 @@ camel_movemail(const char *source, const char *dest, CamelException *ex) int res = -1; int sfd, dfd; struct stat st; - int nread, nwrote; - char buf[BUFSIZ]; camel_exception_clear(ex); @@ -103,7 +107,7 @@ camel_movemail(const char *source, const char *dest, CamelException *ex) camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not check mail file " "%s: %s"), source, - g_strerror (errno)); + strerror (errno)); } return -1; } @@ -116,7 +120,7 @@ camel_movemail(const char *source, const char *dest, CamelException *ex) if (sfd == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not open mail file %s: %s"), - source, g_strerror (errno)); + source, strerror (errno)); return -1; } @@ -125,7 +129,7 @@ camel_movemail(const char *source, const char *dest, CamelException *ex) camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not open temporary mail " "file %s: %s"), dest, - g_strerror (errno)); + strerror (errno)); close (sfd); return -1; } @@ -138,49 +142,23 @@ camel_movemail(const char *source, const char *dest, CamelException *ex) return -1; } - while (1) { - int written = 0; - - nread = read (sfd, buf, sizeof (buf)); - 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)); - break; - } - - 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"), - g_strerror (errno)); - break; - } - written += nwrote; - nread -= nwrote; - } - } +#ifdef HAVE_BROKEN_SPOOL + res = camel_movemail_solaris(sfd, dfd, ex); +#else + res = camel_movemail_copy_file(sfd, dfd, ex); +#endif /* If no errors occurred copying the data, and we successfully * close the destination file, then truncate the source file. */ - if (!camel_exception_is_set (ex)) { + if (res != -1) { if (close (dfd) == 0) { ftruncate (sfd, 0); - res = 0; } else { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Failed to store mail in " - "temp file %s: %s"), dest, - g_strerror (errno)); + _("Failed to store mail in temp file %s: %s"), dest, + strerror(errno)); + res = -1; } } else close (dfd); @@ -209,7 +187,7 @@ movemail_external (const char *source, const char *dest, CamelException *ex) sigprocmask (SIG_SETMASK, &omask, NULL); camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not create pipe: %s"), - g_strerror (errno)); + strerror (errno)); return; } @@ -221,7 +199,7 @@ movemail_external (const char *source, const char *dest, CamelException *ex) sigprocmask (SIG_SETMASK, &omask, NULL); camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not fork: %s"), - g_strerror (errno)); + strerror (errno)); return; case 0: @@ -265,6 +243,46 @@ movemail_external (const char *source, const char *dest, CamelException *ex) } #endif +#ifndef HAVE_BROKEN_SPOOL +static int +camel_movemail_copy_file(int sfd, int dfd, CamelException *ex) +{ + int nread, nwrote; + char buf[4096]; + + while (1) { + int written = 0; + + nread = read (sfd, buf, sizeof (buf)); + if (nread == 0) + break; + else if (nread == -1) { + if (errno == EINTR) + continue; + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Error reading mail file: %s"), + strerror (errno)); + return -1; + } + + 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"), + strerror (errno)); + return -1; + } + written += nwrote; + nread -= nwrote; + } + } + + return 0; +} +#endif #if 0 static int @@ -318,7 +336,7 @@ camel_movemail_copy(int fromfd, int tofd, off_t start, size_t bytes) #define PRE_SIZE (32) -#if 0 +#ifdef HAVE_BROKEN_SPOOL static int camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, CamelMimeFilter *filter) { @@ -349,6 +367,8 @@ camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, Came if (towrite == -1) return -1; + printf("read %d unfiltered bytes\n", towrite); + /* check for 'end of file' */ if (towrite == 0) { d(printf("end of file?\n")); @@ -363,6 +383,8 @@ camel_movemail_copy_filter(int fromfd, int tofd, off_t start, size_t bytes, Came towrite = filterlen; } + printf("writing %d filtered bytes\n", towrite); + do { toread = write(tofd, filterbuffer, towrite); } while (toread == -1 && errno == EINTR); @@ -428,13 +450,24 @@ solaris_header_write(int fd, struct _header_raw *header) 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) +camel_movemail_solaris (int oldsfd, int dfd, CamelException *ex) { CamelMimeParser *mp; char *buffer; int len; + int sfd; CamelMimeFilterFrom *ffrom; int ret = 1; + char *from = NULL; + + /* need to dup as the mime parser will close on finish */ + sfd = dup(oldsfd); + if (sfd == -1) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, + _("Error copying mail temp file: %s"), + strerror (errno)); + return -1; + } mp = camel_mime_parser_new(); camel_mime_parser_scan_from(mp, TRUE); @@ -443,6 +476,8 @@ camel_movemail_solaris (int sfd, int dfd, CamelException *ex) ffrom = camel_mime_filter_from_new(); while (camel_mime_parser_step(mp, &buffer, &len) == HSCAN_FROM) { + g_assert(camel_mime_parser_from_line(mp)); + from = g_strdup(camel_mime_parser_from_line(mp)); if (camel_mime_parser_step(mp, &buffer, &len) != HSCAN_FROM_END) { const char *cl; int length; @@ -454,8 +489,12 @@ camel_movemail_solaris (int sfd, int dfd, CamelException *ex) start = camel_mime_parser_tell_start_from(mp); body = camel_mime_parser_tell(mp); + if (write(dfd, from, strlen(from)) != strlen(from)) + goto fail; + /* write out headers, but NOT content-length header */ - solaris_header_write(dfd, camel_mime_parser_headers_raw(mp)); + if (solaris_header_write(dfd, camel_mime_parser_headers_raw(mp)) == -1) + goto fail; cl = camel_mime_parser_header(mp, "content-length", NULL); if (cl == NULL) { @@ -480,6 +519,7 @@ camel_movemail_solaris (int sfd, int dfd, CamelException *ex) } else { g_error("Inalid parser state: %d", camel_mime_parser_state(mp)); } + g_free(from); } camel_object_unref((CamelObject *)mp); @@ -488,10 +528,11 @@ camel_movemail_solaris (int sfd, int dfd, CamelException *ex) return ret; fail: + g_free(from); + camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Error copying " - "mail temp file: %s"), - g_strerror (errno)); + _("Error copying mail temp file: %s"), + strerror (errno)); camel_object_unref((CamelObject *)mp); @@ -499,5 +540,5 @@ fail: return -1; } -#endif +#endif /* HAVE_BROKEN_SPOOL */ |