From 0527181f45c8e74c2f6dcdb515ce348b76b8e44b Mon Sep 17 00:00:00 2001 From: Michael Elkins Date: Fri, 22 Dec 2000 07:14:32 +0000 Subject: [PATCH] added MaxSize configuration variable fixed --fast to work robustly without relying on the \Recent flag in messages --- ChangeLog | 50 ++++++++++++++ NEWS | 14 ++++ configure.in | 2 +- imap.c | 159 +++++++++++++++----------------------------- isync.1 | 15 +++-- isync.h | 17 +++-- isyncrc.sample | 2 + maildir.c | 174 +++++++++++++++++++++++++++++++++++++++++++++---- main.c | 19 ++++-- sync.c | 54 +++++++++------ 10 files changed, 347 insertions(+), 159 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddfa2f0..fdcd4bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,55 @@ 2000-12-21 Michael Elkins + * imap.c, isync.h, maildir.c, sync.c: + RFC822.PEEK is obsolete in RFC2060. Use BODY.PEEK[] instead, which does + the same thing + + keep track of the uidvalidity so isync can detect if the mailbox on the + server has changed since the last sync. + + * NEWS: updated NEWS for 0.3 release + + * Makefile.am, isync.spec: + added support for building RPMS + + * Makefile.am, isync.1: + added target for creating html version of the man page + + documented the imaps: prefix to the Host command + + * imap.c, sync.c: + can't assume flag order when fetching a message. just search for the + first `{' to find the message size. + + * isync.1, sync.c: + added BUGS section to manpage detailing the fact that we break the + maildir(5) spec by parsing the filename + + change message delivery to use the method described in maildir(5) + + * configure.in, main.c, sync.c: + use getpass() to get the user's password + + unlink the temp file if we are unable to fetch a new message from the + server. + + update version to 0.3 + + * isync.1: fixed typo in man page for --verbose option + + * Makefile.am, README, TODO, imap.c, isync.h, list.c: + added generic IMAP list parser and rewrote imap_exec() to handle + arbitrary data instead of hardcoded + + * Makefile.am, README, configure.in, main.c: + fixes to compile cleanly under Solaris 2.7 + + * configure.in, imap.c, isync.1, isync.h, main.c: + added OpenSSL support + + * ChangeLog, configure.in, main.c: + config options were not case insensitive + * imap.c, isync.h, maildir.c, main.c, sync.c: don't fetch deleted messages when expunging diff --git a/NEWS b/NEWS index 43f6fd1..de1c1b7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +[0.4] + +Added MaxSize configuration option to limit downloading of new messages from +the server to less than some threshold. + +More robust --fast option works without using \Recent flags, so the previous +problem with multiple accesses killing these flags is no longer a problem. + +RFC2060 obsoleted RFC822.PEEK, use BODY.PEEK[] instead which does the same +job. + +Don't need to request UID in a FETCH when doing UID FETCH (RFC2060 states +that its automatically returned). + [0.3] Fixed to clean up temp maildir files when the fetch of a new message failed. diff --git a/configure.in b/configure.in index 4a3d360..8907ac7 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_INIT(isync.h) -AM_INIT_AUTOMAKE(isync,0.3) +AM_INIT_AUTOMAKE(isync,0.4) AM_PROG_CC_STDC if test $CC = gcc; then CFLAGS="$CFLAGS -pipe" diff --git a/imap.c b/imap.c index c50f083..274c5fc 100644 --- a/imap.c +++ b/imap.c @@ -150,9 +150,13 @@ buffer_gets (buffer_t * b, char **s) } static int -parse_fetch (imap_t * imap, list_t * list, message_t * cur) +parse_fetch (imap_t * imap, list_t * list) { list_t *tmp; + unsigned int uid = 0; + unsigned int mask = 0; + unsigned int size = 0; + message_t *cur; if (!is_list (list)) return -1; @@ -165,7 +169,14 @@ parse_fetch (imap_t * imap, list_t * list, message_t * cur) { tmp = tmp->next; if (is_atom (tmp)) - cur->uid = atoi (tmp->val); + { + uid = atoi (tmp->val); + if (uid < imap->minuid) + { + /* already saw this message */ + return 0; + } + } else puts ("Error, unable to parse UID"); } @@ -181,20 +192,17 @@ parse_fetch (imap_t * imap, list_t * list, message_t * cur) if (is_atom (flags)) { if (!strcmp ("\\Seen", flags->val)) - cur->flags |= D_SEEN; + mask |= D_SEEN; else if (!strcmp ("\\Flagged", flags->val)) - cur->flags |= D_FLAGGED; + mask |= D_FLAGGED; else if (!strcmp ("\\Deleted", flags->val)) - { - cur->flags |= D_DELETED; - imap->deleted++; - } + mask |= D_DELETED; else if (!strcmp ("\\Answered", flags->val)) - cur->flags |= D_ANSWERED; + mask |= D_ANSWERED; else if (!strcmp ("\\Draft", flags->val)) - cur->flags |= D_DRAFT; + mask |= D_DRAFT; else if (!strcmp ("\\Recent", flags->val)) - cur->flags |= D_RECENT; + mask |= D_RECENT; else printf ("Warning, unknown flag %s\n", flags->val); @@ -206,8 +214,26 @@ parse_fetch (imap_t * imap, list_t * list, message_t * cur) else puts ("Error, unable to parse FLAGS"); } + else if (!strcmp ("RFC822.SIZE", tmp->val)) + { + tmp = tmp->next; + if (is_atom (tmp)) + size = atol (tmp->val); + } } } + + cur = calloc (1, sizeof (message_t)); + cur->next = imap->msgs; + imap->msgs = cur; + + if (mask & D_DELETED) + imap->deleted++; + + cur->uid = uid; + cur->flags = mask; + cur->size = size; + return 0; } @@ -246,8 +272,6 @@ imap_exec (imap_t * imap, const char *fmt, ...) char *cmd; char *arg; char *arg1; - message_t **cur = 0; - message_t **rec = 0; va_start (ap, fmt); vsnprintf (tmp, sizeof (tmp), fmt, ap); @@ -281,22 +305,6 @@ imap_exec (imap_t * imap, const char *fmt, ...) imap->ns_other = parse_list (cmd, &cmd); imap->ns_shared = parse_list (cmd, 0); } - else if (!strcmp ("SEARCH", arg)) - { - if (!rec) - { - rec = &imap->recent_msgs; - while (*rec) - rec = &(*rec)->next; - } - /* parse rest of `cmd' */ - while ((arg = next_arg (&cmd))) - { - *rec = calloc (1, sizeof (message_t)); - (*rec)->uid = atoi (arg); - rec = &(*rec)->next; - } - } else if (!strcmp ("OK", arg) || !strcmp ("BAD", arg) || !strcmp ("NO", arg) || !strcmp ("PREAUTH", arg) || !strcmp ("BYE", arg)) @@ -313,25 +321,15 @@ imap_exec (imap_t * imap, const char *fmt, ...) { list_t *list; - if (!cur) - { - cur = &imap->msgs; - while (*cur) - cur = &(*cur)->next; - } - list = parse_list (cmd, 0); - *cur = calloc (1, sizeof (message_t)); - if (parse_fetch (imap, list, *cur)) + if (parse_fetch (imap, list)) { free_list (list); return -1; } free_list (list); - - cur = &(*cur)->next; } } else @@ -357,66 +355,20 @@ imap_exec (imap_t * imap, const char *fmt, ...) /* not reached */ } -static int -fetch_recent_flags (imap_t * imap) -{ - char buf[1024]; - message_t **cur = &imap->recent_msgs; - message_t *tmp; - unsigned int start = -1; - unsigned int last = -1; - int ret = 0; - - buf[0] = 0; - while (*cur) - { - tmp = *cur; - - if (last == (unsigned int) -1) - { - /* init */ - start = tmp->uid; - last = tmp->uid; - } - else if (tmp->uid == last + 1) - last++; - else - { - /* out of sequence */ - if (start == last) - ret = imap_exec (imap, "UID FETCH %d (UID FLAGS)", start); - else - ret = - imap_exec (imap, "UID FETCH %d:%d (UID FLAGS)", start, - last); - start = tmp->uid; - last = tmp->uid; - } - free (tmp); - *cur = (*cur)->next; - } - - if (start != (unsigned int) -1) - { - if (start == last) - ret = imap_exec (imap, "UID FETCH %d (UID FLAGS)", start); - else - ret = - imap_exec (imap, "UID FETCH %d:%d (UID FLAGS)", start, last); - } - - return ret; -} - +/* `box' is the config info for the maildrop to sync. `minuid' is the + * minimum UID to consider. in normal mode this will be 1, but in --fast + * mode we only fetch messages newer than the last one seen in the local + * mailbox. + */ imap_t * -imap_open (config_t * box, int fast) +imap_open (config_t * box, unsigned int minuid) { int ret; imap_t *imap; int s; struct sockaddr_in sin; struct hostent *he; - char *ns_prefix = 0; + char *ns_prefix = ""; #if HAVE_LIBSSL int use_ssl = 0; #endif @@ -463,6 +415,7 @@ imap_open (config_t * box, int fast) imap->buf = calloc (1, sizeof (buffer_t)); imap->buf->sock = imap->sock; imap->box = box; + imap->minuid = minuid; #if HAVE_LIBSSL if (!box->use_imaps) @@ -520,28 +473,18 @@ imap_open (config_t * box, int fast) { fputs ("Selecting mailbox... ", stdout); fflush (stdout); - ret = imap_exec (imap, "SELECT %s%s", - ns_prefix ? ns_prefix : "", box->box); + ret = imap_exec (imap, "SELECT %s%s", ns_prefix, box->box); if (!ret) printf ("%d messages, %d recent\n", imap->count, imap->recent); } if (!ret) { - if (fast) + puts ("Reading IMAP mailbox index"); + if (imap->count > 0) { - if (imap->recent > 0) - { - puts ("Fetching info for recent messages"); - ret = imap_exec (imap, "UID SEARCH RECENT"); - if (!ret) - ret = fetch_recent_flags (imap); - } - } - else if (imap->count > 0) - { - puts ("Reading IMAP mailbox index"); - ret = imap_exec (imap, "FETCH 1:%d (UID FLAGS)", imap->count); + ret = imap_exec (imap, "UID FETCH %d:* (FLAGS RFC822.SIZE)", + imap->minuid); } } diff --git a/isync.1 b/isync.1 index 8f97795..1be053b 100644 --- a/isync.1 +++ b/isync.1 @@ -66,12 +66,6 @@ Causes to skip the step of synchronzing message flags between the local maildir mailbox and the IMAP mailbox. Only new messages existing on the server will be fetched into the local mailbox. -.B NOTE: -This command works by checking the \\Recent flag on messages in the IMAP -mailbox. If you access the IMAP mailbox from multiple locations, the -\\Recent flag will be lost between sessions, so you must do a full -synchronization to fetch the messages which do not exist in the local -mailbox. .TP .B -h, --help Displays a summary of command line options @@ -158,6 +152,15 @@ Defines an alias for the mailbox which can be used as a shortcut on the command line. .. .TP +\fBMaxSize\fR \fIbytes\fR +Sets a threshold for the maximum message size (in bytes) for which +.B isync +should fetch from the server. This is useful for weeding out messages with +large attachments. If +.I bytes +is 0, the maximum file size is +.B unlimited. +.TP \fBRequireSSL\fR \fIyes|no\fR .B isync will abort the connection if a TLS/SSL session to the IMAP diff --git a/isync.h b/isync.h index d4ef130..a968ead 100644 --- a/isync.h +++ b/isync.h @@ -54,6 +54,7 @@ struct config char *pass; char *box; char *alias; + unsigned int max_size; config_t *next; #if HAVE_LIBSSL char *cert_file; @@ -69,7 +70,9 @@ struct mailbox message_t *msgs; unsigned int deleted; /* # of deleted messages */ unsigned int uidvalidity; + unsigned int maxuid; /* largest uid we know about */ unsigned int changed:1; + unsigned int maxuidchanged:1; }; /* message dispositions */ @@ -86,6 +89,7 @@ struct message char *file; unsigned int uid; unsigned int flags; + unsigned int size; message_t *next; unsigned int processed:1; /* message has already been evaluated */ unsigned int new:1; /* message is in the new/ subdir */ @@ -119,6 +123,8 @@ typedef struct */ unsigned int deleted; /* # of deleted messages */ unsigned int uidvalidity; + unsigned int maxuid; + unsigned int minuid; /* NAMESPACE info */ list_t *ns_personal; list_t *ns_other; @@ -127,9 +133,8 @@ typedef struct imap_t; /* flags for sync_mailbox */ -#define SYNC_FAST (1<<0) /* don't sync flags, only fetch new msgs */ -#define SYNC_DELETE (1<<1) /* delete local that don't exist on server */ -#define SYNC_EXPUNGE (1<<2) /* don't fetch deleted messages */ +#define SYNC_DELETE (1<<0) /* delete local that don't exist on server */ +#define SYNC_EXPUNGE (1<<1) /* don't fetch deleted messages */ extern config_t global; extern unsigned int Tag; @@ -142,19 +147,21 @@ extern SSL_CTX *SSLContext; char *next_arg (char **); -int sync_mailbox (mailbox_t *, imap_t *, int); +int sync_mailbox (mailbox_t *, imap_t *, int, unsigned int); void imap_close (imap_t *); int imap_fetch_message (imap_t *, unsigned int, int); int imap_set_flags (imap_t *, unsigned int, unsigned int); int imap_expunge (imap_t *); -imap_t *imap_open (config_t *, int); +imap_t *imap_open (config_t *, unsigned int); mailbox_t *maildir_open (const char *, int fast); int maildir_expunge (mailbox_t *, int); int maildir_sync (mailbox_t *); int maildir_set_uidvalidity (mailbox_t *, unsigned int uidvalidity); +message_t * find_msg (message_t * list, unsigned int uid); + /* parse an IMAP list construct */ list_t * parse_list (char *s, char **end); int is_atom (list_t *list); diff --git a/isyncrc.sample b/isyncrc.sample index 90c4442..a170c18 100644 --- a/isyncrc.sample +++ b/isyncrc.sample @@ -6,6 +6,8 @@ User me #Port 143 #Box INBOX +# don't download messages larger than 200K bytes +MaxSize 200000 ### ### work mailbox diff --git a/maildir.c b/maildir.c index a03c5bd..558d4d6 100644 --- a/maildir.c +++ b/maildir.c @@ -25,8 +25,38 @@ #include #include #include +#include +#include #include "isync.h" +static int +do_lock (int fd, int flag) +{ + struct flock lck; + struct stat sb; + + if (fstat (fd, &sb)) + { + perror ("fstat"); + return -1; + } + + memset (&lck, 0, sizeof (lck)); + lck.l_type = flag; + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = sb.st_size; + + if (fcntl (fd, F_SETLK, &lck)) + { + perror ("fcntl"); + close (fd); + return -1; + } + + return 0; +} + /* 2, */ static void parse_info (message_t * m, char *s) @@ -49,6 +79,45 @@ parse_info (message_t * m, char *s) } } +static unsigned int +read_uid (const char *path, const char *file) +{ + char full[_POSIX_PATH_MAX]; + int fd; + int ret; + int len; + char buf[64]; + unsigned int uid = 0; + + snprintf (full, sizeof (full), "%s/%s", path, file); + fd = open (full, O_RDONLY); + if (fd == -1) + { + if (errno != ENOENT) + { + perror ("open"); + return -1; + } + return 0; /* doesn't exist */ + } + ret = do_lock (fd, F_RDLCK); + if (!ret) + { + len = read (fd, buf, sizeof (buf) - 1); + if (len == -1) + ret = -1; + else + { + buf[len] = 0; + uid = atol (buf); + } + } + ret |= do_lock (fd, F_UNLCK); + close (fd); + return ret ? ret : uid; + +} + /* open a maildir mailbox. if `fast' is nonzero, 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, @@ -66,7 +135,6 @@ maildir_open (const char *path, int fast) mailbox_t *m; char *s; int count = 0; - FILE *fp; /* check to make sure this looks like a valid maildir box */ snprintf (buf, sizeof (buf), "%s/new", path); @@ -84,16 +152,22 @@ maildir_open (const char *path, int fast) m = calloc (1, sizeof (mailbox_t)); m->path = strdup (path); - m->uidvalidity = -1; /* check for the uidvalidity value */ - snprintf (buf, sizeof (buf), "%s/isyncuidvalidity", path); - if ((fp = fopen (buf, "r"))) + m->uidvalidity = read_uid (path, "isyncuidvalidity"); + if (m->uidvalidity == (unsigned int) -1) { - buf[sizeof (buf) - 1] = 0; - if (fgets (buf, sizeof (buf) - 1, fp)) - m->uidvalidity = atol (buf); - fclose (fp); + free (m->path); + free (m); + return NULL; + } + + /* load the current maxuid */ + if ((m->maxuid = read_uid (path, "isyncmaxuid")) == (unsigned int) -1) + { + free (m->path); + free (m); + return NULL; } if (fast) @@ -108,6 +182,8 @@ maildir_open (const char *path, int fast) d = opendir (buf); if (!d) { + free (m->path); + free (m); perror ("opendir"); return 0; } @@ -130,10 +206,15 @@ maildir_open (const char *path, int fast) */ s = strstr (p->file, "UID"); if (!s) - puts ("warning, no uid for message"); + puts ("Warning, no uid for message"); else { p->uid = strtol (s + 3, &s, 10); + if (p->uid > m->maxuid) + { + m->maxuid = p->uid; + m->maxuidchanged = 1; + } if (*s && *s != ':') { puts ("warning, unable to parse uid"); @@ -183,6 +264,70 @@ maildir_expunge (mailbox_t * mbox, int dead) return 0; } +static int +update_maxuid (mailbox_t * mbox) +{ + int fd; + char buf[64]; + size_t len; + unsigned int uid; + char path[_POSIX_PATH_MAX]; + int ret = 0; + + snprintf (path, sizeof (path), "%s/isyncmaxuid", mbox->path); + fd = open (path, O_RDWR | O_CREAT, 0600); + if (fd == -1) + { + perror ("open"); + return -1; + } + + /* lock the file */ + if (do_lock (fd, F_WRLCK)) + { + close (fd); + return -1; + } + + /* read the file again just to make sure it wasn't updated while + * we were doing something else + */ + len = read (fd, buf, sizeof (buf) - 1); + buf[len] = 0; + uid = atol (buf); + if (uid > mbox->maxuid) + { + puts ("Error, maxuid is now higher (fatal)"); + ret = -1; + } + + if (!ret) + { + /* rewind */ + lseek (fd, 0, SEEK_SET); + + /* write out the file */ + snprintf (buf, sizeof (buf), "%u\n", mbox->maxuid); + len = write (fd, buf, strlen (buf)); + if (len == (size_t) - 1) + { + perror ("write"); + ret = -1; + } + else + { + ret = ftruncate (fd, len); + if (ret) + perror ("ftruncate"); + } + } + + ret |= do_lock (fd, F_UNLCK); + ret |= close (fd); + + return ret; +} + int maildir_sync (mailbox_t * mbox) { @@ -190,6 +335,7 @@ maildir_sync (mailbox_t * mbox) char path[_POSIX_PATH_MAX]; char oldpath[_POSIX_PATH_MAX]; char *p; + int ret = 0; if (mbox->changed) { @@ -219,7 +365,11 @@ maildir_sync (mailbox_t * mbox) } } } - return 0; + + if (mbox->maxuidchanged) + ret = update_maxuid (mbox); + + return ret; } int @@ -242,7 +392,7 @@ maildir_set_uidvalidity (mailbox_t * mbox, unsigned int uidvalidity) ret = write (fd, buf, strlen (buf)); if (ret == -1) - perror("write"); + perror ("write"); else if ((size_t) ret != strlen (buf)) ret = -1; else @@ -250,7 +400,7 @@ maildir_set_uidvalidity (mailbox_t * mbox, unsigned int uidvalidity) if (close (fd)) { - perror("close"); + perror ("close"); ret = -1; } diff --git a/main.c b/main.c index 368a96e..4cd79d2 100644 --- a/main.c +++ b/main.c @@ -95,6 +95,7 @@ config_defaults (config_t * conf) conf->port = global.port; conf->box = global.box; conf->host = global.host; + conf->max_size = global.max_size; #if HAVE_LIBSSL conf->require_ssl = global.require_ssl; conf->use_imaps = global.use_imaps; @@ -206,6 +207,13 @@ load_config (char *where) if (*cur) (*cur)->alias = strdup (p); } + else if (!strncasecmp ("maxsize", buf, 7)) + { + if (*cur) + (*cur)->max_size = atol (p); + else + global.max_size = atol (p); + } #if HAVE_LIBSSL else if (!strncasecmp ("CertificateFile", buf, 15)) { @@ -285,6 +293,7 @@ main (int argc, char **argv) global.port = 143; global.box = "INBOX"; global.user = strdup (pw->pw_name); + global.max_size = 100000; #if HAVE_LIBSSL /* this will probably annoy people, but its the best default just in * case people forget to turn it on @@ -380,16 +389,14 @@ main (int argc, char **argv) exit (1); } - imap = imap_open (box, fast); + imap = imap_open (box, fast ? mail->maxuid + 1 : 1); if (!imap) exit (1); puts ("Synchronizing"); - i = 0; - i |= (fast) ? SYNC_FAST : 0; - i |= (delete) ? SYNC_DELETE : 0; - i |= (expunge) ? SYNC_EXPUNGE : 0; - if (sync_mailbox (mail, imap, i)) + i = delete ? SYNC_DELETE : 0; + i |= expunge ? SYNC_EXPUNGE : 0; + if (sync_mailbox (mail, imap, i, box->max_size)) exit (1); if (!fast) diff --git a/sync.c b/sync.c index 73bee17..4cee760 100644 --- a/sync.c +++ b/sync.c @@ -31,7 +31,7 @@ static unsigned int MaildirCount = 0; -static message_t * +message_t * find_msg (message_t * list, unsigned int uid) { for (; list; list = list->next) @@ -41,7 +41,7 @@ find_msg (message_t * list, unsigned int uid) } int -sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) +sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags, unsigned int max_size) { message_t *cur; message_t *tmp; @@ -69,12 +69,21 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) return -1; } + if (mbox->maxuid == (unsigned int) -1 || imap->maxuid > mbox->maxuid) + { + mbox->maxuid = imap->maxuid; + mbox->maxuidchanged = 1; + } + + /* if we are --fast mode, the mailbox wont have been loaded, so + * this next step is skipped. + */ for (cur = mbox->msgs; cur; cur = cur->next) { tmp = find_msg (imap->msgs, cur->uid); if (!tmp) { - printf ("warning, uid %d doesn't exist on server\n", cur->uid); + printf ("Warning, uid %d doesn't exist on server\n", cur->uid); if (flags & SYNC_DELETE) { cur->flags |= D_DELETED; @@ -85,25 +94,22 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) } tmp->processed = 1; - if (!(flags & SYNC_FAST)) + /* check if local flags are different from server flags. + * ignore \Recent and \Draft + */ + if (cur->flags != (tmp->flags & ~(D_RECENT | D_DRAFT))) { - /* check if local flags are different from server flags. - * ignore \Recent and \Draft - */ - if (cur->flags != (tmp->flags & ~(D_RECENT | D_DRAFT))) - { - /* set local flags that don't exist on the server */ - if (!(tmp->flags & D_DELETED) && (cur->flags & D_DELETED)) - imap->deleted++; - imap_set_flags (imap, cur->uid, cur->flags & ~tmp->flags); + /* set local flags that don't exist on the server */ + if (!(tmp->flags & D_DELETED) && (cur->flags & D_DELETED)) + imap->deleted++; + imap_set_flags (imap, cur->uid, cur->flags & ~tmp->flags); - /* update local flags */ - if((cur->flags & D_DELETED) == 0 && (tmp->flags & D_DELETED)) - mbox->deleted++; - cur->flags |= (tmp->flags & ~(D_RECENT | D_DRAFT)); - cur->changed = 1; - mbox->changed = 1; - } + /* update local flags */ + if((cur->flags & D_DELETED) == 0 && (tmp->flags & D_DELETED)) + mbox->deleted++; + cur->flags |= (tmp->flags & ~(D_RECENT | D_DRAFT)); + cur->changed = 1; + mbox->changed = 1; } } @@ -124,6 +130,13 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) continue; } + if (max_size && cur->size > max_size) + { + printf ("Warning, message skipped because it is too big (%u)\n", + cur->size); + continue; + } + for (;;) { /* create new file */ @@ -150,7 +163,6 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) (cur->flags & D_ANSWERED) ? "R" : "", (cur->flags & D_SEEN) ? "S" : "", (cur->flags & D_DELETED) ? "T" : ""); - } /* give some visual feedback that something is happening */