Commit e7ce526d e7ce526d1f0903065333ffd88bb9379be3d78c34 by Alain Magloire

* mailbox/folder_imap.c (imap_flags): Bailout at the matching

	LPAREN.
	* mailbox/header.c (header_get_fvalue): Return 0 in the
	number of byte return argument even when no header is found.
	(header_get_value): Likewised.

	* mailbox/mbx_imap.c (imap_header_get_fvalue): Also cache
	the message size and the FLAGS.
	(imap_message_size): If we already have the size do not request
	it again.
1 parent 0de08a30
2001-10-05 Alain Magloire
* mailbox/folder_imap.c (imap_flags): Bailout at the matching
LPAREN.
* mailbox/header.c (header_get_fvalue): Return 0 in the
number of byte return argument even when no header is found.
(header_get_value): Likewised.
* mailbox/mbx_imap.c (imap_header_get_fvalue): Also cache
the message size and the FLAGS.
(imap_message_size): If we already have the size do not request
it again.
2001-10-05 Sergey Poznyakoff
* guimb/scm/Makefile.am: Added reject.scm.
* mailbox/parse822.c: (parse822_word): Additional check
for qstr != NULL: parse822_quoted_string() sometimes returns
EOK and does not fill qstr (e.g. when parsing empty string: "")
2001-10-04 Alain Magloire
* imap4d/select.c(imap4_select_status): According to RFC2060
......
......@@ -1232,34 +1232,42 @@ imap_bodystructure (f_imap_t f_imap, char **ptr)
static int
imap_flags (f_imap_t f_imap, char **ptr)
{
char *flag;
char *start_flag;
char *end_flag;
/* msg_imap may be null for an untag response deal with it. */
msg_imap_t msg_imap = f_imap->callback.msg_imap;
/* Skip space. */
while (**ptr == ' ')
(*ptr)++;
/* Skip LPAREN. */
if (**ptr == '(')
(*ptr)++;
for (;**ptr && **ptr != ')'; ++(*ptr))
/* Go through the list and break on ')' */
do
{
/* Skip space before next word. */
while (**ptr == ' ')
(*ptr)++;
/* Save the beginning of the word. */
flag = *ptr;
start_flag = *ptr;
/* Get the next word boundary. */
while (**ptr && **ptr != ' ' && **ptr != ')')
++*ptr;
++(*ptr);
/* Make a C string for the strcasecmp. */
**ptr = '\0';
end_flag = *ptr;
/* Bail out. */
if (*flag == '\0')
if (*start_flag == '\0')
break;
/* Guess the flag. */
if (strcasecmp (flag, "\\Seen") == 0)
if (strncasecmp (start_flag, "\\Seen", end_flag - start_flag) == 0)
{
if (msg_imap)
{
......@@ -1269,28 +1277,28 @@ imap_flags (f_imap_t f_imap, char **ptr)
else
f_imap->flags |= MU_ATTRIBUTE_SEEN;
}
else if (strcasecmp (flag, "\\Answered") == 0)
else if (strncasecmp (start_flag, "\\Answered", end_flag - start_flag) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_ANSWERED;
else
f_imap->flags |= MU_ATTRIBUTE_ANSWERED;
}
else if (strcasecmp (flag, "\\Flagged") == 0)
else if (strncasecmp (start_flag, "\\Flagged", end_flag - start_flag) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_FLAGGED;
else
f_imap->flags |= MU_ATTRIBUTE_FLAGGED;
}
else if (strcasecmp (flag, "\\Deleted") == 0)
else if (strncasecmp (start_flag, "\\Deleted", end_flag - start_flag) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_DELETED;
else
f_imap->flags |= MU_ATTRIBUTE_DELETED;
}
else if (strcasecmp (flag, "\\Draft") == 0)
else if (strncasecmp (start_flag, "\\Draft", end_flag - start_flag) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_DRAFT;
......@@ -1298,6 +1306,9 @@ imap_flags (f_imap_t f_imap, char **ptr)
f_imap->flags |= MU_ATTRIBUTE_DRAFT;
}
}
while (**ptr && **ptr != ')');
if (**ptr == ')')
(*ptr)++;
return 0;
}
......@@ -1306,6 +1317,7 @@ imap_body (f_imap_t f_imap, char **ptr)
{
int status;
/* Skip leading spaces. */
while (**ptr && **ptr == ' ')
(*ptr)++;
......@@ -1322,8 +1334,10 @@ imap_body (f_imap_t f_imap, char **ptr)
section[len] = '\0';
/* strupper. */
for (; *p; p++)
if (isalpha((unsigned)*p))
*p = toupper ((unsigned)*p);
{
if (isalpha((unsigned)*p))
*p = toupper ((unsigned)*p);
}
/* Check to see the callback type to update the line count. */
if (!strstr (section, "FIELD"))
{
......
......@@ -409,23 +409,24 @@ header_get_fvalue (header_t header, const char *name, char *buffer,
for (i = 0, name_len = strlen (name); i < header->fhdr_count; i++)
{
fn_len = header->fhdr[i].fn_end - header->fhdr[i].fn;
if (fn_len == name_len
&& strcasecmp (header->fhdr[i].fn, name) == 0)
if (fn_len == name_len && strcasecmp (header->fhdr[i].fn, name) == 0)
{
fv_len = header->fhdr[i].fv_end - header->fhdr[i].fv;
/* Permanent failure. */
/* Permanent failure: If the field exist but the value is NULL
It is a way to notify that the field dow not exist.
The value EINVAL is return no ENOENT to let header_get_value()
know about the error. */
if (fv_len == 0)
return EINVAL;
if (buffer && buflen > 0)
err = EINVAL;
else if (buffer && buflen > 0)
{
buflen--;
fv_len = (fv_len < buflen) ? fv_len : buflen;
memcpy (buffer, header->fhdr[i].fv, fv_len);
buffer[fv_len] = '\0';
err = 0;
}
err = 0;
break;
}
}
......@@ -452,11 +453,13 @@ header_get_value (header_t header, const char *name, char *buffer,
err = header_get_fvalue (header, name, buffer, buflen, pn);
switch (err)
{
case ENOENT:
break; /* Do not give up just yet. */
case EINVAL: /* Permanent failure. */
return ENOENT;
case 0:
return 0;
case ENOMEM:
err = ENOENT;
default:
if (err && pn)
*pn = 0;
return err;
}
......
......@@ -1008,7 +1008,7 @@ imap_message_size (message_t msg, size_t *psize)
msg_imap_t msg_imap = message_get_owner (msg);
m_imap_t m_imap = msg_imap->m_imap;
f_imap_t f_imap = m_imap->f_imap;
int status;
int status = 0;;
/* If there is a parent it means it is a sub message, IMAP does not give
the full size of mime messages, so the message_size retrieved from
......@@ -1018,22 +1018,27 @@ imap_message_size (message_t msg, size_t *psize)
return imap_submessage_size (msg_imap, psize);
}
/* Select first. */
if (f_imap->state == IMAP_NO_STATE)
if (msg_imap->message_size == 0)
{
status = imap_messages_count (m_imap->mailbox, NULL);
if (status != 0)
return status;
/* We strip the \r, but the offset/size on the imap server is with that
octet so add it in the offset, since it's the number of lines. */
status = imap_writeline (f_imap,
"g%d FETCH %d RFC822.SIZE\r\n",
f_imap->seq++, msg_imap->num);
CHECK_ERROR (f_imap, status);
MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer);
f_imap->state = IMAP_FETCH;
/* Select first. */
if (f_imap->state == IMAP_NO_STATE)
{
status = imap_messages_count (m_imap->mailbox, NULL);
if (status != 0)
return status;
/* We strip the \r, but the offset/size on the imap server is with
that octet so add it in the offset, since it's the number of
lines. */
status = imap_writeline (f_imap,
"g%d FETCH %d RFC822.SIZE\r\n",
f_imap->seq++, msg_imap->num);
CHECK_ERROR (f_imap, status);
MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer);
f_imap->state = IMAP_FETCH;
}
status = message_operation (f_imap, msg_imap, 0, 0, 0);
}
status = message_operation (f_imap, msg_imap, 0, 0, 0);
if (status == 0)
{
if (psize)
......@@ -1583,10 +1588,11 @@ imap_header_get_fvalue (header_t header, const char *field, char * buffer,
status = imap_messages_count (m_imap->mailbox, NULL);
if (status != 0)
return status;
#define CACHE_HEADERS "Bcc Cc Content-Language Content-Transfer-Encoding Content-Type Date From In-Reply-To Message-ID Reference Reply-To Sender Subject To X-UIDL"
#define MU_IMAP_CACHE_HEADERS "Bcc Cc Content-Language Content-Transfer-Encoding Content-Type Date From In-Reply-To Message-ID Reference Reply-To Sender Subject To X-UIDL"
status = imap_writeline (f_imap,
"g%d FETCH %d BODY.PEEK[HEADER.FIELDS (%s)]\r\n",
f_imap->seq++, msg_imap->num, CACHE_HEADERS);
"g%d FETCH %d FLAGS RFC822.SIZE BODY.PEEK[HEADER.FIELDS (%s)]\r\n",
f_imap->seq++, msg_imap->num,
MU_IMAP_CACHE_HEADERS);
CHECK_ERROR (f_imap, status);
MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer);
f_imap->state = IMAP_FETCH;
......