Commit 93717359 937173596bd77d773c3fc8330a1ebbe2c8c13df6 by Sergey Poznyakoff

Implement mu_scan_datetime.

* include/mailutils/stream.h (mu_fixed_memory_stream_create): New proto.
* libmailutils/stream/memory_stream.c
(mu_fixed_memory_stream_create): New function.

* include/mailutils/util.h (mu_parse_imap_date_time)
(mu_parse_ctime_date_time): Remove.
(mu_scan_datetime): New proto.
(mu_strftime): Remove const from the last arg.
(MU_DATETIME_FROM,MU_DATETIME_IMAP)
(MU_DATETIME_IMAP_SEARCH,MU_DATETIME_INTERNALDATE): New defines.
* libmailutils/base/strftime.c: New file.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Add strftime.c.
* libmailutils/base/date.c (mu_scan_datetime): New function.
* libmailutils/base/mutil.c (mu_strftime): Remove.

* libmailutils/tests/scantime.at: New file.
* libmailutils/tests/scantime.c: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add scantime.
(TESTSUITE_AT): Add scantime.at.
* libmailutils/tests/strftime.c (main): Call mu_set_program_name.
* libmailutils/tests/testsuite.at: Include scantime.at

* libmu_sieve/actions.c (mime_create_reason): Use mu_c_streamftime.

* imap4d/fetch.c (_frt_internaldate): Use mu_scan_datetime.
* imap4d/util.c (util_parse_internal_date): Likewise.
* libmu_scm/mu_message.c (mu-message-get-envelope-date): Likewise.
* libproto/imap/fetch.c (_date_mapper): Likewise.
* mail/from.c (hdr_date): Use mu_scan_datetime.
1 parent 025c888a
......@@ -960,16 +960,12 @@ _frt_internaldate (struct fetch_function_closure *ffc,
mu_envelope_t env = NULL;
struct tm tm, *tmp = NULL;
mu_timezone tz;
char datebuf[sizeof ("13-Jul-2002 00:00:00")];
int tzoff;
int tzh = 0, tzm = 0;
mu_message_get_envelope (frt->msg, &env);
if (mu_envelope_sget_date (env, &date) == 0
&& mu_parse_ctime_date_time (&date, &tm, &tz) == 0)
&& mu_scan_datetime (date, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
{
tmp = &tm;
tzoff = tz.utc_offset;
}
else
{
......@@ -977,18 +973,13 @@ _frt_internaldate (struct fetch_function_closure *ffc,
struct timeval stv;
struct timezone stz;
gettimeofday(&stv, &stz);
gettimeofday (&stv, &stz);
t = stv.tv_sec;
tzoff = - stz.tz_minuteswest;
tz.utc_offset = - stz.tz_minuteswest;
tmp = localtime (&t);
}
tzh = tzoff / 3600;
if (tzoff < 0)
tzoff = - tzoff;
tzm = tzoff % 3600;
mu_strftime (datebuf, sizeof (datebuf), "%d-%b-%Y %H:%M:%S", tmp);
io_sendf ("%s", ffc->name);
io_sendf (" \"%s %+03d%02d\"", datebuf, tzh, tzm);
mu_c_streamftime (iostream, " \"%d-%b-%Y %H:%M:%S %z\"", tmp, &tz);
return 0;
}
......
......@@ -373,9 +373,8 @@ util_parse_internal_date (char *date, time_t *timep,
struct tm tm;
mu_timezone tz;
time_t time;
char **datep = &date;
if (mu_parse_imap_date_time ((const char **) datep, &tm, &tz))
if (mu_scan_datetime (date, MU_DATETIME_IMAP_SEARCH, &tm, &tz, NULL))
return 1;
adjust_tm (&tm, &tz, flag);
......@@ -412,7 +411,7 @@ util_parse_ctime_date (const char *date, time_t *timep,
struct tm tm;
mu_timezone tz;
if (mu_parse_ctime_date_time (&date, &tm, &tz) == 0)
if (mu_scan_datetime (date, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
{
adjust_tm (&tm, &tz, flag);
*timep = mu_tm2time (&tm, &tz);
......
......@@ -305,6 +305,8 @@ int mu_stdio_stream_create (mu_stream_t *pstream, int fd, int flags);
int mu_memory_stream_create (mu_stream_t *pstream, int flags);
int mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem,
size_t size);
int mu_fixed_memory_stream_create (mu_stream_t *pstream, void *mem,
size_t size, int flags);
int mu_mapfile_stream_create (mu_stream_t *pstream, const char *filename,
int flags);
......
......@@ -61,18 +61,22 @@ struct mu_timezone
typedef struct mu_timezone mu_timezone;
int mu_parse_date (const char *p, time_t *rettime, const time_t *now);
int mu_parse_imap_date_time (const char **p, struct tm *tm,
mu_timezone *tz);
int mu_parse_ctime_date_time (const char **p, struct tm *tm,
mu_timezone *tz);
time_t mu_utc_offset (void);
time_t mu_tm2time (struct tm *timeptr, mu_timezone *tz);
size_t mu_strftime (char *s, size_t max, const char *format,
const struct tm *tm);
size_t mu_strftime (char *s, size_t max, const char *format, struct tm *tm);
int mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *tm,
struct mu_timezone *tz);
int mu_scan_datetime (const char *input, const char *fmt, struct tm *tm,
struct mu_timezone *tz, char **endp);
/* 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"
/* ----------------------- */
/* File & path names. */
......
......@@ -61,6 +61,7 @@ libbase_la_SOURCES = \
sha1.c\
secret.c\
spawnvp.c\
strftime.c\
symlink.c\
tempfile.c\
ticket.c\
......
......@@ -26,6 +26,7 @@
#include <mailutils/stream.h>
#include <mailutils/errno.h>
#include <mailutils/cstr.h>
#include <mailutils/cctype.h>
#define SECS_PER_DAY 86400
#define ADJUSTMENT -719162L
......@@ -528,140 +529,349 @@ mu_c_streamftime (mu_stream_t str, const char *fmt, struct tm *input_tm,
return rc;
}
int
mu_parse_imap_date_time (const char **p, struct tm *tm, mu_timezone *tz)
static int
_mu_short_weekday_string (const char *str)
{
int year, mon, day, hour, min, sec;
char zone[6] = "+0000"; /* ( "+" / "-" ) hhmm */
char month[5] = "";
int hh = 0;
int mm = 0;
int sign = 1;
int scanned = 0, scanned3;
int i;
int tzoffset;
day = mon = year = hour = min = sec = 0;
memset (tm, 0, sizeof (*tm));
switch (sscanf (*p,
"%2d-%3s-%4d%n %2d:%2d:%2d %5s%n",
&day, month, &year, &scanned3, &hour, &min, &sec, zone,
&scanned))
for (i = 0; i < 7; i++)
{
case 3:
scanned = scanned3;
break;
case 7:
break;
default:
return -1;
if (mu_c_strncasecmp (str, short_wday[i], 3) == 0)
return i;
}
return -1;
}
tm->tm_sec = sec;
tm->tm_min = min;
tm->tm_hour = hour;
tm->tm_mday = day;
for (i = 0; i < 12; i++)
static int
_mu_full_weekday_string (const char *str, char **endp)
{
int i;
for (i = 0; i < 7; i++)
{
if (mu_c_strncasecmp (month, short_month[i], 3) == 0)
if (mu_c_strcasecmp (str, full_wday[i]) == 0)
{
mon = i;
break;
if (endp)
*endp = (char*) (str + strlen (full_wday[i]));
return i;
}
}
tm->tm_mon = mon;
tm->tm_year = (year > 1900) ? year - 1900 : year;
tm->tm_yday = 0; /* unknown. */
tm->tm_wday = 0; /* unknown. */
#if HAVE_STRUCT_TM_TM_ISDST
tm->tm_isdst = -1; /* unknown. */
#endif
hh = (zone[1] - '0') * 10 + (zone[2] - '0');
mm = (zone[3] - '0') * 10 + (zone[4] - '0');
sign = (zone[0] == '-') ? -1 : +1;
tzoffset = sign * (hh * 60 * 60 + mm * 60);
return -1;
}
#if HAVE_STRUCT_TM_TM_GMTOFF
tm->tm_gmtoff = tzoffset;
#endif
if (tz)
static int
_mu_short_month_string (const char *str)
{
int i;
for (i = 0; i < 12; i++)
{
tz->utc_offset = tzoffset;
tz->tz_name = NULL;
if (mu_c_strncasecmp (str, short_month[i], 3) == 0)
return i;
}
return -1;
}
*p += scanned;
return 0;
static int
_mu_full_month_string (const char *str, char **endp)
{
int i;
for (i = 0; i < 12; i++)
{
if (mu_c_strcasecmp (str, full_month[i]) == 0)
{
if (endp)
*endp = (char*) (str + strlen (full_month[i]));
return i;
}
}
return -1;
}
/* "ctime" format is: Thu Jul 01 15:58:27 1999, with no trailing \n. */
int
mu_parse_ctime_date_time (const char **p, struct tm *tm, mu_timezone *tz)
get_num (const char *str, char **endp, int ndig, int minval, int maxval,
int *pn)
{
int wday = 0;
int year = 0;
int mon = 0;
int day = 0;
int hour = 0;
int min = 0;
int sec = 0;
int n = 0;
int x = 0;
int i;
char weekday[5] = "";
char month[5] = "";
errno = 0;
for (i = 0; i < ndig && *str && mu_isdigit (*str); str++, i++)
x = x * 10 + *str - '0';
if (sscanf (*p, "%3s %3s %2d %2d:%2d:%2d %d%n\n",
weekday, month, &day, &hour, &min, &sec, &year, &n) != 7)
*endp = (char*) str;
if (i == 0)
return -1;
else if (pn)
*pn = i;
else if (i != ndig)
return -1;
if (x < minval || x > maxval)
return -1;
return x;
}
*p += n;
#define DT_YEAR 0x01
#define DT_MONTH 0x02
#define DT_MDAY 0x04
#define DT_WDAY 0x08
#define DT_HOUR 0x10
#define DT_MIN 0x20
#define DT_SEC 0x40
for (i = 0; i < 7; i++)
int
mu_scan_datetime (const char *input, const char *fmt,
struct tm *tm, struct mu_timezone *tz, char **endp)
{
int rc = 0;
char *p;
int n;
int eof_ok = 0;
int datetime_parts = 0;
memset (tm, 0, sizeof *tm);
#ifdef HAVE_STRUCT_TM_TM_ISDST
tm->tm_isdst = -1; /* unknown. */
#endif
/* provide default timezone, in case it is not supplied in input */
if (tz)
{
if (mu_c_strncasecmp (weekday, short_wday[i], 3) == 0)
{
wday = i;
break;
}
memset (tz, 0, sizeof *tz);
tz->utc_offset = mu_utc_offset ();
}
for (i = 0; i < 12; i++)
/* Skip leading whitespace */
input = mu_str_skip_class (input, MU_CTYPE_BLANK);
for (; *fmt && rc == 0; fmt++)
{
if (mu_c_strncasecmp (month, short_month[i], 3) == 0)
if (mu_isspace (*fmt))
{
mon = i;
break;
fmt = mu_str_skip_class (fmt, MU_CTYPE_BLANK);
input = mu_str_skip_class (input, MU_CTYPE_BLANK);
if (!*fmt)
break;
}
eof_ok = 0;
if (*fmt == '%')
{
switch (*++fmt)
{
case 'a':
/* The abbreviated weekday name. */
n = _mu_short_weekday_string (input);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_wday = n;
datetime_parts |= DT_WDAY;
input += 3;
}
break;
case 'A':
/* The full weekday name. */
n = _mu_full_weekday_string (input, &p);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_wday = n;
datetime_parts |= DT_WDAY;
input = p;
}
break;
case 'b':
/* The abbreviated month name. */
n = _mu_short_month_string (input);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_mon = n;
datetime_parts |= DT_MONTH;
input += 3;
}
break;
case 'B':
/* The full month name. */
n = _mu_full_month_string (input, &p);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_mon = n;
datetime_parts |= DT_MONTH;
input = p;
}
break;
case 'd':
/* The day of the month as a decimal number (range 01 to 31). */
n = get_num (input, &p, 2, 1, 31, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_mday = n;
datetime_parts |= DT_MDAY;
input = p;
}
break;
case 'e':
/* Like %d, the day of the month as a decimal number, but a
leading zero is replaced by a space. */
{
int ndig;
n = get_num (input, &p, 2, 1, 31, &ndig);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_mday = n;
datetime_parts |= DT_MDAY;
input = p;
}
}
break;
case 'H':
/* The hour as a decimal number using a 24-hour clock (range
00 to 23). */
n = get_num (input, &p, 2, 0, 23, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_hour = n;
datetime_parts |= DT_HOUR;
input = p;
}
break;
case 'm':
/* The month as a decimal number (range 01 to 12). */
n = get_num (input, &p, 2, 1, 12, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_mon = n - 1;
datetime_parts |= DT_MONTH;
input = p;
}
break;
case 'M':
/* The minute as a decimal number (range 00 to 59). */
n = get_num (input, &p, 2, 0, 59, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_min = n;
datetime_parts |= DT_MIN;
input = p;
}
break;
case 'S':
/* The second as a decimal number (range 00 to 60) */
n = get_num (input, &p, 2, 0, 60, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
tm->tm_sec = n;
datetime_parts |= DT_SEC;
input = p;
}
break;
case 'Y':
/* The year as a decimal number including the century. */
errno = 0;
n = strtoul (input, &p, 10);
if (errno || p == input)
rc = MU_ERR_PARSE;
else
{
tm->tm_year = n - 1900;
datetime_parts |= DT_YEAR;
input = p;
}
break;
case 'z':
/* The time-zone as hour offset from GMT */
{
int sign = 1;
int hr;
if (*input == '+')
input++;
else if (*input == '-')
{
input++;
sign = -1;
}
n = get_num (input, &p, 2, 0, 11, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
input = p;
hr = n;
n = get_num (input, &p, 2, 0, 59, NULL);
if (n == -1)
rc = MU_ERR_PARSE;
else
{
input = p;
if (tz)
tz->utc_offset = sign * (hr * 60 + n) * 60;
}
}
}
break;
case '%':
if (*input == '%')
input++;
else
rc = MU_ERR_PARSE;
break;
case '?':
eof_ok = 1;
break;
}
if (eof_ok && rc == 0 && *input == 0)
break;
}
else if (*input != *fmt)
rc = MU_ERR_PARSE;
else
input++;
}
if (tm)
{
memset (tm, 0, sizeof (struct tm));
tm->tm_sec = sec;
tm->tm_min = min;
tm->tm_hour = hour;
tm->tm_mday = day;
tm->tm_wday = wday;
tm->tm_mon = mon;
tm->tm_year = (year > 1900) ? year - 1900 : year;
#ifdef HAVE_STRUCT_TM_TM_ISDST
tm->tm_isdst = -1; /* unknown. */
#endif
}
if (!eof_ok && rc == 0 && *input == 0 && *fmt)
rc = MU_ERR_PARSE;
/* ctime has no timezone information, set tz to local TZ if they ask. */
if (tz)
{
tz->utc_offset = mu_utc_offset ();
tz->tz_name = NULL;
}
if (!(datetime_parts & DT_WDAY) &&
(datetime_parts & (DT_YEAR|DT_MONTH|DT_MDAY)) ==
(DT_YEAR|DT_MONTH|DT_MDAY))
tm->tm_wday = dayofweek (tm->tm_year + 1900, tm->tm_mon, tm->tm_mday);
return 0;
if (endp)
*endp = (char*) input;
return rc;
}
......
......@@ -56,18 +56,6 @@ mu_mh_delim (const char *str)
return str[0] == '\n';
}
/* A locale-independent version of strftime */
size_t
mu_strftime (char *s, size_t max, const char *format, const struct tm *tm)
{
size_t size;
mu_set_locale ("C");
size = strftime (s, max, format, tm);
mu_restore_locale ();
return size;
}
static void
assoc_str_free (void *data)
{
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
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
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/util.h>
#include <mailutils/stream.h>
#include <mailutils/errno.h>
#include <mailutils/cstr.h>
/* A locale-independent version of strftime */
size_t
mu_strftime (char *buf, size_t size, const char *format, struct tm *tm)
{
int rc;
mu_stream_t str;
mu_stream_stat_buffer stat;
if (mu_fixed_memory_stream_create (&str, buf, size, MU_STREAM_WRITE))
return 0;
mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), stat);
rc = mu_c_streamftime (str, format, tm, NULL);
if (rc == 0)
rc = mu_stream_write (str, "", 1, NULL);
mu_stream_unref (str);
return rc ? 0 : stat[MU_STREAM_STAT_OUT] - 1;
}
......@@ -88,6 +88,27 @@ _memory_write (mu_stream_t stream, const char *iptr, size_t isize,
}
static int
_fixed_size_memory_write (mu_stream_t stream, const char *iptr, size_t isize,
size_t *nbytes)
{
struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream;
if (mfs->capacity < mfs->offset + isize)
isize = mfs->capacity - mfs->offset;
memcpy (mfs->ptr + mfs->offset, iptr, isize);
mfs->offset += isize;
if (mfs->offset > mfs->size)
mfs->size = mfs->offset;
if (nbytes)
*nbytes = isize;
return 0;
}
static int
_memory_truncate (mu_stream_t stream, mu_off_t len)
{
struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream;
......@@ -271,3 +292,39 @@ mu_static_memory_stream_create (mu_stream_t *pstream, const void *mem,
return 0;
}
int
mu_fixed_memory_stream_create (mu_stream_t *pstream, void *mem,
size_t size, int flags)
{
mu_stream_t stream;
struct _mu_memory_stream *str;
flags &= (MU_STREAM_READ|MU_STREAM_WRITE);
if (!flags)
return EINVAL;
str = (struct _mu_memory_stream *)
_mu_stream_create (sizeof (*str), flags | MU_STREAM_SEEK);
if (!str)
return ENOMEM;
str->ptr = (void*) mem;
str->size = size;
str->offset = 0;
str->capacity = size;
str->stream.flags |= _MU_STR_OPEN;
if (flags & MU_STREAM_READ)
str->stream.read = _memory_read;
if (flags & MU_STREAM_WRITE)
str->stream.write = _fixed_size_memory_write;
str->stream.size = _memory_size;
str->stream.ctl = _memory_ioctl;
str->stream.seek = _memory_seek;
stream = (mu_stream_t) str;
*pstream = stream;
return 0;
}
......
......@@ -51,6 +51,7 @@ noinst_PROGRAMS = \
listop\
mailcap\
prop\
scantime\
strftime\
tempfile\
url-comp\
......@@ -82,6 +83,7 @@ TESTSUITE_AT = \
list.at\
mailcap.at\
prop.at\
scantime.at\
strftime.at\
testsuite.at\
url.at\
......
# This file is part of GNU Mailutils. -*- Autotest -*-
# Copyright (C) 2011 Free Software Foundation, Inc.
#
# GNU Mailutils is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3, or (at
# your option) any later version.
#
# GNU Mailutils is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER(mu_scan_datetime)
dnl ---------------------------------------------------------------------
dnl SCANTIME([NAME], [KW], [FMT], [INPUT], [STDOUT = `'], [STDERR = `'])
dnl
m4_pushdef([SCANTIME],[
m4_pushdef([MU_TEST_GROUP],[scantime])
m4_pushdef([MU_TEST_KEYWORDS],[scantime mu_scan_datetime])
m4_pushdef([MU_TEST_COMMAND],[TZ=0 scantime -format='$3'])
MU_GENERIC_TEST([$1],[$2],[$4],[],[$5],[$6])
m4_popdef([MU_TEST_COMMAND])
m4_popdef([MU_TEST_KEYWORDS])
m4_popdef([MU_TEST_GROUP])
])
dnl ---------------------------------------------------------------------
SCANTIME([RFC-822 time],[rfc822],
[%a %b %e %H:%M:%S %Y],
[Tue May 3 13:25:26 2011
Fri Nov 11 11:55:01 2011],
[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=0
sec=1,min=55,hour=11,mday=11,mon=10,year=111,wday=5,tz=0
])
SCANTIME([IMAP time format],[imap],
[%d-%b-%Y %H:%M:%S %z],
[03-May-2011 13:25:26 +0100
11-Nov-2011 11:55:01 +0100],
[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=3600
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],
[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
sec=0,min=0,hour=0,mday=3,mon=4,year=111,wday=2,tz=0
])
SCANTIME([IMAP INTERNALDATE],[imap-internaldate],
[%a, %d %b %Y %H:%M:%S %z],
[Tue, 03 May 2011 13:25:26 +0200],
[sec=26,min=25,hour=13,mday=3,mon=4,year=111,wday=2,tz=7200
])
m4_popdef([SCANTIME])
dnl ---------------------------------------------------------------------
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2007, 2009, 2010, 2011 Free Software
Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mailutils/error.h>
#include <mailutils/errno.h>
#include <mailutils/util.h>
#include <mailutils/stream.h>
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
#include <mailutils/stdstream.h>
void
usage ()
{
mu_stream_printf (mu_strout, "usage: %s [-format=FMT] [-tz=TZ]\n",
mu_program_name);
exit (0);
}
int
main (int argc, char **argv)
{
int rc, i;
char *format = "%d-%b-%Y%? %H:%M:%S %z";
char *buf = NULL;
size_t size = 0;
size_t n;
mu_set_program_name (argv[0]);
mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
for (i = 1; i < argc; i++)
{
char *opt = argv[i];
if (strncmp (opt, "-format=", 8) == 0)
format = opt + 8;
else if (strcmp (opt, "-h") == 0)
usage ();
else
{
mu_error ("%s: unrecognized argument", opt);
exit (1);
}
}
while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0)
{
char *endp;
struct tm tm;
struct mu_timezone tz;
mu_rtrim_class (buf, MU_CTYPE_ENDLN);
rc = mu_scan_datetime (buf, format, &tm, &tz, &endp);
if (rc)
{
if (*endp)
mu_error ("parse failed near %s", endp);
else
mu_error ("parse failed at end of input");
continue;
}
if (*endp)
mu_printf ("# stopped at %s\n", endp);
/* FIXME: add tm_yday? */
mu_printf ("sec=%d,min=%d,hour=%d,mday=%d,mon=%d,year=%d,wday=%d,tz=%d\n",
tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon,
tm.tm_year, tm.tm_wday, tz.utc_offset);
//mu_c_streamftime (mu_strout, "%c %z%n", &tm, &tz);
}
if (rc)
{
mu_error ("%s", mu_strerror (rc));
return 1;
}
return 0;
}
......@@ -32,7 +32,7 @@ m4_popdef([MU_TEST_GROUP])
])
dnl ------------------------------------------------------------
# Test data
# Some test data
# January 1970
# Su Mo Tu We Th Fr Sa
......
......@@ -46,6 +46,8 @@ main (int argc, char **argv)
size_t size = 0;
size_t n;
struct mu_timezone tz, *tzp = NULL;
mu_set_program_name (argv[0]);
mu_set_program_name (argv[0]);
mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
......
......@@ -24,7 +24,7 @@ m4_define([MU_TEST_KEYWORDS])
dnl ------------------------------------------------------------
m4_define([MU_TEST_COMMAND])
m4_define([mu_trimstr],[m4_if([$2],-1,[$1],[m4_substr($1,0,$2)...])])
m4_define([mu_trimstr],[m4_if([$2],-1,[$1],[m4_substr([$1],0,$2)...])])
m4_define([mu_firstline],[mu_trimstr([$1],m4_index([$1],[
]))])
......@@ -43,7 +43,7 @@ dnl RUN-IF-FAIL $7
dnl RUN-IF-PASS $8
dnl
m4_define([MU_GENERIC_TEST],[
AT_SETUP([m4_if(MU_TEST_GROUP,[],,MU_TEST_GROUP: )m4_if([$1],[],mu_firstline([$3]),[$1])])
AT_SETUP([m4_if(MU_TEST_GROUP,[],,MU_TEST_GROUP: )m4_if([$1],[],[mu_firstline([$3])],[$1])])
AT_KEYWORDS([MU_TEST_KEYWORDS $2])
AT_CHECK([
AT_DATA([input],[$3
......@@ -83,6 +83,7 @@ m4_include([debugspec.at])
AT_BANNER([IMAP IO])
m4_include([imapio.at])
m4_include([scantime.at])
m4_include([strftime.at])
m4_include([fsaf.at])
\ No newline at end of file
......
......@@ -104,7 +104,7 @@ mu_scm_message_print (SCM message_smob, SCM port, scm_print_state * pstate)
scm_puts ("UNKNOWN", port);
if (mu_envelope_sget_date (env, &p) == 0
&& mu_parse_ctime_date_time (&p, &tm, &tz) == 0)
&& mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
{
strftime (datebuf, sizeof (datebuf), "%a %b %e %H:%M", &tm);
buffer = datebuf;
......@@ -416,7 +416,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_envelope_date, "mu-message-get-envelope-da
if (status)
mu_scm_error (FUNC_NAME, status, "cannot get envelope date",
scm_list_1 (mesg));
status = mu_parse_ctime_date_time (&sdate, &tm, &tz);
status = mu_scan_datetime (sdate, MU_DATETIME_FROM, &tm, &tz, NULL);
if (status)
mu_scm_error (FUNC_NAME, status, "invalid envelope date",
scm_list_1 (scm_from_locale_string (sdate)));
......
......@@ -145,7 +145,6 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text)
char *sender;
mu_body_t body;
mu_header_t hdr;
char datestr[80];
static char *content_header =
"Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n"
"Content-Transfer-Encoding: 8bit\n";
......@@ -156,13 +155,14 @@ mime_create_reason (mu_mime_t mime, mu_message_t msg, const char *text)
time (&t);
tm = localtime (&t);
mu_strftime (datestr, sizeof datestr, "%a, %b %d %H:%M:%S %Y %Z", tm);
mu_sieve_get_message_sender (msg, &sender);
mu_stream_printf (stream,
"The original message was received at %s from %s.\n",
datestr, sender);
mu_c_streamftime (stream,
"The original message was received at "
"%a, %b %d %H:%M:%S %Y %Z", tm, NULL);
mu_stream_printf (stream, " from %s.\n", sender);
free (sender);
mu_stream_printf (stream,
"Message was refused by recipient's mail filtering program.\n");
......@@ -201,7 +201,7 @@ mime_create_ds (mu_mime_t mime, mu_message_t orig)
mu_message_get_envelope (orig, &env);
if (mu_envelope_sget_date (env, &p) == 0
&& mu_parse_ctime_date_time (&p, &tm, &tz) == 0)
&& mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
t = mu_tm2time (&tm, &tz);
else
/* Use local time instead */
......
......@@ -339,14 +339,13 @@ _date_mapper (union mu_imap_fetch_response *resp,
struct imap_list_element *elt,
struct parse_response_env *parse_env)
{
const char *p;
struct tm tm;
struct mu_timezone tz;
if (elt->type != imap_eltype_string)
return MU_ERR_FAILURE;
p = elt->v.string;
if (mu_parse_imap_date_time (&p, &tm, &tz))
if (mu_scan_datetime (elt->v.string, MU_DATETIME_INTERNALDATE, &tm, &tz,
NULL))
return MU_ERR_FAILURE;
resp->internaldate.tm = tm;
resp->internaldate.tz = tz;
......@@ -472,10 +471,10 @@ _fill_response (void *item, void *data)
rc = MU_ERR_FAILURE;
else
{
char const *p = elt->v.string;
if (mu_parse_imap_date_time (&p,
&env->envelope->date,
&env->envelope->tz))
if (mu_scan_datetime (elt->v.string,
MU_DATETIME_IMAP,
&env->envelope->date,
&env->envelope->tz, NULL))
rc = MU_ERR_FAILURE;
else
rc = 0;
......
......@@ -213,7 +213,7 @@ hdr_date (struct header_call_args *args, void *data)
mu_message_get_envelope (args->msg, &env);
if (mu_envelope_sget_date (env, &p) == 0
&& mu_parse_ctime_date_time (&p, &tm, &tz) == 0)
&& mu_scan_datetime (p, MU_DATETIME_FROM, &tm, &tz, NULL) == 0)
strftime (date, sizeof(date), "%a %b %e %H:%M", &tm);
}
return header_buf_string (args, date);
......