some code fix in procheader.c
[claws.git] / src / procheader.c
index 0f7e8c0a594c683630b63ee8070fb33552af95c9..2363c03597e3fe475ed0b0e3f9c1a51a2f5f521e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * 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
@@ -31,8 +31,8 @@
 #include "procheader.h"
 #include "procmsg.h"
 #include "codeconv.h"
-#include "utils.h"
 #include "prefs_common.h"
+#include "utils.h"
 
 #define BUFFSIZE       8192
 
@@ -185,20 +185,35 @@ gchar *procheader_get_unfolded_line(gchar *buf, gint len, FILE *fp)
        return buf;
 }
 
-GSList *procheader_get_header_list(const gchar *file)
+GSList *procheader_get_header_list_from_file(const gchar *file)
 {
        FILE *fp;
-       gchar buf[BUFFSIZE], tmp[BUFFSIZE];
-       gchar *p;
-       GSList *hlist = NULL;
-       Header *header;
+       GSList *hlist;
 
        if ((fp = fopen(file, "r")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
                return NULL;
        }
 
+       hlist = procheader_get_header_list(fp);
+
+       fclose(fp);
+       return hlist;
+}
+
+GSList *procheader_get_header_list(FILE *fp)
+{
+       gchar buf[BUFFSIZE], tmp[BUFFSIZE];
+       gchar *p;
+       GSList *hlist = NULL;
+       Header *header;
+
+       g_return_val_if_fail(fp != NULL, NULL);
+
        while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
+               if (header = procheader_parse_header(buf))
+                       hlist = g_slist_append(hlist, header);
+               /*
                if (*buf == ':') continue;
                for (p = buf; *p && *p != ' '; p++) {
                        if (*p == ':') {
@@ -213,26 +228,165 @@ GSList *procheader_get_header_list(const gchar *file)
                                break;
                        }
                }
+               */
        }
 
-       fclose(fp);
        return hlist;
 }
 
+GPtrArray *procheader_get_header_array(FILE *fp)
+{
+       gchar buf[BUFFSIZE], tmp[BUFFSIZE];
+       gchar *p;
+       GPtrArray *headers;
+       Header *header;
+
+       g_return_val_if_fail(fp != NULL, NULL);
+
+       headers = g_ptr_array_new();
+
+       while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
+               if (header = procheader_parse_header(buf))
+                       g_ptr_array_add(headers, header);
+               /*
+               if (*buf == ':') continue;
+               for (p = buf; *p && *p != ' '; p++) {
+                       if (*p == ':') {
+                               header = g_new(Header, 1);
+                               header->name = g_strndup(buf, p - buf);
+                               p++;
+                               while (*p == ' ' || *p == '\t') p++;
+                               conv_unmime_header(tmp, sizeof(tmp), p, NULL);
+                               header->body = g_strdup(tmp);
+
+                               g_ptr_array_add(headers, header);
+                               break;
+                       }
+               }
+               */
+       }
+
+       return headers;
+}
+
+GPtrArray *procheader_get_header_array_asis(FILE *fp)
+{
+       gchar buf[BUFFSIZE], tmp[BUFFSIZE];
+       gchar *p;
+       GPtrArray *headers;
+       Header *header;
+
+       g_return_val_if_fail(fp != NULL, NULL);
+
+       headers = g_ptr_array_new();
+
+       while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
+               if (header = procheader_parse_header(buf))
+                       g_ptr_array_add(headers, header);
+                       /*
+               if (*buf == ':') continue;
+               for (p = buf; *p && *p != ' '; p++) {
+                       if (*p == ':') {
+                               header = g_new(Header, 1);
+                               header->name = g_strndup(buf, p - buf);
+                               p++;
+                               conv_unmime_header(tmp, sizeof(tmp), p, NULL);
+                               header->body = g_strdup(tmp);
+
+                               g_ptr_array_add(headers, header);
+                               break;
+                       }
+               }
+                       */
+       }
+
+       return headers;
+}
+
 void procheader_header_list_destroy(GSList *hlist)
 {
        Header *header;
 
        while (hlist != NULL) {
                header = hlist->data;
-
-               g_free(header->name);
-               g_free(header->body);
-               g_free(header);
+               procheader_header_free(header);
                hlist = g_slist_remove(hlist, header);
        }
 }
 
+void procheader_header_array_destroy(GPtrArray *harray)
+{
+       gint i;
+       Header *header;
+
+       for (i = 0; i < harray->len; i++) {
+               header = g_ptr_array_index(harray, i);
+               procheader_header_free(header);
+       }
+
+       g_ptr_array_free(harray, TRUE);
+}
+
+void procheader_header_free(Header *header)
+{
+       if (!header) return;
+
+       g_free(header->name);
+       g_free(header->body);
+       g_free(header);
+}
+
+/*
+  tests whether two headers' names are equal
+  remove the trailing ':' or ' ' before comparing
+*/
+
+gboolean procheader_headername_equal(char * hdr1, char * hdr2)
+{
+       int len1;
+       int len2;
+
+       len1 = strlen(hdr1);
+       len2 = strlen(hdr2);
+       if ((hdr1[len1 - 1] == ':') || (hdr1[len1 - 1] == ' '))
+               len1--;
+       if ((hdr2[len2 - 1] == ':') || (hdr2[len2 - 1] == ' '))
+               len2--;
+       if (len1 != len2)
+               return 0;
+       return (g_strncasecmp(hdr1, hdr2, len1) == 0);
+}
+
+/*
+  parse headers, for example :
+  From: dinh@enseirb.fr becomes :
+  header->name = "From:"
+  header->body = "dinh@enseirb.fr"
+ */
+
+Header * procheader_parse_header(gchar * buf)
+{
+       gchar tmp[BUFFSIZE];
+       gchar *p = buf;
+       Header * header;
+
+       if ((*buf == ':') || (*buf == ' '))
+               return NULL;
+
+       for (p = buf; *p ; p++) {
+               if ((*p == ':') || (*p == ' ')) {
+                       header = g_new(Header, 1);
+                       header->name = g_strndup(buf, p - buf + 1);
+                       p++;
+                       while (*p == ' ' || *p == '\t') p++;
+                       conv_unmime_header(tmp, sizeof(tmp), p, NULL);
+                       header->body = g_strdup(tmp);
+                       return header;
+               }
+       }
+       return NULL;
+}
+
 void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 {
        gchar buf[BUFFSIZE];
@@ -251,8 +405,8 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 
                if (hp->body == NULL)
                        hp->body = g_strdup(p);
-               else if (!strcasecmp(hp->name, "To:") ||
-                        !strcasecmp(hp->name, "Cc:")) {
+               else if (procheader_headername_equal(hp->name, "To") ||
+                        procheader_headername_equal(hp->name, "Cc")) {
                        gchar *tp = hp->body;
                        hp->body = g_strconcat(tp, ", ", p, NULL);
                        g_free(tp);
@@ -265,14 +419,16 @@ enum
        H_DATE          = 0,
        H_FROM          = 1,
        H_TO            = 2,
-       H_NEWSGROUPS    = 3,
-       H_SUBJECT       = 4,
-       H_MSG_ID        = 5,
-       H_REFERENCES    = 6,
-       H_IN_REPLY_TO   = 7,
-       H_CONTENT_TYPE  = 8,
-       H_SEEN          = 9,
-       H_X_FACE        = 10,
+       H_CC            = 3,
+       H_NEWSGROUPS    = 4,
+       H_SUBJECT       = 5,
+       H_MSG_ID        = 6,
+       H_REFERENCES    = 7,
+       H_IN_REPLY_TO   = 8,
+       H_CONTENT_TYPE  = 9,
+       H_SEEN          = 10,
+       H_X_FACE        = 11,
+       H_DISPOSITION_NOTIFICATION_TO = 12
 };
 
 MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
@@ -280,6 +436,7 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
        static HeaderEntry hentry_full[] = {{"Date:",           NULL, FALSE},
                                           {"From:",            NULL, TRUE},
                                           {"To:",              NULL, TRUE},
+                                          {"Cc:",              NULL, TRUE},
                                           {"Newsgroups:",      NULL, TRUE},
                                           {"Subject:",         NULL, TRUE},
                                           {"Message-Id:",      NULL, FALSE},
@@ -288,11 +445,13 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                                           {"Content-Type:",    NULL, FALSE},
                                           {"Seen:",            NULL, FALSE},
                                           {"X-Face:",          NULL, FALSE},
+                                          {"Disposition-Notification-To:",NULL, FALSE},
                                           {NULL,               NULL, FALSE}};
 
        static HeaderEntry hentry_short[] = {{"Date:",          NULL, FALSE},
                                            {"From:",           NULL, TRUE},
                                            {"To:",             NULL, TRUE},
+                                           {"Cc:",             NULL, TRUE},
                                            {"Newsgroups:",     NULL, TRUE},
                                            {"Subject:",        NULL, TRUE},
                                            {"Message-Id:",     NULL, FALSE},
@@ -354,6 +513,16 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                        } else
                                msginfo->to = g_strdup(tmp);
                        break;
+               case H_CC:
+                       conv_unmime_header(tmp, sizeof(tmp), hp, NULL);
+                       if (msginfo->cc) {
+                               p = msginfo->cc;
+                               msginfo->cc =
+                                       g_strconcat(p, ", ", tmp, NULL);
+                               g_free(p);
+                       } else
+                               msginfo->cc = g_strdup(tmp);
+                       break;
                case H_NEWSGROUPS:
                        if (msginfo->newsgroups) {
                                p = msginfo->newsgroups;
@@ -408,6 +577,10 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                        if (msginfo->xface) break;
                        msginfo->xface = g_strdup(hp);
                        break;
+               case H_DISPOSITION_NOTIFICATION_TO:
+                       if (msginfo->dispositionnotificationto) break;
+                       msginfo->dispositionnotificationto = g_strdup(hp);
+                       break;
                default:
                }
        }
@@ -524,35 +697,13 @@ time_t procheader_date_parse(gchar *dest, const gchar *src, gint len)
 
 void procheader_date_get_localtime(gchar *dest, gint len, const time_t timer)
 {
-#ifdef HAVE_STRFTIME
        struct tm *lt;
+       gchar *default_format = "%y/%m/%d(%a) %H:%M";
 
        lt = localtime(&timer);
 
        if (prefs_common.date_format)
                strftime(dest, len, prefs_common.date_format, lt);
        else
-               *dest = '\0';
-#else
-       static gchar *wdaystr = N_("SunMonTueWedThuFriSat");
-       static gchar *tr_wday = NULL;
-       struct tm *lt;
-       gint wdlen;
-       gchar *wday;
-
-       if (!tr_wday)
-               tr_wday = g_strdup(gettext(wdaystr));
-
-       lt = localtime(&timer);
-
-       wdlen = strlen(tr_wday) / 7;
-       if ((wday = alloca(wdlen + 1))) {
-               strncpy(wday, tr_wday + lt->tm_wday * wdlen, wdlen);
-               wday[wdlen] = '\0';
-       }
-
-       g_snprintf(dest, len, "%02d/%d/%d(%s) %02d:%02d",
-                  lt->tm_year % 100, lt->tm_mon + 1, lt->tm_mday,
-                  wday, lt->tm_hour, lt->tm_min);
-#endif
+               strftime(dest, len, default_format, lt);
 }