From 21bf53b2ab0cc785f52ea4295bb0175a0238ed5f Mon Sep 17 00:00:00 2001 From: Michael Elkins Date: Thu, 21 Dec 2000 00:30:53 +0000 Subject: [PATCH] don't fetch deleted messages when expunging display number of messages that are to be deleted flags for \Recent messages were not properly fetched local messages with updated flags were not corrected renamed --- imap.c | 14 ++++++++++++-- isync.h | 7 ++++++- maildir.c | 10 ++++++---- main.c | 11 ++++++++--- sync.c | 29 ++++++++++++++++++++++++----- 5 files changed, 56 insertions(+), 15 deletions(-) diff --git a/imap.c b/imap.c index 6cb585e..1b1ec31 100644 --- a/imap.c +++ b/imap.c @@ -1,4 +1,6 @@ -/* isync - IMAP4 to maildir mailbox synchronizer +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer * Copyright (C) 2000 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify @@ -133,10 +135,15 @@ imap_exec (imap_t * imap, const char *fmt, ...) { if (!rec) { - rec = &imap->msgs; + rec = &imap->recent_msgs; while (*rec) rec = &(*rec)->next; } + /* need to add arg1 */ + *rec = calloc (1, sizeof (message_t)); + (*rec)->uid = atoi (arg1); + rec = &(*rec)->next; + /* parse rest of `cmd' */ while ((arg = next_arg (&cmd))) { *rec = calloc (1, sizeof (message_t)); @@ -189,7 +196,10 @@ imap_exec (imap_t * imap, const char *fmt, ...) else if (!strcmp ("\\Flagged", arg)) (*cur)->flags |= D_FLAGGED; else if (!strcmp ("\\Deleted", arg)) + { (*cur)->flags |= D_DELETED; + imap->deleted++; + } else if (!strcmp ("\\Answered", arg)) (*cur)->flags |= D_ANSWERED; else if (!strcmp ("\\Draft", arg)) diff --git a/isync.h b/isync.h index a2604e0..3545593 100644 --- a/isync.h +++ b/isync.h @@ -1,4 +1,6 @@ -/* isync - IMAP4 to maildir mailbox synchronizer +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer * Copyright (C) 2000 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify @@ -48,6 +50,7 @@ struct mailbox { char *path; message_t *msgs; + unsigned int deleted; /* # of deleted messages */ unsigned int changed:1; }; @@ -84,12 +87,14 @@ typedef struct message_t *recent_msgs; /* list of recent messages - only contains * UID to be used in a FETCH FLAGS command */ + unsigned int deleted; /* # of deleted messages */ } 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 */ extern config_t global; extern unsigned int Tag; diff --git a/maildir.c b/maildir.c index e4914d8..8c7e170 100644 --- a/maildir.c +++ b/maildir.c @@ -1,4 +1,6 @@ -/* isync - IMAP4 to maildir mailbox synchronizer +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer * Copyright (C) 2000 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify @@ -129,6 +131,8 @@ maildir_open (const char *path, int fast) s = strchr (p->file, ':'); if (s) parse_info (p, s + 1); + if (p->flags & D_DELETED) + m->deleted++; cur = &p->next; } closedir (d); @@ -189,10 +193,8 @@ maildir_sync (mailbox_t * mbox) if (p) *p = 0; - p = strrchr (cur->file, '/'); - /* generate new path */ - snprintf (path, sizeof (path), "%s/%s%s:2,%s%s%s%s", + snprintf (path, sizeof (path), "%s/%s/%s:2,%s%s%s%s", mbox->path, (cur->flags & D_SEEN) ? "cur" : "new", cur->file, (cur->flags & D_FLAGGED) ? "F" : "", (cur->flags & D_ANSWERED) ? "R" : "", diff --git a/main.c b/main.c index 85eb993..42f6bb1 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,6 @@ -/* isync - IMAP4 to maildir mailbox synchronizer +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer * Copyright (C) 2000 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify @@ -364,17 +366,20 @@ main (int argc, char **argv) i = 0; i |= (fast) ? SYNC_FAST : 0; i |= (delete) ? SYNC_DELETE : 0; + i |= (expunge) ? SYNC_EXPUNGE : 0; if (sync_mailbox (mail, imap, i)) exit (1); if (!fast) { - if (expunge) + if (expunge && (imap->deleted || mail->deleted)) { /* remove messages marked for deletion */ - puts ("Expunging messages"); + printf ("Expunging %d messages from server\n", imap->deleted); if (imap_expunge (imap)) exit (1); + printf ("Expunging %d messages from local mailbox\n", + mail->deleted); if (maildir_expunge (mail, 0)) exit (1); } diff --git a/sync.c b/sync.c index 001774a..61d68ac 100644 --- a/sync.c +++ b/sync.c @@ -1,4 +1,6 @@ -/* isync - IMAP4 to maildir mailbox synchronizer +/* $Id$ + * + * isync - IMAP4 to maildir mailbox synchronizer * Copyright (C) 2000 Michael R. Elkins * * This program is free software; you can redistribute it and/or modify @@ -56,6 +58,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) { cur->flags |= D_DELETED; cur->dead = 1; + mbox->deleted++; } continue; } @@ -69,9 +72,13 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) 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); /* 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; @@ -86,13 +93,20 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags) if (!cur->processed) { /* new message on server */ - fputs (".", stdout); - fflush (stdout); + + if ((flags & SYNC_EXPUNGE) && (cur->flags & D_DELETED)) + { + /* this message has been marked for deletion and + * we are currently expunging a mailbox. don't + * bother downloading this message + */ + continue; + } /* create new file */ snprintf (path, sizeof (path), "%s/tmp/%s.%ld_%d.%d.UID%d", - mbox->path, Hostname, time (0), MaildirCount++, - getpid (), cur->uid); + mbox->path, Hostname, time (0), MaildirCount++, + getpid (), cur->uid); if (cur->flags) { @@ -103,8 +117,13 @@ 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 */ + fputs (".", stdout); + fflush (stdout); + // printf("creating %s\n", path); fd = open (path, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd < 0)