diff options
author | nobody <nobody@localhost> | 2000-07-06 12:58:12 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2000-07-06 12:58:12 +0800 |
commit | a2d460b54b167a639bf05662d2f0de46acf73400 (patch) | |
tree | 4ba00fa4856e39912c9a54ecba72de80d51d2418 /camel/camel-movemail.c | |
parent | 04f148f617112009091abd18b16463033dd322d0 (diff) | |
download | gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar.gz gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar.bz2 gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar.lz gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar.xz gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.tar.zst gsoc2013-evolution-BEFORE_GTK_1_3_CHANGES.zip |
This commit was manufactured by cvs2svn to create tagBEFORE_GTK_1_3_CHANGES
'BEFORE_GTK_1_3_CHANGES'.
svn path=/tags/BEFORE_GTK_1_3_CHANGES/; revision=3911
Diffstat (limited to 'camel/camel-movemail.c')
-rw-r--r-- | camel/camel-movemail.c | 500 |
1 files changed, 0 insertions, 500 deletions
diff --git a/camel/camel-movemail.c b/camel/camel-movemail.c deleted file mode 100644 index 3ba3ee9efb..0000000000 --- a/camel/camel-movemail.c +++ /dev/null @@ -1,500 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-movemail.c: mbox copying function */ - -/* - * Author: - * Dan Winship <danw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#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 - * @source: source file - * @dest: destination file - * @ex: a CamelException - * - * This copies an mbox file from a shared directory with multiple - * readers and writers into a private (presumably Camel-controlled) - * directory. Dot locking is used on the source file (but not the - * destination). - * - * Return value: 1 if mail was copied, 0 if the source file contained - * no mail, -1 if an error occurred. - **/ -int -camel_movemail (const char *source, const char *dest, CamelException *ex) -{ - gboolean locked, error; - int sfd, dfd, tmpfd; - char *locktmpfile, *lockfile; - struct stat st; - time_t now, timeout; - int nread, nwrote; - char buf[BUFSIZ]; - - camel_exception_clear (ex); - - /* Stat and then open the spool file. If it doesn't exist or - * is empty, the user has no mail. (There's technically a race - * condition here in that an MDA might have just now locked it - * to deliver a message, but we don't care. In that case, - * assuming it's unlocked is equivalent to pretending we were - * called a fraction earlier.) - */ - if (stat (source, &st) == -1) { - if (errno == ENOENT) - return 0; - - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not check mail file %s: %s", - source, g_strerror (errno)); - return -1; - } - if (st.st_size == 0) - return 0; - - sfd = open (source, O_RDWR); - if (sfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not open mail file %s: %s", - source, g_strerror (errno)); - return -1; - } - - 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 " - "file %s: %s", dest, g_strerror (errno)); - close (sfd); - return -1; - } - - /* Create the unique lock file. */ - locktmpfile = g_strdup_printf ("%s.lock.XXXXXX", source); -#ifdef HAVE_MKSTEMP - tmpfd = mkstemp (locktmpfile); -#else - if (mktemp (locktmpfile)) { - tmpfd = open (locktmpfile, O_RDWR | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR); - } else - tmpfd = -1; -#endif - if (tmpfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not create lock file " - "for %s: %s", source, g_strerror (errno)); - close (sfd); - close (dfd); - unlink (dest); - return -1; - } - close (tmpfd); - - lockfile = g_strdup_printf ("%s.lock", source); - locked = FALSE; - time (&timeout); - timeout += 30; - - /* Loop trying to lock the file for 30 seconds. */ - while (time (&now) < timeout) { - /* Try to make the lock. */ - if (symlink (locktmpfile, lockfile) == 0) { - locked = TRUE; - break; - } - - /* If we fail for a reason other than that someone - * else has the lock, then abort. - */ - if (errno != EEXIST) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not create lock " - "file for %s: %s", source, - g_strerror (errno)); - break; - } - - /* Check the modtime on the lock file. */ - if (stat (lockfile, &st) == -1) { - /* If the lockfile disappeared, try again. */ - if (errno == ENOENT) - continue; - - /* Some other error. Abort. */ - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Could not test lock " - "file for %s: %s", source, - g_strerror (errno)); - break; - } - - /* If the lock file is stale, remove it and try again. */ - if (st.st_mtime < now - 60) { - unlink (lockfile); - continue; - } - - /* Otherwise, sleep and try again. */ - sleep (5); - } - - if (!locked) { - /* Something has gone awry. */ - if (now >= timeout) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Timed out trying to get " - "lock file on %s. Try again " - "later.", source); - } - g_free (lockfile); - unlink (locktmpfile); - g_free (locktmpfile); - close (sfd); - close (dfd); - unlink (dest); - return -1; - } - - /* OK. We have the file locked now. */ - - /* FIXME: Set a timer to keep the file locked. */ - - error = FALSE; - 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)); - error = TRUE; - 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)); - error = TRUE; - break; - } - written += nwrote; - nread -= nwrote; - } - } - - /* If no errors occurred copying the data, and we successfully - * close the destination file, then truncate the source file. - * If there is some sort of error, delete the destination file. - */ - if (!error) { - if (close (dfd) == 0) - ftruncate (sfd, 0); - else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Failed to store mail in " - "temp file %s: %s", dest, - g_strerror (errno)); - unlink (dest); - error = TRUE; - } - } else { - close (dfd); - unlink (dest); - } - close (sfd); - - /* Clean up lock files. */ - unlink (lockfile); - g_free (lockfile); - unlink (locktmpfile); - g_free (locktmpfile); - - 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; -} - |