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
This commit is contained in:
Michael Elkins 2001-11-20 18:06:09 +00:00
parent f0c7fdf008
commit 3fe6f3f086
6 changed files with 102 additions and 31 deletions

View File

@ -1,5 +1,6 @@
bin_PROGRAMS=isync 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_LDADD=@DEBUGOBJ@
isync_DEPENDENCIES=@DEBUGOBJ@ isync_DEPENDENCIES=@DEBUGOBJ@
EXTRA_isync_SOURCES=debug.c EXTRA_isync_SOURCES=debug.c

3
NEWS
View File

@ -3,6 +3,9 @@
Added `MaxMessages' configuration option to allow tracking of only the most Added `MaxMessages' configuration option to allow tracking of only the most
recently added message in the local mailbox. 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] [0.6]
Added `Delete' configuration option to correspond to the -d command line Added `Delete' configuration option to correspond to the -d command line

13
isync.1
View File

@ -1,6 +1,6 @@
.ig .ig
\" isync - IMAP4 to maildir mailbox synchronizer \" 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 \" 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 \" 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 \" along with this program; if not, write to the Free Software
\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \" 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 .SH NAME
isync - synchronize IMAP4 and maildir mailboxes isync - synchronize IMAP4 and maildir mailboxes
@ -43,6 +43,10 @@ all flags are synchronized.
\fB-a\fR, \fB--all\fR \fB-a\fR, \fB--all\fR
Synchronize all mailboxes specified in the user's ~/.isyncrc. Synchronize all mailboxes specified in the user's ~/.isyncrc.
.TP .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 \fB-c\fR, \fB--config\fR \fIfile\fR
Read configuration from Read configuration from
.I file .I file
@ -206,7 +210,8 @@ deleted.
If If
.I count .I count
is 0, the maximum number of messages is is 0, the maximum number of messages is
.B unlimited (Default: 0). .B unlimited
(Default: 0).
.. ..
.TP .TP
\fBMaxSize\fR \fIbytes\fR \fBMaxSize\fR \fIbytes\fR
@ -328,7 +333,7 @@ mutt(1), maildir(5)
Up to date information on Up to date information on
.B isync .B isync
can be found at can be found at
http://www.sigpipe.org/isync/. http://www.sigpipe.org:8080/isync/.
.. ..
.SH AUTHOR .SH AUTHOR
Written by Michael R. Elkins <me@mutt.org>. Written by Michael R. Elkins <me@mutt.org>.

View File

@ -155,6 +155,10 @@ imap_t;
#define SYNC_EXPUNGE (1<<1) /* don't fetch deleted messages */ #define SYNC_EXPUNGE (1<<1) /* don't fetch deleted messages */
#define SYNC_QUIET (1<<2) /* only display critical errors */ #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 global;
extern config_t *boxes; extern config_t *boxes;
extern unsigned int Tag; extern unsigned int Tag;
@ -184,7 +188,7 @@ int imap_expunge (imap_t *);
imap_t *imap_open (config_t *, unsigned int, imap_t *); imap_t *imap_open (config_t *, unsigned int, imap_t *);
int imap_append_message (imap_t *, int, message_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_expunge (mailbox_t *, int);
int maildir_set_uidvalidity (mailbox_t *, unsigned int uidvalidity); int maildir_set_uidvalidity (mailbox_t *, unsigned int uidvalidity);
int maildir_close (mailbox_t *); int maildir_close (mailbox_t *);

View File

@ -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 * 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, * 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 * so we can save a lot of time when the user just wants to fetch new messages
* without syncing the flags. * without syncing the flags.
* if OPEN_CREATE is set, we create the mailbox if it doesn't already exist.
*/ */
mailbox_t * mailbox_t *
maildir_open (const char *path, int fast) maildir_open (const char *path, int flags)
{ {
char buf[_POSIX_PATH_MAX]; char buf[_POSIX_PATH_MAX];
DIR *d; DIR *d;
@ -136,27 +138,68 @@ maildir_open (const char *path, int fast)
mailbox_t *m; mailbox_t *m;
char *s; char *s;
int count = 0; int count = 0;
struct stat sb;
const char *subdirs[] = { "cur", "new", "tmp" };
int i;
m = calloc (1, sizeof (mailbox_t)); m = calloc (1, sizeof (mailbox_t));
/* filename expansion happens here, not in the config parser */ /* filename expansion happens here, not in the config parser */
m->path = expand_strdup (path); m->path = expand_strdup (path);
/* check to make sure this looks like a valid maildir box */ if (stat (m->path, &sb))
snprintf (buf, sizeof (buf), "%s/new", m->path);
if (access (buf, F_OK))
{ {
free (m->path); if (errno == ENOENT && (flags & OPEN_CREATE))
free (m); {
perror ("access"); if (mkdir (m->path, S_IRUSR | S_IWUSR | S_IXUSR))
return 0; {
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); else
if (access (buf, F_OK))
{ {
free (m->path); /* check to make sure this looks like a valid maildir box */
free (m); for (i = 0; i < 3; i++)
perror ("access"); {
return 0; 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 */ /* check for the uidvalidity value */
@ -176,7 +219,7 @@ maildir_open (const char *path, int fast)
return NULL; return NULL;
} }
if (fast) if (flags & OPEN_FAST)
return m; return m;
cur = &m->msgs; cur = &m->msgs;
@ -224,11 +267,11 @@ maildir_open (const char *path, int fast)
m->maxuidchanged = 1; m->maxuidchanged = 1;
} }
/* Courier-IMAP names it files /* 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 * so we need to put the UID before the size, hence here
* we check for a comma as a valid terminator as well, * we check for a comma as a valid terminator as well,
* since the format will be * since the format will be
* unique,U=<uid>,S=<size>:info * unique,U=<uid>,S=<size>:info
*/ */
if (*s && *s != ':' && *s != ',') if (*s && *s != ':' && *s != ',')
{ {
@ -358,7 +401,8 @@ maildir_clean_tmp (const char *mbox)
dirp = opendir (path); dirp = opendir (path);
if (dirp == NULL) 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; return;
} }
/* assuming this scan will take less than a second, we only need to /* 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); snprintf (path, sizeof (path), "%s/tmp/%s", mbox, entry->d_name);
if (stat (path, &info)) 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) else if (S_ISREG (info.st_mode) && now - info.st_ctime >= _24_HOURS)
{ {
/* this should happen infrequently enough that it won't be /* 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); printf ("Warning: removing stale file %s\n", path);
if (unlink (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);
} }
} }
} }

19
main.c
View File

@ -35,6 +35,7 @@
struct option Opts[] = { struct option Opts[] = {
{"all", 0, NULL, 'a'}, {"all", 0, NULL, 'a'},
{"config", 1, NULL, 'c'}, {"config", 1, NULL, 'c'},
{"create", 0, NULL, 'C'},
{"delete", 0, NULL, 'd'}, {"delete", 0, NULL, 'd'},
{"expunge", 0, NULL, 'e'}, {"expunge", 0, NULL, 'e'},
{"fast", 0, NULL, 'f'}, {"fast", 0, NULL, 'f'},
@ -70,6 +71,7 @@ usage (void)
printf ("usage: %s [ flags ] mailbox [mailbox ...]\n", PACKAGE); printf ("usage: %s [ flags ] mailbox [mailbox ...]\n", PACKAGE);
puts (" -a, --all Synchronize all defined mailboxes"); puts (" -a, --all Synchronize all defined mailboxes");
puts (" -c, --config CONFIG read an alternate config file (default: ~/.isyncrc)"); 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 (" -d, --delete delete local msgs that don't exist on the server");
puts (" -e, --expunge expunge deleted messages from the server"); puts (" -e, --expunge expunge deleted messages from the server");
puts (" -f, --fast only fetch new messages"); puts (" -f, --fast only fetch new messages");
@ -141,6 +143,7 @@ main (int argc, char **argv)
struct passwd *pw; struct passwd *pw;
int quiet = 0; int quiet = 0;
int all = 0; int all = 0;
int create = 0;
pw = getpwuid (getuid ()); pw = getpwuid (getuid ());
@ -163,7 +166,7 @@ main (int argc, char **argv)
global.use_tlsv1 = 1; global.use_tlsv1 = 1;
#endif #endif
#define FLAGS "ac:defhp:qu:r:s:vV" #define FLAGS "aCc:defhp:qu:r:s:vV"
#if HAVE_GETOPT_LONG #if HAVE_GETOPT_LONG
while ((i = getopt_long (argc, argv, FLAGS, Opts, NULL)) != -1) while ((i = getopt_long (argc, argv, FLAGS, Opts, NULL)) != -1)
@ -176,6 +179,9 @@ main (int argc, char **argv)
case 'a': case 'a':
all = 1; all = 1;
break; break;
case 'C':
create = 1;
break;
case 'c': case 'c':
config = optarg; config = optarg;
break; break;
@ -270,10 +276,15 @@ main (int argc, char **argv)
if (!quiet) if (!quiet)
printf ("Reading %s\n", box->path); 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) 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; goto cleanup;
} }
@ -326,7 +337,7 @@ main (int argc, char **argv)
if (maildir_close (mail)) if (maildir_close (mail))
exit (1); exit (1);
cleanup: cleanup:
if (all) if (all)
box = box->next; box = box->next;
} }