isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 3fe6f3f086118ebbe1ce8b2220feffe5ce85e0e2
parent f0c7fdf008aeebfa039d76fc4e3e50dedc70170c
Author: Michael Elkins <me@mutt.org>
Date:   Tue, 20 Nov 2001 18:06:09 +0000

added --create/-C command line option to force creation of the local
maildir-style mailbox if nonexistent

debug.h was not included in isync_SOURCES in Makefile.am

Diffstat:
MMakefile.am | 3++-
MNEWS | 3+++
Misync.1 | 13+++++++++----
Misync.h | 6+++++-
Mmaildir.c | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mmain.c | 19+++++++++++++++----
6 files changed, 102 insertions(+), 31 deletions(-)

diff --git a/Makefile.am b/Makefile.am @@ -1,5 +1,6 @@ bin_PROGRAMS=isync -isync_SOURCES=main.c imap.c sync.c maildir.c isync.h list.c cram.c config.c +isync_SOURCES=main.c imap.c sync.c maildir.c isync.h list.c cram.c config.c \ + debug.h isync_LDADD=@DEBUGOBJ@ isync_DEPENDENCIES=@DEBUGOBJ@ EXTRA_isync_SOURCES=debug.c diff --git a/NEWS b/NEWS @@ -3,6 +3,9 @@ Added `MaxMessages' configuration option to allow tracking of only the most recently added message in the local mailbox. +Added --create (-C) command line option to force creation of the local +maildir-style mailbox if it doesn't already exist. + [0.6] Added `Delete' configuration option to correspond to the -d command line diff --git a/isync.1 b/isync.1 @@ -1,6 +1,6 @@ .ig \" isync - IMAP4 to maildir mailbox synchronizer -\" Copyright (C) 2000 Michael R. Elkins <me@mutt.org> +\" Copyright (C) 2000-1 Michael R. Elkins <me@mutt.org> \" \" 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 @@ -16,7 +16,7 @@ \" along with this program; if not, write to the Free Software \" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA .. -.TH isync 1 "2001 Oct 30" +.TH isync 1 "2001 Nov 20" .. .SH NAME isync - synchronize IMAP4 and maildir mailboxes @@ -43,6 +43,10 @@ all flags are synchronized. \fB-a\fR, \fB--all\fR Synchronize all mailboxes specified in the user's ~/.isyncrc. .TP +\fB-C\fR, \fB--create\fR +Automatically create the local maildir-style mailbox if it doesn't already +exist. +.TP \fB-c\fR, \fB--config\fR \fIfile\fR Read configuration from .I file @@ -206,7 +210,8 @@ deleted. If .I count is 0, the maximum number of messages is -.B unlimited (Default: 0). +.B unlimited +(Default: 0). .. .TP \fBMaxSize\fR \fIbytes\fR @@ -328,7 +333,7 @@ mutt(1), maildir(5) Up to date information on .B isync can be found at -http://www.sigpipe.org/isync/. +http://www.sigpipe.org:8080/isync/. .. .SH AUTHOR Written by Michael R. Elkins <me@mutt.org>. diff --git a/isync.h b/isync.h @@ -155,6 +155,10 @@ imap_t; #define SYNC_EXPUNGE (1<<1) /* don't fetch deleted messages */ #define SYNC_QUIET (1<<2) /* only display critical errors */ +/* flags for maildir_open */ +#define OPEN_FAST (1<<0) /* fast open - don't parse */ +#define OPEN_CREATE (1<<1) /* create mailbox if nonexistent */ + extern config_t global; extern config_t *boxes; extern unsigned int Tag; @@ -184,7 +188,7 @@ int imap_expunge (imap_t *); imap_t *imap_open (config_t *, unsigned int, imap_t *); int imap_append_message (imap_t *, int, message_t *); -mailbox_t *maildir_open (const char *, int fast); +mailbox_t *maildir_open (const char *, int flags); int maildir_expunge (mailbox_t *, int); int maildir_set_uidvalidity (mailbox_t *, unsigned int uidvalidity); int maildir_close (mailbox_t *); diff --git a/maildir.c b/maildir.c @@ -119,14 +119,16 @@ read_uid (const char *path, const char *file) } -/* open a maildir mailbox. if `fast' is nonzero, we just check to make +/* open a maildir mailbox. + * if OPEN_FAST is set, we just check to make * sure its a valid mailbox and don't actually parse it. any IMAP messages * with the \Recent flag set are guaranteed not to be in the mailbox yet, * so we can save a lot of time when the user just wants to fetch new messages * without syncing the flags. + * if OPEN_CREATE is set, we create the mailbox if it doesn't already exist. */ mailbox_t * -maildir_open (const char *path, int fast) +maildir_open (const char *path, int flags) { char buf[_POSIX_PATH_MAX]; DIR *d; @@ -136,27 +138,68 @@ maildir_open (const char *path, int fast) mailbox_t *m; char *s; int count = 0; + struct stat sb; + const char *subdirs[] = { "cur", "new", "tmp" }; + int i; m = calloc (1, sizeof (mailbox_t)); /* filename expansion happens here, not in the config parser */ m->path = expand_strdup (path); - /* check to make sure this looks like a valid maildir box */ - snprintf (buf, sizeof (buf), "%s/new", m->path); - if (access (buf, F_OK)) + if (stat (m->path, &sb)) { - free (m->path); - free (m); - perror ("access"); - return 0; + if (errno == ENOENT && (flags & OPEN_CREATE)) + { + if (mkdir (m->path, S_IRUSR | S_IWUSR | S_IXUSR)) + { + fprintf (stderr, "ERROR: mkdir %s: %s (errno %d)\n", + m->path, strerror (errno), errno); + free (m->path); + free (m); + return NULL; + } + + for (i = 0; i < 3; i++) + { + snprintf (buf, sizeof (buf), "%s/%s", m->path, subdirs[i]); + if (mkdir (buf, S_IRUSR | S_IWUSR | S_IXUSR)) + { + fprintf (stderr, "ERROR: mkdir %s: %s (errno %d)\n", + buf, strerror (errno), errno); + free (m->path); + free (m); + return NULL; + } + } + + } + else + { + fprintf (stderr, "ERROR: stat %s: %s (errno %d)\n", m->path, + strerror (errno), errno); + free (m->path); + free (m); + return NULL; + } } - snprintf (buf, sizeof (buf), "%s/cur", m->path); - if (access (buf, F_OK)) + else { - free (m->path); - free (m); - perror ("access"); - return 0; + /* check to make sure this looks like a valid maildir box */ + for (i = 0; i < 3; i++) + { + snprintf (buf, sizeof (buf), "%s/%s", m->path, subdirs[i]); + if (stat (buf, &sb)) + { + fprintf (stderr, "ERROR: stat %s: %s (errno %d)\n", buf, + strerror (errno), errno); + fprintf (stderr, + "ERROR: %s does not appear to be a valid maildir style mailbox\n", + m->path); + free (m->path); + free (m); + return 0; + } + } } /* check for the uidvalidity value */ @@ -176,7 +219,7 @@ maildir_open (const char *path, int fast) return NULL; } - if (fast) + if (flags & OPEN_FAST) return m; cur = &m->msgs; @@ -224,11 +267,11 @@ maildir_open (const char *path, int fast) m->maxuidchanged = 1; } /* Courier-IMAP names it files - * unique,S=<size>:info + * unique,S=<size>:info * so we need to put the UID before the size, hence here * we check for a comma as a valid terminator as well, * since the format will be - * unique,U=<uid>,S=<size>:info + * unique,U=<uid>,S=<size>:info */ if (*s && *s != ':' && *s != ',') { @@ -358,7 +401,8 @@ maildir_clean_tmp (const char *mbox) dirp = opendir (path); if (dirp == NULL) { - fprintf (stderr, "maildir_clean_tmp: opendir: %s: %s (errno %d)\n", path, strerror (errno), errno); + fprintf (stderr, "maildir_clean_tmp: opendir: %s: %s (errno %d)\n", + path, strerror (errno), errno); return; } /* assuming this scan will take less than a second, we only need to @@ -369,7 +413,8 @@ maildir_clean_tmp (const char *mbox) { snprintf (path, sizeof (path), "%s/tmp/%s", mbox, entry->d_name); if (stat (path, &info)) - fprintf (stderr, "maildir_clean_tmp: stat: %s: %s (errno %d)\n", path, strerror (errno), errno); + fprintf (stderr, "maildir_clean_tmp: stat: %s: %s (errno %d)\n", + path, strerror (errno), errno); else if (S_ISREG (info.st_mode) && now - info.st_ctime >= _24_HOURS) { /* this should happen infrequently enough that it won't be @@ -377,7 +422,9 @@ maildir_clean_tmp (const char *mbox) */ printf ("Warning: removing stale file %s\n", path); if (unlink (path)) - fprintf (stderr, "maildir_clean_tmp: unlink: %s: %s (errno %d)\n", path, strerror (errno), errno); + fprintf (stderr, + "maildir_clean_tmp: unlink: %s: %s (errno %d)\n", + path, strerror (errno), errno); } } } diff --git a/main.c b/main.c @@ -35,6 +35,7 @@ struct option Opts[] = { {"all", 0, NULL, 'a'}, {"config", 1, NULL, 'c'}, + {"create", 0, NULL, 'C'}, {"delete", 0, NULL, 'd'}, {"expunge", 0, NULL, 'e'}, {"fast", 0, NULL, 'f'}, @@ -70,6 +71,7 @@ usage (void) printf ("usage: %s [ flags ] mailbox [mailbox ...]\n", PACKAGE); puts (" -a, --all Synchronize all defined mailboxes"); puts (" -c, --config CONFIG read an alternate config file (default: ~/.isyncrc)"); + puts (" -C, --create create local maildir mailbox if nonexistent"); puts (" -d, --delete delete local msgs that don't exist on the server"); puts (" -e, --expunge expunge deleted messages from the server"); puts (" -f, --fast only fetch new messages"); @@ -141,6 +143,7 @@ main (int argc, char **argv) struct passwd *pw; int quiet = 0; int all = 0; + int create = 0; pw = getpwuid (getuid ()); @@ -163,7 +166,7 @@ main (int argc, char **argv) global.use_tlsv1 = 1; #endif -#define FLAGS "ac:defhp:qu:r:s:vV" +#define FLAGS "aCc:defhp:qu:r:s:vV" #if HAVE_GETOPT_LONG while ((i = getopt_long (argc, argv, FLAGS, Opts, NULL)) != -1) @@ -176,6 +179,9 @@ main (int argc, char **argv) case 'a': all = 1; break; + case 'C': + create = 1; + break; case 'c': config = optarg; break; @@ -270,10 +276,15 @@ main (int argc, char **argv) if (!quiet) printf ("Reading %s\n", box->path); - mail = maildir_open (box->path, fast); + i = 0; + if (fast) + i |= OPEN_FAST; + if (create) + i |= OPEN_CREATE; + mail = maildir_open (box->path, i); if (!mail) { - fprintf (stderr, "%s: unable to load mailbox\n", box->path); + fprintf (stderr, "ERROR: unable to load mailbox %s\n", box->path); goto cleanup; } @@ -326,7 +337,7 @@ main (int argc, char **argv) if (maildir_close (mail)) exit (1); -cleanup: + cleanup: if (all) box = box->next; }