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"
/* ----------------------- */
......
......@@ -13,7 +13,7 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
......@@ -213,11 +213,11 @@ mu_address_concatenate (mu_address_t to, mu_address_t *from)
return 0;
}
mu_address_t
mu_address_t
_address_get_nth (mu_address_t addr, size_t no)
{
int i;
for (i = 1; addr; addr = addr->next, i++)
if (i == no)
break;
......@@ -239,13 +239,13 @@ mu_address_get_nth (mu_address_t addr, size_t no, mu_address_t *pret)
#define AC4(a,b,c,d) a ## b ## c ## d
#define ACCESSOR(action,field) AC4(mu_address_,action,_,field)
#define DECL_SET(field) \
#define DECL_SET(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; \
\
......@@ -253,22 +253,59 @@ ACCESSOR(set, field) (mu_address_t addr, size_t no, const char *buf) \
if (!subaddr) \
return MU_ERR_NOENT; \
\
s = strdup (buf); \
if (!s) \
return errno; \
\
if (buf) \
{ \
s = strdup (buf); \
if (!s) \
return errno; \
} \
else \
s = (char *) buf; \
\
free (subaddr->field); \
subaddr->field = s; \
\
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) \
{ \
mu_address_t subaddr; \
\
\
if (addr == NULL) \
return EINVAL; \
\
......@@ -287,7 +324,7 @@ ACCESSOR(get,field) (mu_address_t addr, size_t no, char *buf, size_t len, \
size_t i; \
const char *str; \
int status = ACCESSOR(sget, field) (addr, no, &str); \
\
\
if (status) \
return status; \
\
......@@ -322,7 +359,13 @@ ACCESSOR(aget, field) (mu_address_t addr, size_t no, char **buf) \
DECL_SET(field) \
DECL_SGET(field) \
DECL_GET(field) \
DECL_AGET(field)
DECL_AGET(field)
#define DECL_ACCESSORS_EI(field) \
DECL_SET_EI(field) \
DECL_SGET(field) \
DECL_GET(field) \
DECL_AGET(field)
......@@ -330,15 +373,115 @@ DECL_AGET(field)
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 {\
......@@ -349,7 +492,7 @@ DECL_ACCESSORS(route)
}\
else\
rc++;\
} while(0)
} while(0)
#define format_string(str) do {\
if (buflen) \
......@@ -361,22 +504,23 @@ DECL_ACCESSORS(route)
else\
rc += strlen (str);\
} while (0)
size_t
mu_address_format_string (mu_address_t addr, char *buf, size_t buflen)
{
int rc = 0;
int comma = 0;
for (;addr; addr = addr->next)
{
validate_email (addr);
if (addr->email)
{
int space = 0;
if (comma)
format_char (',');
if (addr->personal)
{
format_char ('"');
......@@ -384,7 +528,7 @@ mu_address_format_string (mu_address_t addr, char *buf, size_t buflen)
format_char ('"');
space++;
}
if (addr->comments)
{
if (space)
......@@ -394,7 +538,7 @@ mu_address_format_string (mu_address_t addr, char *buf, size_t buflen)
format_char (')');
space++;
}
if (space)
format_char (' ');
format_char ('<');
......@@ -435,14 +579,14 @@ int
mu_address_is_group (mu_address_t addr, size_t no, int *yes)
{
mu_address_t subaddr;
if (addr == NULL)
return EINVAL;
subaddr = _address_get_nth (addr, no);
if (!subaddr)
return MU_ERR_NOENT;
if (yes)
*yes = _address_is_group (subaddr);
return 0;
......@@ -465,7 +609,7 @@ mu_address_to_string (mu_address_t addr, char *buf, size_t len, size_t *n)
return ENOMEM;
mu_address_format_string (addr, addr->addr, i+1);
}
i = mu_cpystr (buf, addr->addr, len);
if (n)
*n = i;
......@@ -562,12 +706,12 @@ mu_address_dup (mu_address_t src)
return dst;
}
int
mu_address_union (mu_address_t *a, mu_address_t b)
{
mu_address_t last = NULL;
if (!a || !b)
return EINVAL;
......@@ -601,4 +745,3 @@ mu_address_union (mu_address_t *a, mu_address_t b)
}
return 0;
}
......
......@@ -515,6 +515,10 @@ mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm,
/* A literal '%' character. */
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. */
......@@ -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);
......