annotate src/lib-imap/imap-date.c @ 9595:166a188f9165 HEAD

mbox: Fields weren't being added to cache file during message saving.
author Timo Sirainen <tss@iki.fi>
date Fri, 30 Jul 2010 16:55:58 +0100
parents 00cd9aacd03c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9532
00cd9aacd03c Updated copyright notices to include year 2010.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
1 /* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
4 #include "utc-offset.h"
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
5 #include "utc-mktime.h"
579
e524da896d92 Several minor fixes: signess, casting away const, missing static, etc.
Timo Sirainen <tss@iki.fi>
parents: 492
diff changeset
6 #include "imap-date.h"
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8 #include <ctype.h>
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 static const char *month_names[] = {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 };
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 static int parse_timezone(const char *str)
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 int offset;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19 /* +|-zone */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 if ((*str != '+' && *str != '-') ||
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 !i_isdigit(str[1]) || !i_isdigit(str[2]) ||
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 !i_isdigit(str[3]) || !i_isdigit(str[4]))
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 return 0;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
25 offset = (str[1]-'0') * 10*60 + (str[2]-'0') * 60 +
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 (str[3]-'0') * 10 + (str[4]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 return *str == '+' ? offset : -offset;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 static const char *imap_parse_date_internal(const char *str, struct tm *tm)
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 int i;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 if (str == NULL || *str == '\0')
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 return NULL;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 memset(tm, 0, sizeof(struct tm));
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 /* "dd-mon-yyyy [hh:mi:ss +|-zone]"
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 dd is 1-2 digits and may be prefixed with space or zero. */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 if (str[0] == ' ') {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 /* " d-..." */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 str++;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 if (!(i_isdigit(str[0]) && (str[1] == '-' ||
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 (i_isdigit(str[1]) && str[2] == '-'))))
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 return NULL;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 tm->tm_mday = (str[0]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 if (str[1] == '-')
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 str += 2;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 else {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 tm->tm_mday = (tm->tm_mday * 10) + (str[1]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 str += 3;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 /* month name */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 for (i = 0; i < 12; i++) {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 if (strncasecmp(month_names[i], str, 3) == 0) {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 tm->tm_mon = i;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 break;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 if (i == 12 || str[3] != '-')
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 return NULL;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 str += 4;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 /* yyyy */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71 if (!i_isdigit(str[0]) || !i_isdigit(str[1]) ||
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 !i_isdigit(str[2]) || !i_isdigit(str[3]))
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 return NULL;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 tm->tm_year = (str[0]-'0') * 1000 + (str[1]-'0') * 100 +
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 (str[2]-'0') * 10 + (str[3]-'0') - 1900;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 str += 4;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 return str;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81
5700
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
82 static bool imap_mktime(struct tm *tm, time_t *time_r)
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
83 {
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
84 *time_r = utc_mktime(tm);
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
85 if (*time_r != (time_t)-1)
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
86 return TRUE;
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
87
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
88 /* the date is outside valid range for time_t. it might still be
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
89 technically valid though, so try to handle this case.
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
90 with 64bit time_t the full 0..9999 year range is valid. */
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
91 if (tm->tm_year <= 100) {
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
92 /* too old. time_t can be signed or unsigned, handle
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
93 both cases. */
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
94 *time_r = (time_t)-1 < (int)0 ? INT_MIN : 0;
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
95 } else {
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
96 /* too high. return the highest allowed value.
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
97 we shouldn't get here with 64bit time_t,
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
98 but handle that anyway. */
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
99 #if (TIME_T_MAX_BITS == 32 || TIME_T_MAX_BITS == 64)
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
100 *time_r = (1UL << (TIME_T_MAX_BITS-1)) - 1;
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
101 #else
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
102 *time_r = (1UL << TIME_T_MAX_BITS) - 1;
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
103 #endif
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
104 }
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
105 return FALSE;
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
106 }
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
107
7561
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
108 bool imap_parse_date(const char *str, time_t *timestamp_r)
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 {
982
4937e278489c imap_parse_date() returned a bit wrong time: mktime() already builds the
Timo Sirainen <tss@iki.fi>
parents: 579
diff changeset
110 struct tm tm;
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 str = imap_parse_date_internal(str, &tm);
5600
945966bb18c2 imap_parse_date() returns failure now if there's any extra data after the
Timo Sirainen <tss@iki.fi>
parents: 3863
diff changeset
113 if (str == NULL || str[0] != '\0')
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 tm.tm_isdst = -1;
7561
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
117 (void)imap_mktime(&tm, timestamp_r);
5700
bbd2b811d3e6 If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Timo Sirainen <tss@iki.fi>
parents: 5600
diff changeset
118 return TRUE;
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120
7561
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
121 bool imap_parse_datetime(const char *str, time_t *timestamp_r,
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
122 int *timezone_offset_r)
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 {
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124 struct tm tm;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 str = imap_parse_date_internal(str, &tm);
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 if (str == NULL)
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 if (str[0] != ' ')
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 str++;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 /* hh: */
120
82f566bc9d85 IMAP date+time parser bugfix
Timo Sirainen <tss@iki.fi>
parents: 119
diff changeset
135 if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ':')
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 tm.tm_hour = (str[0]-'0') * 10 + (str[1]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 str += 3;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 /* mm: */
120
82f566bc9d85 IMAP date+time parser bugfix
Timo Sirainen <tss@iki.fi>
parents: 119
diff changeset
141 if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ':')
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143 tm.tm_min = (str[0]-'0') * 10 + (str[1]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 str += 3;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 /* ss */
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 if (!i_isdigit(str[0]) || !i_isdigit(str[1]) || str[2] != ' ')
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 return FALSE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 tm.tm_sec = (str[0]-'0') * 10 + (str[1]-'0');
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150 str += 3;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 /* timezone */
7561
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
153 *timezone_offset_r = parse_timezone(str);
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 tm.tm_isdst = -1;
7561
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
156 if (imap_mktime(&tm, timestamp_r))
1a58b18652a6 Avoid using shadow variables. Unfortunately -Wshadow also complains about
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
157 *timestamp_r -= *timezone_offset_r * 60;
119
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 return TRUE;
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 }
2f67de235489 Whops, we were using RFC822 dates everywhere instead of IMAP dates.
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160
7838
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
161 static const char *
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
162 imap_to_datetime_tm(const struct tm *tm, int timezone_offset)
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
163 {
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
164 char *buf;
7838
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
165 int year;
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
166
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
167 /* @UNSAFE: but faster than t_strdup_printf() call.. */
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
168 buf = t_malloc(27);
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
169
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
170 /* dd-mon- */
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
171 buf[0] = (tm->tm_mday / 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
172 buf[1] = (tm->tm_mday % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
173 buf[2] = '-';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
174 memcpy(buf+3, month_names[tm->tm_mon], 3);
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
175 buf[6] = '-';
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
176
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
177 /* yyyy */
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
178 year = tm->tm_year + 1900;
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
179 buf[7] = (year / 1000) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
180 buf[8] = ((year / 100) % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
181 buf[9] = ((year / 10) % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
182 buf[10] = (year % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
183 buf[11] = ' ';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
184
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
185 /* hh:mi:ss */
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
186 buf[12] = (tm->tm_hour / 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
187 buf[13] = (tm->tm_hour % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
188 buf[14] = ':';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
189 buf[15] = (tm->tm_min / 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
190 buf[16] = (tm->tm_min % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
191 buf[17] = ':';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
192 buf[18] = (tm->tm_sec / 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
193 buf[19] = (tm->tm_sec % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
194 buf[20] = ' ';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
195
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
196 /* timezone */
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
197 if (timezone_offset >= 0)
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
198 buf[21] = '+';
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
199 else {
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
200 buf[21] = '-';
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
201 timezone_offset = -timezone_offset;
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
202 }
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
203 buf[22] = (timezone_offset / 600) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
204 buf[23] = ((timezone_offset / 60) % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
205 buf[24] = ((timezone_offset % 60) / 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
206 buf[25] = (timezone_offset % 10) + '0';
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
207 buf[26] = '\0';
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
208
1761
3767595e9069 imap_to_datetime_offset() isn't needed. optimized imap_to_datetime() a bit.
Timo Sirainen <tss@iki.fi>
parents: 1374
diff changeset
209 return buf;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents: 120
diff changeset
210 }
7838
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
211
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
212 const char *imap_to_datetime(time_t timestamp)
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
213 {
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
214 struct tm *tm;
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
215 int timezone_offset;
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
216
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
217 tm = localtime(&timestamp);
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
218 timezone_offset = utc_offset(tm, timestamp);
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
219 return imap_to_datetime_tm(tm, timezone_offset);
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
220 }
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
221
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
222 const char *imap_to_datetime_tz(time_t timestamp, int timezone_offset)
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
223 {
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
224 const struct tm *tm;
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
225 time_t adjusted = timestamp + timezone_offset*60;
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
226
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
227 tm = gmtime(&adjusted);
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
228 return imap_to_datetime_tm(tm, timezone_offset);
1b1fe3d50079 Added imap_to_datetime_tz() to create IMAP date-time with specified timezone.
Timo Sirainen <tss@iki.fi>
parents: 7561
diff changeset
229 }