Mercurial > dovecot > original-hg > dovecot-1.2
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 |
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 | 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 | 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(×tamp); |
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 } |