Bläddra i källkod

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

Michael Elkins 23 år sedan
förälder
incheckning
3fe6f3f086
6 ändrade filer med 102 tillägg och 31 borttagningar
  1. 2 1
      Makefile.am
  2. 3 0
      NEWS
  3. 9 4
      isync.1
  4. 5 1
      isync.h
  5. 68 21
      maildir.c
  6. 15 4
      main.c

+ 2 - 1
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

+ 3 - 0
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

+ 9 - 4
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>.

+ 5 - 1
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 *);

+ 68 - 21
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);
 	}
     }
 }

+ 15 - 4
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;
     }