add patch RFE 4244, 'Handle additional Date header formats'
[claws.git] / src / procheader.c
index 327774009370f6d0200eb76cde399b4049eb7fc5..f5755b6a395694be369d68aa363a4a918629e301 100644 (file)
@@ -41,6 +41,7 @@
 #include "hooks.h"
 #include "utils.h"
 #include "defs.h"
+#include "file-utils.h"
 
 #define BUFFSIZE       8192
 
@@ -83,6 +84,24 @@ static gint string_get_one_field(gchar **buf, char **str,
                                     TRUE);
 }
 
+gboolean procheader_skip_headers(FILE *fp)
+{
+       gchar *buf = g_malloc(BUFFSIZE);
+       do {
+               if (fgets_crlf(buf, BUFFSIZE - 1, fp) == NULL) {
+                       g_free(buf);
+                       return FALSE;
+               }
+               if (buf[0] == '\r' || buf[0] == '\n') {
+                       break;
+               }
+       } while (TRUE);
+       g_free(buf);
+
+       return TRUE;
+}
+
+
 static char *string_getline(char *buf, size_t len, char **str)
 {
        gboolean is_cr = FALSE;
@@ -403,30 +422,68 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,
                               gboolean full, gboolean decrypted)
 {
+#ifdef G_OS_WIN32
+       GFile *f;
+       GFileInfo *fi;
+       GTimeVal tv;
+       GError *error = NULL;
+#else
        GStatBuf s;
+#endif
        FILE *fp;
        MsgInfo *msginfo;
 
+#ifdef G_OS_WIN32
+       f = g_file_new_for_path(file);
+       fi = g_file_query_info(f, "standard::size,standard::type,time::modified",
+                       G_FILE_QUERY_INFO_NONE, NULL, &error);
+       if (error != NULL) {
+               g_warning(error->message);
+               g_error_free(error);
+               g_object_unref(f);
+       }
+#else
        if (g_stat(file, &s) < 0) {
                FILE_OP_ERROR(file, "stat");
                return NULL;
        }
+#endif
+
+#ifdef G_OS_WIN32
+       if (g_file_info_get_file_type(fi) != G_FILE_TYPE_REGULAR) {
+               g_object_unref(fi);
+               g_object_unref(f);
+               return NULL;
+       }
+#else
        if (!S_ISREG(s.st_mode))
                return NULL;
+#endif
 
-       if ((fp = g_fopen(file, "rb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
+       if ((fp = claws_fopen(file, "rb")) == NULL) {
+               FILE_OP_ERROR(file, "claws_fopen");
                return NULL;
        }
 
        msginfo = procheader_parse_stream(fp, flags, full, decrypted);
-       fclose(fp);
+       claws_fclose(fp);
 
        if (msginfo) {
+#ifdef G_OS_WIN32
+               msginfo->size = g_file_info_get_size(fi);
+               g_file_info_get_modification_time(fi, &tv);
+               msginfo->mtime = tv.tv_sec;
+#else
                msginfo->size = s.st_size;
                msginfo->mtime = s.st_mtime;
+#endif
        }
 
+#ifdef G_OS_WIN32
+       g_object_unref(fi);
+       g_object_unref(f);
+#endif
+
        return msginfo;
 }
 
@@ -550,7 +607,7 @@ static gboolean avatar_from_some_face(gpointer source, gpointer userdata)
        return FALSE;
 }
 
-static guint avatar_hook_id = 0;
+static gulong avatar_hook_id = HOOK_NONE;
 
 static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                             gboolean full, gboolean decrypted)
@@ -574,8 +631,11 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
                        if ((!strncmp(buf, "X-Claws-End-Special-Headers: 1",
                                strlen("X-Claws-End-Special-Headers:"))) ||
                            (!strncmp(buf, "X-Sylpheed-End-Special-Headers: 1",
-                               strlen("X-Sylpheed-End-Special-Headers:"))))
+                               strlen("X-Sylpheed-End-Special-Headers:")))) {
+                               g_free(buf);
+                               buf = NULL;
                                break;
+                       }
                        /* from other mailers */
                        if (!strncmp(buf, "Date: ", 6)
                        ||  !strncmp(buf, "To: ", 4)
@@ -603,11 +663,11 @@ 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 == HOOK_NONE && (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 != HOOK_NONE && !(prefs_common.enable_avatars & AVATARS_ENABLE_CAPTURE)) {
                hooks_unregister_hook(AVATAR_HEADER_UPDATE_HOOKLIST, avatar_hook_id);
-               avatar_hook_id = 0;
+               avatar_hook_id = HOOK_NONE;
        }
 
        while ((hnum = get_one_field(&buf, data, hentry)) != -1) {
@@ -878,6 +938,10 @@ static gint procheader_scan_date_string(const gchar *str,
                        weekday, day, month, year, hh, mm, ss, zone);
        if (result == 8) return 0;
 
+       result = sscanf(str, "%3s %3s %d %2d:%2d:%2d %d %6s",
+                       weekday, month, day, hh, mm, ss, year, zone);
+       if (result == 8) return 0;
+
        result = sscanf(str, "%d %9s %d %2d:%2d:%2d %6s",
                        day, month, year, hh, mm, ss, zone);
        if (result == 7) return 0;
@@ -887,6 +951,10 @@ static gint procheader_scan_date_string(const gchar *str,
                        weekday, day, month, year, hh, mm, ss);
        if (result == 7) return 0;
 
+       result = sscanf(str, "%3s %3s %d %2d:%2d:%2d %d",
+                       weekday, month, day, hh, mm, ss, year);
+       if (result == 7) return 0;
+
        result = sscanf(str, "%d %9s %d %2d:%2d:%2d",
                        day, month, year, hh, mm, ss);
        if (result == 6) return 0;
@@ -1150,8 +1218,8 @@ gint procheader_get_header_from_msginfo(MsgInfo *msginfo, gchar **buf, gchar *he
        hentry[0].name = header;
 
        file = procmsg_get_message_file_path(msginfo);
-       if ((fp = g_fopen(file, "rb")) == NULL) {
-               FILE_OP_ERROR(file, "fopen");
+       if ((fp = claws_fopen(file, "rb")) == NULL) {
+               FILE_OP_ERROR(file, "claws_fopen");
                g_free(file);
                g_free(*buf);
                *buf = NULL;
@@ -1159,8 +1227,8 @@ gint procheader_get_header_from_msginfo(MsgInfo *msginfo, gchar **buf, gchar *he
        }
        val = procheader_get_one_field(buf, fp, hentry);
 
-       if (fclose(fp) == EOF) {
-               FILE_OP_ERROR(file, "fclose");
+       if (claws_fclose(fp) == EOF) {
+               FILE_OP_ERROR(file, "claws_fclose");
                claws_unlink(file);
                g_free(file);
                g_free(*buf);