Commit 4a151fd8 4a151fd82add56d993437bcceb969a7cf8dd3bdf by Sergey Poznyakoff

Bugfixes.

* imap4d/util.c (util_parse_internal_date): Use MU_DATETIME_INTERNALDATE
format.
* include/mailutils/util.h (MU_DATETIME_IMAP_SEARCH): Rename to
MU_DATETIME_INTERNALDATE (previous incorrect definition removed).
(MU_DATETIME_RFC822): New format.
* libmailutils/address/address.c: Accessors for local_part and
domain invalidate email field.
(validate_email): New static function.
(mu_address_sget_email): Reconstruct email, if necessary.
(mu_address_format_string): Likewise.
* libmailutils/base/date.c (mu_c_streamftime): Allow for %$ specifier
for compatibility with mu_scan_datetime.
(mu_scan_datetime): Use %$ to idicate optional end of string.
* libmailutils/tests/scantime.at: Update.
* libproto/imap/fetch.c (_fill_response): Use MU_DATETIME_RFC822 format.
* mu/imap.c (fetch_response_printer): Print subject.
1 parent 93717359
......@@ -374,7 +374,7 @@ util_parse_internal_date (char *date, time_t *timep,
mu_timezone tz;
time_t time;
if (mu_scan_datetime (date, MU_DATETIME_IMAP_SEARCH, &tm, &tz, NULL))
if (mu_scan_datetime (date, MU_DATETIME_INTERNALDATE, &tm, &tz, NULL))
return 1;
adjust_tm (&tm, &tz, flag);
......
......@@ -74,8 +74,9 @@ int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm,
/* Common datetime formats: */
#define MU_DATETIME_FROM "%a %b %e %H:%M:%S %Y"
#define MU_DATETIME_IMAP "%d-%b-%Y %H:%M:%S %z"
#define MU_DATETIME_IMAP_SEARCH "%d-%b-%Y%? %H:%M:%S %z"
#define MU_DATETIME_INTERNALDATE "%a, %e %b %Y %H:%M:%S %z"
#define MU_DATETIME_INTERNALDATE "%d-%b-%Y%$ %H:%M:%S %z"
/* FIXME: [%a, ] part is actually optional */
#define MU_DATETIME_RFC822 "%a, %e %b %Y %H:%M:%S %z"
/* ----------------------- */
......
......@@ -253,9 +253,14 @@ ACCESSOR(set, field) (mu_address_t addr, size_t no, const char *buf) \
if (!subaddr) \
return MU_ERR_NOENT; \
\
if (buf) \
{ \
s = strdup (buf); \
if (!s) \
return errno; \
} \
else \
s = (char *) buf; \
\
free (subaddr->field); \
subaddr->field = s; \
......@@ -263,6 +268,38 @@ ACCESSOR(set, field) (mu_address_t addr, size_t no, const char *buf) \
return 0; \
}
#define DECL_SET_EI(field) \
int \
ACCESSOR(set, field) (mu_address_t addr, size_t no, const char *buf) \
{ \
char *s; \
mu_address_t subaddr; \
\
if (addr == NULL) \
return EINVAL; \
\
subaddr = _address_get_nth (addr, no); \
if (!subaddr) \
return MU_ERR_NOENT; \
\
if (buf) \
{ \
s = strdup (buf); \
if (!s) \
return errno; \
} \
else \
s = (char *) buf; \
\
free (subaddr->field); \
subaddr->field = s; \
\
free (subaddr->email); \
subaddr->email = NULL; \
\
return 0; \
}
#define DECL_SGET(field) \
int \
ACCESSOR(sget,field) (mu_address_t addr, size_t no, char const **sptr) \
......@@ -324,21 +361,127 @@ DECL_SGET(field) \
DECL_GET(field) \
DECL_AGET(field)
#define DECL_ACCESSORS_EI(field) \
DECL_SET_EI(field) \
DECL_SGET(field) \
DECL_GET(field) \
DECL_AGET(field)
/* Personal part */
DECL_ACCESSORS(personal)
/* Comments */
DECL_ACCESSORS(comments)
/* Email */
DECL_ACCESSORS(email)
/* Local part */
DECL_ACCESSORS(local_part)
DECL_ACCESSORS_EI(local_part)
/* Domain */
DECL_ACCESSORS(domain)
DECL_ACCESSORS_EI(domain)
/* Route */
DECL_ACCESSORS(route)
/* Email */
int
mu_address_set_email (mu_address_t addr, size_t no, const char *buf)
{
char *s;
mu_address_t subaddr;
if (addr == NULL)
return EINVAL;
subaddr = _address_get_nth (addr, no);
if (!subaddr)
return MU_ERR_NOENT;
if (buf)
{
s = strdup (buf);
if (!s)
return errno;
}
else
s = (char *) buf;
free (subaddr->email);
subaddr->email = s;
free (subaddr->local_part);
free (subaddr->domain);
if (s)
{
char *p = strchr (subaddr->email, '@');
if (p)
{
size_t len = p - subaddr->email;
subaddr->local_part = malloc (len + 1);
if (subaddr->local_part)
{
memcpy (subaddr->local_part, p, len);
subaddr->local_part[len] = 0;
}
subaddr->domain = strdup (p + 1);
}
}
else
{
subaddr->local_part = NULL;
subaddr->domain = NULL;
}
return 0;
}
static int
validate_email (mu_address_t subaddr)
{
if (!subaddr->email)
{
if (subaddr->local_part)
{
const char *domain;
if (subaddr->domain)
domain = subaddr->domain;
else
mu_get_user_email_domain (&domain);
if (domain)
{
char *p;
subaddr->email = malloc (strlen (subaddr->local_part) +
strlen (domain) + 2);
if (!subaddr->email)
return ENOMEM;
p = mu_stpcpy (subaddr->email, subaddr->local_part);
*p++ = '@';
mu_stpcpy (p, (char*) domain);
}
}
}
return 0;
}
int
mu_address_sget_email (mu_address_t addr, size_t no, char const **sptr)
{
mu_address_t subaddr;
if (addr == NULL)
return EINVAL;
subaddr = _address_get_nth (addr, no);
if (!subaddr)
return MU_ERR_NOENT;
validate_email (subaddr);
*sptr = subaddr->email;
return 0;
}
DECL_GET(email)
DECL_AGET(email)
#define format_char(c) do {\
......@@ -370,6 +513,7 @@ mu_address_format_string (mu_address_t addr, char *buf, size_t buflen)
for (;addr; addr = addr->next)
{
validate_email (addr);
if (addr->email)
{
int space = 0;
......@@ -601,4 +745,3 @@ mu_address_union (mu_address_t *a, mu_address_t b)
}
return 0;
}
......
......@@ -516,6 +516,10 @@ mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm,
rc = mu_stream_write (str, "%", 1, NULL);
break;
case '$':
/* Ignored for compatibilty with mu_scan_datetime */
break;
case '+':
/* Not supported (date and time in date(1) format. */
default:
......@@ -849,7 +853,7 @@ mu_scan_datetime (const char *input, const char *fmt,
rc = MU_ERR_PARSE;
break;
case '?':
case '$':
eof_ok = 1;
break;
}
......
......@@ -47,7 +47,7 @@ sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,tz=3600
])
SCANTIME([IMAP search time format],[imap-search],
[%d-%b-%Y%? %H:%M:%S %z],
[%d-%b-%Y%$ %H:%M:%S %z],
[03-May-2011 13:25:26 +0100
03-May-2011],
[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=3600
......
......@@ -472,7 +472,7 @@ _fill_response (void *item, void *data)
else
{
if (mu_scan_datetime (elt->v.string,
MU_DATETIME_IMAP,
MU_DATETIME_RFC822,
&env->envelope->date,
&env->envelope->tz, NULL))
rc = MU_ERR_FAILURE;
......
......@@ -266,6 +266,9 @@ fetch_response_printer (void *item, void *data)
mu_stream_printf (str, "ENVELOPE:\n");
format_date (str, "date", &resp->envelope.date, &resp->envelope.tz);
mu_stream_printf (str, " subject = %s\n",
resp->envelope.subject ?
resp->envelope.subject : "NIL");
format_email (str, "from", resp->envelope.from);
format_email (str, "sender", resp->envelope.sender);
......