Patch from Sam: added imap_parse_date_time().
imap_parse_date_time() returns tm/timezone pair.
Showing
1 changed file
with
104 additions
and
40 deletions
... | @@ -34,6 +34,8 @@ | ... | @@ -34,6 +34,8 @@ |
34 | #include <registrar0.h> | 34 | #include <registrar0.h> |
35 | #include <imap0.h> | 35 | #include <imap0.h> |
36 | 36 | ||
37 | extern time_t mu_mktime __P((struct tm *timeptr, int tz)); | ||
38 | |||
37 | /* Functions to overload the mailbox_t API. */ | 39 | /* Functions to overload the mailbox_t API. */ |
38 | static void mailbox_imap_destroy __P ((mailbox_t)); | 40 | static void mailbox_imap_destroy __P ((mailbox_t)); |
39 | static int mailbox_imap_open __P ((mailbox_t, int)); | 41 | static int mailbox_imap_open __P ((mailbox_t, int)); |
... | @@ -1230,6 +1232,67 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1230,6 +1232,67 @@ imap_envelope_sender (envelope_t envelope, char *buffer, size_t buflen, |
1230 | return status; | 1232 | return status; |
1231 | } | 1233 | } |
1232 | 1234 | ||
1235 | int | ||
1236 | imap_parse_date_time (const char **p, struct tm *tm, int *tz) | ||
1237 | { | ||
1238 | int year, mon, day, hour, min, sec; | ||
1239 | char zone[6] = "+0000"; /* ( "+" / "-" ) hhmm */ | ||
1240 | char month[5] = ""; | ||
1241 | int hh = 0; | ||
1242 | int mm = 0; | ||
1243 | int sign = 1; | ||
1244 | int scanned = 0, scanned3; | ||
1245 | int i; | ||
1246 | |||
1247 | day = mon = year = hour = min = sec = 0; | ||
1248 | |||
1249 | memset (tm, 0, sizeof (*tm)); | ||
1250 | |||
1251 | switch (sscanf (*p, | ||
1252 | "%2d-%3s-%4d%n %2d:%2d:%2d %5s%n", | ||
1253 | &day, month, &year, &scanned3, &hour, &min, &sec, zone, | ||
1254 | &scanned)) | ||
1255 | { | ||
1256 | case 3: | ||
1257 | scanned = scanned3; | ||
1258 | break; | ||
1259 | case 7: | ||
1260 | break; | ||
1261 | default: | ||
1262 | return -1; | ||
1263 | } | ||
1264 | |||
1265 | tm->tm_sec = sec; | ||
1266 | tm->tm_min = min; | ||
1267 | tm->tm_hour = hour; | ||
1268 | tm->tm_mday = day; | ||
1269 | |||
1270 | for (i = 0; i < 12; i++) | ||
1271 | { | ||
1272 | if (strncasecmp (month, MONTHS[i], 3) == 0) | ||
1273 | { | ||
1274 | mon = i; | ||
1275 | break; | ||
1276 | } | ||
1277 | } | ||
1278 | tm->tm_mon = mon; | ||
1279 | tm->tm_year = (year > 1900) ? year - 1900 : year; | ||
1280 | tm->tm_yday = 0; /* unknown. */ | ||
1281 | tm->tm_wday = 0; /* unknown. */ | ||
1282 | tm->tm_isdst = -1; /* unknown. */ | ||
1283 | |||
1284 | hh = (zone[1] - '0') * 10 + (zone[2] - '0'); | ||
1285 | mm = (zone[3] - '0') * 10 + (zone[4] - '0'); | ||
1286 | sign = (zone[0] == '-') ? -1 : +1; | ||
1287 | |||
1288 | if (tz) | ||
1289 | *tz = sign * (hh * 60 * 60 + mm * 60); | ||
1290 | |||
1291 | *p += scanned; | ||
1292 | |||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1233 | static int | 1296 | static int |
1234 | imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | 1297 | imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1235 | size_t *plen) | 1298 | size_t *plen) |
... | @@ -1238,12 +1301,13 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1238,12 +1301,13 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1238 | msg_imap_t msg_imap = message_get_owner (msg); | 1301 | msg_imap_t msg_imap = message_get_owner (msg); |
1239 | m_imap_t m_imap = msg_imap->m_imap; | 1302 | m_imap_t m_imap = msg_imap->m_imap; |
1240 | f_imap_t f_imap = m_imap->f_imap; | 1303 | f_imap_t f_imap = m_imap->f_imap; |
1241 | int year, mon, day, hour, min, sec; | ||
1242 | int offt; | ||
1243 | int i; | ||
1244 | struct tm tm; | 1304 | struct tm tm; |
1305 | int tz; | ||
1245 | time_t now; | 1306 | time_t now; |
1246 | char month[5]; | 1307 | char datebuf[] = "mm-dd-yyyy hh:mm:ss +0000"; |
1308 | const char* date = datebuf; | ||
1309 | const char** datep = &date; | ||
1310 | /* reserve as much space as we need for internal-date */ | ||
1247 | int status; | 1311 | int status; |
1248 | if (f_imap->state == IMAP_NO_STATE) | 1312 | if (f_imap->state == IMAP_NO_STATE) |
1249 | { | 1313 | { |
... | @@ -1258,47 +1322,47 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1258,47 +1322,47 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1258 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); | 1322 | MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); |
1259 | f_imap->state = IMAP_FETCH; | 1323 | f_imap->state = IMAP_FETCH; |
1260 | } | 1324 | } |
1261 | status = message_operation (f_imap, msg_imap, buffer, buflen, plen); | 1325 | status = message_operation (f_imap, msg_imap, datebuf, sizeof(datebuf), NULL); |
1262 | if (status != 0) | 1326 | if (status != 0) |
1263 | return status; | 1327 | return status; |
1264 | day = mon = year = hour = min = sec = offt = 0; | 1328 | |
1265 | month[0] = '\0'; | 1329 | if (imap_parse_date_time(datep, &tm, &tz) != 0) |
1266 | sscanf (buffer, "%2d-%3s-%4d %2d:%2d:%2d %d", &day, month, &year, | 1330 | now = (time_t)-1; |
1267 | &hour, &min, &sec, &offt); | ||
1268 | tm.tm_sec = sec; | ||
1269 | tm.tm_min = min; | ||
1270 | tm.tm_hour = hour; | ||
1271 | tm.tm_mday = day; | ||
1272 | for (i = 0; i < 12; i++) | ||
1273 | { | ||
1274 | if (strncasecmp(month, MONTHS[i], 3) == 0) | ||
1275 | { | ||
1276 | mon = i; | ||
1277 | break; | ||
1278 | } | ||
1279 | } | ||
1280 | tm.tm_mon = mon; | ||
1281 | tm.tm_year = (year > 1900) ? year - 1900 : year; | ||
1282 | tm.tm_yday = 0; /* unknown. */ | ||
1283 | tm.tm_wday = 0; /* unknown. */ | ||
1284 | tm.tm_isdst = -1; /* unknown. */ | ||
1285 | /* What to do the timezone? */ | ||
1286 | |||
1287 | now = mktime (&tm); | ||
1288 | if (now == (time_t)-1) | ||
1289 | { | ||
1290 | size_t len; | ||
1291 | /* Fall back to localtime. */ | ||
1292 | now = time (NULL); | ||
1293 | snprintf (buffer, buflen, "%s", ctime(&now)); | ||
1294 | len = strlen (buffer); | ||
1295 | if (len && buffer[len - 1] == '\n') | ||
1296 | buffer[len - 1] = '\0'; | ||
1297 | } | ||
1298 | else | 1331 | else |
1332 | now = mu_mktime (&tm, tz); | ||
1333 | |||
1334 | /* if the time was unparseable, or mktime() didn't like what we | ||
1335 | parsed, use the calendar time. */ | ||
1336 | if (now == (time_t)-1) | ||
1299 | { | 1337 | { |
1300 | strftime (buffer, buflen, " %a %b %d %H:%M:%S %Y", &tm); | 1338 | struct tm* gmt; |
1339 | |||
1340 | time(&now); | ||
1341 | |||
1342 | gmt = gmtime(&now); | ||
1343 | |||
1344 | tm = *gmt; | ||
1301 | } | 1345 | } |
1346 | |||
1347 | { | ||
1348 | int len = strftime (buffer, buflen, " %a %b %d %H:%M:%S %Y", &tm); | ||
1349 | |||
1350 | /* FIXME: I don't know what strftime does if the buflen is too | ||
1351 | short, or it fails. Assuming that it won't fail, this is my guess | ||
1352 | as to the right thing. | ||
1353 | |||
1354 | I think if the buffer is too short, it will fill it as much | ||
1355 | as it can, and nul terminate it. But I'll terminate it anyhow. | ||
1356 | */ | ||
1357 | if(len == 0) | ||
1358 | { | ||
1359 | len = buflen - 1; | ||
1360 | buffer[len] = 0; | ||
1361 | } | ||
1362 | |||
1363 | if(plen) | ||
1364 | *plen = len; | ||
1365 | } | ||
1302 | return 0; | 1366 | return 0; |
1303 | } | 1367 | } |
1304 | 1368 | ... | ... |
-
Please register or sign in to post a comment