Commit 3c1dec65 3c1dec655801d103e8299338a94d11ceb14e7ccb by Sergey Poznyakoff

Patch from Sam: added imap_parse_date_time().

imap_parse_date_time() returns tm/timezone pair.
1 parent b32a8225
...@@ -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,46 +1322,46 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, ...@@ -1258,46 +1322,46 @@ 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;
1265 month[0] = '\0';
1266 sscanf (buffer, "%2d-%3s-%4d %2d:%2d:%2d %d", &day, month, &year,
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 1328
1287 now = mktime (&tm); 1329 if (imap_parse_date_time(datep, &tm, &tz) != 0)
1330 now = (time_t)-1;
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. */
1288 if (now == (time_t)-1) 1336 if (now == (time_t)-1)
1289 { 1337 {
1290 size_t len; 1338 struct tm* gmt;
1291 /* Fall back to localtime. */ 1339
1292 now = time (NULL); 1340 time(&now);
1293 snprintf (buffer, buflen, "%s", ctime(&now)); 1341
1294 len = strlen (buffer); 1342 gmt = gmtime(&now);
1295 if (len && buffer[len - 1] == '\n') 1343
1296 buffer[len - 1] = '\0'; 1344 tm = *gmt;
1297 } 1345 }
1298 else 1346
1299 { 1347 {
1300 strftime (buffer, buflen, " %a %b %d %H:%M:%S %Y", &tm); 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;
1301 } 1365 }
1302 return 0; 1366 return 0;
1303 } 1367 }
......