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)