/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "utc-offset.h"
#include "utc-mktime.h"
#include "rfc822-parser.h"
#include "message-date.h"
#include <ctype.h>
/* RFC specifies ':' as the only allowed separator,
but be forgiving also for some broken ones */
#define IS_TIME_SEP(c) \
((c) == ':' || (c) == '.')
struct message_date_parser_context {
};
static const char *month_names[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static const char *weekday_names[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
{
int offset;
char chr;
/* numeric offset */
return 0;
}
if (len == 1) {
/* military zone - handle them the correct way, not as
RFC822 says. RFC2822 though suggests that they'd be
considered as unspecified.. */
if (chr < 'J')
if (chr == 'J')
return 0;
if (chr <= 'M')
if (chr < 'Z')
return 0;
}
/* UT - Universal Time */
return 0;
}
if (len == 3) {
/* GMT | [ECMP][DS]T */
return 0;
case 'E':
break;
case 'C':
break;
case 'M':
break;
case 'P':
break;
default:
/* GMT and others */
return 0;
}
return offset + 60;
return offset;
}
return 0;
}
{
int ret;
}
static bool
{
const unsigned char *value;
int ret;
/* [weekday_name "," ] dd month_name [yy]yy hh:mi[:ss] timezone */
/* skip the optional weekday */
return FALSE;
if (len == 3) {
return FALSE;
return FALSE;
}
/* dd */
return FALSE;
if (len == 2) {
return FALSE;
}
/* month name */
return FALSE;
for (i = 0; i < 12; i++) {
break;
}
}
if (i == 12)
return FALSE;
/* [yy]yy */
return FALSE;
for (i = 0; i < len; i++) {
return FALSE;
}
if (len == 2) {
/* two digit year, assume 1970+ */
} else {
return FALSE;
}
/* hh, allow also single digit */
return FALSE;
if (len == 2) {
return FALSE;
}
/* :mm (may be the last token) */
return FALSE;
return FALSE;
/* [:ss] */
return FALSE;
}
return FALSE;
if (ret == 0) {
/* missing timezone */
*timezone_offset_r = 0;
} else {
/* timezone. invalid timezones are treated as GMT, because
we may not know all the possible timezones that are used
and it's better to give at least a mostly correct reply.
FIXME: perhaps some different strict version of this
function would be useful? */
}
return FALSE;
return TRUE;
}
{
bool success;
T_BEGIN {
} T_END;
return success;
}
{
int offset;
bool negative;
if (offset >= 0)
else {
}
return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %c%02d%02d",
}