Allow 'Z' as time zone in procheader_scan_date_string()
[claws.git] / src / procheader.c
index fad05e1bf426cacd27a8dd56b59f33db43572077..fa4ef49bbb4af51f6635b1504d85b80f6851fb62 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2014 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -337,7 +337,7 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,
                               gboolean full, gboolean decrypted)
 {
-       struct stat s;
+       GStatBuf s;
        FILE *fp;
        MsgInfo *msginfo;
 
@@ -533,9 +533,9 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
        
        msginfo->inreplyto = NULL;
 
-       if (avatar_hook_id == 0 && (prefs_common.enable_avatars | AVATARS_ENABLE_CAPTURE)) {
+       if (avatar_hook_id == 0 && (prefs_common.enable_avatars & AVATARS_ENABLE_CAPTURE)) {
                avatar_hook_id = hooks_register_hook(AVATAR_HEADER_UPDATE_HOOKLIST, avatar_from_some_face, NULL);
-       } else if (avatar_hook_id != 0 && !(prefs_common.enable_avatars | AVATARS_ENABLE_CAPTURE)) {
+       } else if (avatar_hook_id != 0 && !(prefs_common.enable_avatars & AVATARS_ENABLE_CAPTURE)) {
                hooks_unregister_hook(AVATAR_HEADER_UPDATE_HOOKLIST, avatar_hook_id);
                avatar_hook_id = 0;
        }
@@ -790,22 +790,24 @@ static gint procheader_scan_date_string(const gchar *str,
 {
        gint result;
        gint month_n;
-       gchar zone1[3];
-       gchar zone2[3];
+       gint secfract;
+       gint zone1 = 0, zone2 = 0;
+       gchar offset_sign, zonestr[7];
+       gchar sep1;
 
        if (str == NULL)
                return -1;
 
-       result = sscanf(str, "%10s %d %9s %d %2d:%2d:%2d %5s",
+       result = sscanf(str, "%10s %d %9s %d %2d:%2d:%2d %6s",
                        weekday, day, month, year, hh, mm, ss, zone);
        if (result == 8) return 0;
 
        /* RFC2822 */
-       result = sscanf(str, "%3s,%d %9s %d %2d:%2d:%2d %5s",
+       result = sscanf(str, "%3s,%d %9s %d %2d:%2d:%2d %6s",
                        weekday, day, month, year, hh, mm, ss, zone);
        if (result == 8) return 0;
 
-       result = sscanf(str, "%d %9s %d %2d:%2d:%2d %5s",
+       result = sscanf(str, "%d %9s %d %2d:%2d:%2d %6s",
                        day, month, year, hh, mm, ss, zone);
        if (result == 7) return 0;
 
@@ -819,7 +821,7 @@ static gint procheader_scan_date_string(const gchar *str,
        if (result == 6) return 0;
 
        *ss = 0;
-       result = sscanf(str, "%10s %d %9s %d %2d:%2d %5s",
+       result = sscanf(str, "%10s %d %9s %d %2d:%2d %6s",
                        weekday, day, month, year, hh, mm, zone);
        if (result == 7) return 0;
 
@@ -836,23 +838,48 @@ static gint procheader_scan_date_string(const gchar *str,
                        day, month, year, hh, mm);
        if (result == 5) return 0;
 
-       /* RFC3339 subset */
        *weekday = '\0';
-       result = sscanf(str, "%4d-%2d-%2d %2d:%2d:%2d+%2s:%2s",
-                       year, &month_n, day, hh, mm, ss, zone1, zone2);
-       if (result == 8) {
-               if (1 <= month_n && month_n <= 12) {
+
+       /* RFC3339 subset, with fraction of second */
+       result = sscanf(str, "%4d-%2d-%2d%c%2d:%2d:%2d.%1d%6s",
+                       year, &month_n, day, &sep1, hh, mm, ss, &secfract, zonestr);
+       debug_print("str |%s|, result %d\n", str, result);
+       if (result == 9
+                       && (sep1 == 'T' || sep1 == 't' || sep1 == ' ')) {
+               if (month_n >= 1 && month_n <= 12) {
                        strncpy2(month, monthstr+((month_n-1)*3), 4);
-                       *zone = '+';
-                       strncpy2(zone+1, zone1, 3);
-                       strncpy2(zone+3, zone2, 3);
+                       if (zonestr[0] == 'z' || zonestr[0] == 'Z') {
+                               strcat(zone, "+00:00");
+                       } else if (sscanf(zonestr, "%c%2d:%2d",
+                                               &offset_sign, &zone1, &zone2) == 3) {
+                               strcat(zone, zonestr);
+                       }
+                       return 0;
+               }
+       }
+
+       /* RFC3339 subset, no fraction of second */
+       result = sscanf(str, "%4d-%2d-%2d%c%2d:%2d:%2d%6s",
+                       year, &month_n, day, &sep1, hh, mm, ss, zonestr);
+       debug_print("str |%s|, result %d\n", str, result);
+       if (result == 8
+                       && (sep1 == 'T' || sep1 == 't' || sep1 == ' ')) {
+               if (month_n >= 1 && month_n <= 12) {
+                       strncpy2(month, monthstr+((month_n-1)*3), 4);
+                       if (offset_sign == 'z' || offset_sign == 'Z') {
+                               strcat(zone, "+00:00");
+                       } else if (sscanf(zonestr, "%c%2d:%2d",
+                                               &offset_sign, &zone1, &zone2) == 3) {
+                               strcat(zone, zonestr);
+                       }
                        return 0;
                }
        }
 
-       /* RFC3339 subset */
        *zone = '\0';
-       *weekday = '\0';
+
+       /* RFC3339 subset */
+       /* This particular "subset" is invalid, RFC requires the time offset */
        result = sscanf(str, "%4d-%2d-%2d %2d:%2d:%2d",
                        year, &month_n, day, hh, mm, ss);
        if (result == 6) {
@@ -928,7 +955,7 @@ time_t procheader_date_parse(gchar *dest, const gchar *src, gint len)
        gchar month[10];
        gint year;
        gint hh, mm, ss;
-       gchar zone[6];
+       gchar zone[7];
        GDateMonth dmonth = G_DATE_BAD_MONTH;
        struct tm t;
        gchar *p;
@@ -1091,3 +1118,31 @@ void procheader_entries_free (HeaderEntry *entries)
        }
 }
 
+gboolean procheader_header_is_internal(const gchar *hdr_name)
+{
+       const gchar *internal_hdrs[] = {
+               "AF:", "NF:", "PS:", "SRH:", "SFN:", "DSR:", "MID:", "CFG:",
+               "PT:", "S:", "RQ:", "SSV:", "NSV:", "SSH:", "R:", "MAID:",
+               "SCF:", "RMID:", "FMID:", "NAID:",
+               "X-Claws-Account-Id:",
+               "X-Claws-Sign:",
+               "X-Claws-Encrypt:",
+               "X-Claws-Privacy-System:",
+               "X-Claws-Auto-Wrapping:",
+               "X-Claws-Auto-Indent:",
+               "X-Claws-End-Special-Headers:",
+               "X-Sylpheed-Account-Id:",
+               "X-Sylpheed-Sign:",
+               "X-Sylpheed-Encrypt:",
+               "X-Sylpheed-Privacy-System:",
+               "X-Sylpheed-End-Special-Headers:",
+                NULL
+       };
+       int i;
+
+       for (i = 0; internal_hdrs[i]; i++) {
+               if (!strcmp(hdr_name, internal_hdrs[i]))
+                       return TRUE;
+       }
+       return FALSE;
+}