added additionnal matching criteria
[claws.git] / src / procheader.c
index 76ba1409d42f5b2bdbc004f3bb7d1098d58ae4ec..49a03b57b90fbac6a7e9b422be6b6fc3d4130126 100644 (file)
 
 #define BUFFSIZE       8192
 
-/*
-  procheader_get_one_field
-  - reads fp and puts the header and the corresponding content into buf
-    if one of these is one of hentry table.
-  - if hentry is NULL, ignores no headers
- */
-
 gint procheader_get_one_field(gchar *buf, gint len, FILE *fp,
                              HeaderEntry hentry[])
 {
@@ -192,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 == ':') {
@@ -220,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];
@@ -258,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);
@@ -281,7 +428,8 @@ enum
        H_CONTENT_TYPE  = 9,
        H_SEEN          = 10,
        H_X_FACE        = 11,
-       H_DISPOSITION_NOTIFICATION_TO = 12
+       H_DISPOSITION_NOTIFICATION_TO = 12,
+       H_RETURN_RECEIPT_TO = 13
 };
 
 MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
@@ -298,7 +446,8 @@ 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},
+                                          {"Disposition-Notification-To:", NULL, FALSE},
+                                          {"Return-Receipt-To:", NULL, FALSE},
                                           {NULL,               NULL, FALSE}};
 
        static HeaderEntry hentry_short[] = {{"Date:",          NULL, FALSE},
@@ -399,6 +548,7 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                        break;
                case H_REFERENCES:
                        if (!reference) {
+                               msginfo->references = g_strdup(hp);
                                eliminate_parenthesis(hp, '(', ')');
                                if ((p = strrchr(hp, '<')) != NULL &&
                                    strchr(p + 1, '>') != NULL) {
@@ -434,6 +584,10 @@ MsgInfo *procheader_parse(const gchar *file, MsgFlags flags, gboolean full)
                        if (msginfo->dispositionnotificationto) break;
                        msginfo->dispositionnotificationto = g_strdup(hp);
                        break;
+               case H_RETURN_RECEIPT_TO:
+                       if (msginfo->returnreceiptto) break;
+                       msginfo->returnreceiptto = g_strdup(hp);
+                       break;
                default:
                }
        }