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.
This commit is contained in:
parent
145e4ef84d
commit
a8f9af4296
46
imap.c
46
imap.c
|
@ -150,7 +150,7 @@ buffer_gets (buffer_t * b, char **s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_fetch (imap_t * imap, list_t * list, message_t *cur)
|
parse_fetch (imap_t * imap, list_t * list, message_t * cur)
|
||||||
{
|
{
|
||||||
list_t *tmp;
|
list_t *tmp;
|
||||||
|
|
||||||
|
@ -196,7 +196,8 @@ parse_fetch (imap_t * imap, list_t * list, message_t *cur)
|
||||||
else if (!strcmp ("\\Recent", flags->val))
|
else if (!strcmp ("\\Recent", flags->val))
|
||||||
cur->flags |= D_RECENT;
|
cur->flags |= D_RECENT;
|
||||||
else
|
else
|
||||||
printf ("Warning, unknown flag %s\n",flags->val);
|
printf ("Warning, unknown flag %s\n",
|
||||||
|
flags->val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
puts ("Error, unable to parse FLAGS list");
|
puts ("Error, unable to parse FLAGS list");
|
||||||
|
@ -210,6 +211,32 @@ parse_fetch (imap_t * imap, list_t * list, message_t *cur)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_response_code (imap_t * imap, char *s)
|
||||||
|
{
|
||||||
|
char *arg;
|
||||||
|
|
||||||
|
if (*s != '[')
|
||||||
|
return; /* no response code */
|
||||||
|
s++;
|
||||||
|
|
||||||
|
arg = next_arg (&s);
|
||||||
|
|
||||||
|
if (!strcmp ("UIDVALIDITY", arg))
|
||||||
|
{
|
||||||
|
arg = next_arg (&s);
|
||||||
|
imap->uidvalidity = atol (arg);
|
||||||
|
}
|
||||||
|
else if (!strcmp ("ALERT", arg))
|
||||||
|
{
|
||||||
|
/* RFC2060 says that these messages MUST be displayed
|
||||||
|
* to the user
|
||||||
|
*/
|
||||||
|
fputs ("***ALERT*** ", stdout);
|
||||||
|
puts (s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imap_exec (imap_t * imap, const char *fmt, ...)
|
imap_exec (imap_t * imap, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -270,6 +297,12 @@ imap_exec (imap_t * imap, const char *fmt, ...)
|
||||||
rec = &(*rec)->next;
|
rec = &(*rec)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcmp ("OK", arg) || !strcmp ("BAD", arg) ||
|
||||||
|
!strcmp ("NO", arg) || !strcmp ("PREAUTH", arg) ||
|
||||||
|
!strcmp ("BYE", arg))
|
||||||
|
{
|
||||||
|
parse_response_code (imap, cmd);
|
||||||
|
}
|
||||||
else if ((arg1 = next_arg (&cmd)))
|
else if ((arg1 = next_arg (&cmd)))
|
||||||
{
|
{
|
||||||
if (!strcmp ("EXISTS", arg1))
|
if (!strcmp ("EXISTS", arg1))
|
||||||
|
@ -289,7 +322,7 @@ imap_exec (imap_t * imap, const char *fmt, ...)
|
||||||
|
|
||||||
list = parse_list (cmd, 0);
|
list = parse_list (cmd, 0);
|
||||||
|
|
||||||
*cur = calloc (1, sizeof(message_t));
|
*cur = calloc (1, sizeof (message_t));
|
||||||
if (parse_fetch (imap, list, *cur))
|
if (parse_fetch (imap, list, *cur))
|
||||||
{
|
{
|
||||||
free_list (list);
|
free_list (list);
|
||||||
|
@ -315,6 +348,7 @@ imap_exec (imap_t * imap, const char *fmt, ...)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arg = next_arg (&cmd);
|
arg = next_arg (&cmd);
|
||||||
|
parse_response_code (imap, cmd);
|
||||||
if (!strcmp ("OK", arg))
|
if (!strcmp ("OK", arg))
|
||||||
return 0;
|
return 0;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -474,8 +508,8 @@ imap_open (config_t * box, int fast)
|
||||||
{
|
{
|
||||||
/* XXX for now assume personal namespace */
|
/* XXX for now assume personal namespace */
|
||||||
if (is_list (imap->ns_personal) &&
|
if (is_list (imap->ns_personal) &&
|
||||||
is_list(imap->ns_personal->child) &&
|
is_list (imap->ns_personal->child) &&
|
||||||
is_atom(imap->ns_personal->child->child))
|
is_atom (imap->ns_personal->child->child))
|
||||||
{
|
{
|
||||||
ns_prefix = imap->ns_personal->child->child->val;
|
ns_prefix = imap->ns_personal->child->child->val;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +609,7 @@ imap_fetch_message (imap_t * imap, unsigned int uid, int fd)
|
||||||
size_t n;
|
size_t n;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
send_server (imap->sock, "UID FETCH %d (RFC822.PEEK)", uid);
|
send_server (imap->sock, "UID FETCH %d BODY.PEEK[]", uid);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
3
isync.h
3
isync.h
|
@ -68,6 +68,7 @@ struct mailbox
|
||||||
char *path;
|
char *path;
|
||||||
message_t *msgs;
|
message_t *msgs;
|
||||||
unsigned int deleted; /* # of deleted messages */
|
unsigned int deleted; /* # of deleted messages */
|
||||||
|
unsigned int uidvalidity;
|
||||||
unsigned int changed:1;
|
unsigned int changed:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,6 +118,7 @@ typedef struct
|
||||||
* UID to be used in a FETCH FLAGS command
|
* UID to be used in a FETCH FLAGS command
|
||||||
*/
|
*/
|
||||||
unsigned int deleted; /* # of deleted messages */
|
unsigned int deleted; /* # of deleted messages */
|
||||||
|
unsigned int uidvalidity;
|
||||||
/* NAMESPACE info */
|
/* NAMESPACE info */
|
||||||
list_t *ns_personal;
|
list_t *ns_personal;
|
||||||
list_t *ns_other;
|
list_t *ns_other;
|
||||||
|
@ -151,6 +153,7 @@ imap_t *imap_open (config_t *, int);
|
||||||
mailbox_t *maildir_open (const char *, int fast);
|
mailbox_t *maildir_open (const char *, int fast);
|
||||||
int maildir_expunge (mailbox_t *, int);
|
int maildir_expunge (mailbox_t *, int);
|
||||||
int maildir_sync (mailbox_t *);
|
int maildir_sync (mailbox_t *);
|
||||||
|
int maildir_set_uidvalidity (mailbox_t *, unsigned int uidvalidity);
|
||||||
|
|
||||||
/* parse an IMAP list construct */
|
/* parse an IMAP list construct */
|
||||||
list_t * parse_list (char *s, char **end);
|
list_t * parse_list (char *s, char **end);
|
||||||
|
|
52
maildir.c
52
maildir.c
|
@ -66,6 +66,7 @@ maildir_open (const char *path, int fast)
|
||||||
mailbox_t *m;
|
mailbox_t *m;
|
||||||
char *s;
|
char *s;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
/* check to make sure this looks like a valid maildir box */
|
/* check to make sure this looks like a valid maildir box */
|
||||||
snprintf (buf, sizeof (buf), "%s/new", path);
|
snprintf (buf, sizeof (buf), "%s/new", path);
|
||||||
|
@ -80,8 +81,20 @@ maildir_open (const char *path, int fast)
|
||||||
perror ("access");
|
perror ("access");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = calloc (1, sizeof (mailbox_t));
|
m = calloc (1, sizeof (mailbox_t));
|
||||||
m->path = strdup (path);
|
m->path = strdup (path);
|
||||||
|
m->uidvalidity = -1;
|
||||||
|
|
||||||
|
/* check for the uidvalidity value */
|
||||||
|
snprintf (buf, sizeof (buf), "%s/isyncuidvalidity", path);
|
||||||
|
if ((fp = fopen (buf, "r")))
|
||||||
|
{
|
||||||
|
buf[sizeof (buf) - 1] = 0;
|
||||||
|
if (fgets (buf, sizeof (buf) - 1, fp))
|
||||||
|
m->uidvalidity = atol (buf);
|
||||||
|
fclose (fp);
|
||||||
|
}
|
||||||
|
|
||||||
if (fast)
|
if (fast)
|
||||||
return m;
|
return m;
|
||||||
|
@ -208,3 +221,42 @@ maildir_sync (mailbox_t * mbox)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
maildir_set_uidvalidity (mailbox_t * mbox, unsigned int uidvalidity)
|
||||||
|
{
|
||||||
|
char path[_POSIX_PATH_MAX];
|
||||||
|
char buf[16];
|
||||||
|
int fd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
snprintf (path, sizeof (path), "%s/isyncuidvalidity", mbox->path);
|
||||||
|
fd = open (path, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
perror ("open");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
snprintf (buf, sizeof (buf), "%u\n", uidvalidity);
|
||||||
|
|
||||||
|
ret = write (fd, buf, strlen (buf));
|
||||||
|
|
||||||
|
if (ret == -1)
|
||||||
|
perror("write");
|
||||||
|
else if ((size_t) ret != strlen (buf))
|
||||||
|
ret = -1;
|
||||||
|
else
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
if (close (fd))
|
||||||
|
{
|
||||||
|
perror("close");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
if (unlink (path))
|
||||||
|
perror ("unlink");
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
17
sync.c
17
sync.c
|
@ -52,6 +52,23 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags)
|
||||||
int ret;
|
int ret;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
|
if (mbox->uidvalidity != (unsigned int) -1)
|
||||||
|
{
|
||||||
|
if (mbox->uidvalidity != imap->uidvalidity)
|
||||||
|
{
|
||||||
|
/* if the UIDVALIDITY value has changed, it means all our
|
||||||
|
* local UIDs are invalid, so we can't sync.
|
||||||
|
*/
|
||||||
|
puts ("Error, UIDVALIDITY changed on server (fatal)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (maildir_set_uidvalidity (mbox, imap->uidvalidity))
|
||||||
|
{
|
||||||
|
puts ("Error, unable to store UIDVALIDITY");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (cur = mbox->msgs; cur; cur = cur->next)
|
for (cur = mbox->msgs; cur; cur = cur->next)
|
||||||
{
|
{
|
||||||
tmp = find_msg (imap->msgs, cur->uid);
|
tmp = find_msg (imap->msgs, cur->uid);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user