Commit 1f40b359 1f40b3595aa75e25bab1f1f868b67774e7569743 by Alain Magloire

ChangeLog : updated.

imap4d/fetch.c : ENVELOPE implemented.

mailbox/address.c : Remove quotes FIXME: need a rewriting to do proper
RFC822 address parsing.

mailbox/folder_imap.c mailbox/mbx_imap.c mailbox/mbx_mbox.c
mailbox/include/imap0.h  : various fixes, not critical.
1 parent 5188cb9d
2001-02-28 Alain Magloire
* mailbox/address.c (address_get_personal) : Remove surrounding quotes.
* mailbox/mbx_mbox.c (mbox_scan) : If the mailbox is updated don't
rescan again.
(mbox_expunge) : Same the uidvalidity in the header field "IMABase:"
on the first message of the mailbox.
* imap4d/fetch.c (fetch_envelope) : Envelope imap4 command implemented.
(fetch_send_address) : New function.
2001-02-26 Alain Magloire
* mailbox/mbx_imap.c (imap_submessage_size) : New function to
......
......@@ -46,6 +46,7 @@ static int fetch_body_peek (struct imap4d_command *, char*);
static int fetch_body (struct imap4d_command *, char*);
static int fetch_uid (struct imap4d_command *, char*);
static int fetch_send_address (char *addr);
static int fetch_operation (size_t, char *);
struct imap4d_command fetch_command_table [] =
......@@ -164,6 +165,59 @@ fetch_fast (struct imap4d_command *command, char *arg)
return 0;
}
static int
fetch_send_address (char *addr)
{
address_t address;
size_t i, count = 0;
if (*addr == '\0')
{
util_send ("NIL");
return 0;
}
address_create (&address, addr);
address_get_count (address, &count);
util_send ("(", count);
for (i = 1; i <= count; i++)
{
char buf[128];
char *at;
size_t len = 0;
util_send ("(");
*buf = '\0';
address_get_personal (address, 1, buf, sizeof (buf), NULL);
if (*buf == '\0')
util_send ("NIL ");
else
util_send ("\"%s\" ", buf);
/* FIXME: Source route. */
util_send ("NIL ", buf);
*buf = '\0';
address_get_email (address, 1, buf, sizeof (buf), &len);
if (*buf == '\0')
strcpy (buf, "NIL");
at = memchr (buf, '@', len);
if (at)
{
*at = '\0';
at++;
util_send ("\"%s\" \"%s\"", buf, at);
}
else
util_send ("\"%s\" NIL", buf);
util_send (")");
}
util_send (")");
return 0;
}
/* Header: Date, Subject, From, Sender, Reply-To, To, Cc, Bcc, In-Reply-To,
and Message-Id. */
/* FIXME, FIXME:
......@@ -175,68 +229,79 @@ static int
fetch_envelope (struct imap4d_command *command, char *arg)
{
char buffer[512];
char from[128];
header_t header = NULL;
message_t msg = NULL;
int status;
/* FIXME: K&R compilers will choke at this, initializing local arrays was
not permitted. Even AIX xlc use to choke. */
mailbox_get_message (mbox, command->states, &msg);
message_get_header (msg, &header);
util_send (" %s", command->name);
util_send (" %s(", command->name);
/* FIXME: Incorrect Date. */
status = header_get_value (header, "Date", buffer, sizeof (buffer), NULL);
if (status != 0)
util_send (" NIL");
*buffer = '\0';
header_get_value (header, "Date", buffer, sizeof (buffer), NULL);
if (*buffer == '\0')
util_send ("NIL");
else
util_send (" \"%s\"", buffer);
util_send ("\"%s\"", buffer);
util_send (" ");
status = header_get_value (header, "Subject", buffer, sizeof (buffer), NULL);
if (status != 0)
util_send (" NIL");
/* Subject. */
*buffer = '\0';
header_get_value (header, "Subject", buffer, sizeof (buffer), NULL);
if (*buffer == '\0')
util_send ("NIL");
else
util_send (" \"%s\"", buffer);
util_send ("\"%s\"", buffer);
util_send (" ");
*buffer = '\0';
header_get_value (header, "From", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
/* FIXME:
Note that the server MUST default the reply-to and sender fields from
/* From. */
*from = '\0';
header_get_value (header, "From", from, sizeof (from), NULL);
fetch_send_address (from);
util_send (" ");
/* Note that the server MUST default the reply-to and sender fields from
the from field; a client is not expected to know to do this. */
*buffer = '\0';
header_get_value (header, "Sender", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
fetch_send_address ((*buffer == '\0') ? from : buffer);
util_send (" ");
*buffer = '\0';
header_get_value (header, "Reply-to", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
fetch_send_address ((*buffer == '\0') ? from : buffer);
util_send (" ");
*buffer = '\0';
header_get_value (header, "To", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
fetch_send_address (buffer);
util_send (" ");
*buffer = '\0';
header_get_value (header, "Cc", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
fetch_send_address (buffer);
util_send (" ");
*buffer = '\0';
header_get_value (header, "Bcc", buffer, sizeof (buffer), NULL);
util_send (" ((NIL NIL NIL \"%s\"))", buffer);
fetch_send_address (buffer);
util_send (" ");
status = header_get_value (header, "In-Reply-To", buffer,
sizeof (buffer), NULL);
if (status != 0)
util_send (" NIL");
else
util_send (" \"%s\"", buffer);
*buffer = '\0';
header_get_value (header, "In-Reply-To", buffer, sizeof (buffer), NULL);
fetch_send_address (buffer);
util_send (" ");
status = header_get_value (header, "Message-ID", buffer,
sizeof (buffer), NULL);
if (status != 0)
util_send (" NIL");
*buffer = '\0';
header_get_value (header, "Message-ID", buffer, sizeof (buffer), NULL);
if (*buffer == '\0')
util_send ("NIL");
else
util_send (" \"%s\"", buffer);
util_send ("\"%s\"", buffer);
util_send (")");
return 0;
}
......
......@@ -47,6 +47,7 @@
#include <mailutils/message.h>
#include <mailutils/header.h>
#include <mailutils/body.h>
#include <mailutils/address.h>
#include <mailutils/registrar.h>
#ifdef __cplusplus
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
......@@ -352,17 +352,29 @@ address_get_personal (address_t addr, size_t no, char *buf, size_t len,
int status = EINVAL;
if (addr == NULL)
return EINVAL;
for (j = 1; addr; addr = addr->next, j++)
for (i = 0, j = 1; addr; addr = addr->next, j++)
{
if (j == no)
{
i = _cpystr (buf, addr->personal, len);
if (n)
*n = i;
status = 0;
break;
}
}
/* Remove the leading doublequotes. */
if (i && buf && *buf == '"')
{
memmove (buf, buf + 1, i - 1);
i--;
}
/* Remove the trailing doublequotes. */
if (i && buf && buf[i - 1] == '"')
{
buf[i - 1] = '\0';
i--;
}
if (n)
*n = i;
return status;
}
......@@ -415,6 +427,8 @@ address_to_string (address_t addr, char *buf, size_t len, size_t *n)
size_t i;
if (addr == NULL)
return EINVAL;
if (buf)
*buf = '\0';
i = _cpystr (buf, addr->addr, len);
if (n)
*n = i;
......
......@@ -50,6 +50,8 @@ static struct _record _imap_record =
record_t imap_record = &_imap_record;
/* Concrete IMAP implementation. */
static int folder_imap_open __P ((folder_t, int));
static int folder_imap_close __P ((folder_t));
static void folder_imap_destroy __P ((folder_t));
static int folder_imap_delete __P ((folder_t, const char *));
static int folder_imap_list __P ((folder_t, const char *, const char *,
......@@ -193,7 +195,7 @@ imap_user (authority_t auth)
}
/* Create/Open the stream for IMAP. */
int
static int
folder_imap_open (folder_t folder, int flags)
{
f_imap_t f_imap = folder->data;
......@@ -204,8 +206,13 @@ folder_imap_open (folder_t folder, int flags)
int preauth = 0; /* Do we have "preauth"orisation ? */
/* If we are already open for business, noop. */
monitor_wrlock (folder->monitor);
if (f_imap->isopen)
{
monitor_wrlock (folder->monitor);
return 0;
}
monitor_unlock (folder->monitor);
/* Fetch the pop server name and the port in the url_t. */
status = url_get_host (folder->url, NULL, 0, &len);
......@@ -312,17 +319,28 @@ folder_imap_open (folder_t folder, int flags)
break;
}
f_imap->state = IMAP_NO_STATE;
f_imap->isopen = 1;
monitor_wrlock (folder->monitor);
f_imap->isopen++;
monitor_unlock (folder->monitor);
return 0;
}
/* Shutdown the connection. */
int
static int
folder_imap_close (folder_t folder)
{
f_imap_t f_imap = folder->data;
int status = 0;
monitor_wrlock (folder->monitor);
f_imap->isopen--;
if (f_imap->isopen)
{
monitor_unlock (folder->monitor);
return 0;
}
monitor_unlock (folder->monitor);
switch (f_imap->state)
{
case IMAP_NO_STATE:
......@@ -1814,7 +1832,9 @@ imap_parse (f_imap_t f_imap)
{
/* We should close the stream. This is not recoverable. */
done = 1;
monitor_wrlock (f_imap->folder->monitor);
f_imap->isopen = 0;
monitor_unlock (f_imap->folder->monitor);
stream_close (f_imap->folder->stream);
}
else if (strcasecmp (response, "CAPABILITY") == 0)
......
......@@ -192,9 +192,6 @@ struct _msg_imap
size_t header_lines;
};
int folder_imap_open __P ((folder_t, int));
int folder_imap_close __P ((folder_t));
int imap_writeline __P ((f_imap_t, const char *format, ...));
int imap_write __P ((f_imap_t));
int imap_send __P ((f_imap_t));
......
......@@ -254,7 +254,7 @@ mailbox_imap_close (mailbox_t mailbox)
f_imap->selected = NULL;
f_imap->state = IMAP_NO_STATE;
return status;
return folder_close (mailbox->folder);
}
/* Construction of the message_t, nothing else is done then this setup. To
......
......@@ -416,6 +416,8 @@ mbox_close (mailbox_t mailbox)
mud->umessages = NULL;
mud->messages_count = mud->umessages_count = 0;
mud->size = 0;
mud->uidvalidity = 0;
mud->uidnext = 0;
monitor_unlock (mailbox->monitor);
return stream_close (mailbox->stream);
}
......@@ -428,9 +430,24 @@ mbox_close (mailbox_t mailbox)
static int
mbox_scan (mailbox_t mailbox, size_t msgno, size_t *pcount)
{
size_t i;
mbox_data_t mud = mailbox->data;
MAILBOX_DEBUG1 (mailbox, MU_DEBUG_TRACE, "mbox_scan(%s)\n", mud->name);
if (! mbox_is_updated (mailbox))
return mbox_scan0 (mailbox, msgno, pcount, 1);
/* Since the mailbox is already updated fake the scan. */
if (msgno > 0)
msgno--; /* The fist message is number "1", decremente for the C array. */
for (i = msgno; i < mud->messages_count; i++)
{
if (observable_notify (mailbox->observable, MU_EVT_MESSAGE_ADD) != 0)
break;
if (((i +1) % 50) == 0)
{
observable_notify (mailbox->observable, MU_EVT_MAILBOX_PROGRESS);
}
}
return 0;
}
/* FIXME: How to handle a shrink ? meaning, the &^$^@%#@^& user start two
......@@ -653,10 +670,14 @@ mbox_expunge (mailbox_t mailbox)
if (ATTRIBUTE_IS_DELETED (mum->attr_flags))
{
/* We save the uidvalidity in the first message, if it is being
deleted we need to the header to the first available(non-deleted)
message. */
if (i == 0)
deleted we need to move the uidvalidity to the first available
(non-deleted) message. */
if (i == save_imapbase)
{
save_imapbase = i + 1;
if (save_imapbase < mud->messages_count)
(mud->umessages[save_imapbase])->attr_flags |= MU_ATTRIBUTE_MODIFIED;
}
continue;
}
......