Statistics
| Revision:

root / src / unmime.c @ 1

History | View | Annotate | Download (3.33 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2003 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19

    
20
#ifdef HAVE_CONFIG_H
21
#  include "config.h"
22
#endif
23

    
24
#include <glib.h>
25
#include <string.h>
26
#include <ctype.h>
27

    
28
#include "codeconv.h"
29
#include "base64.h"
30
#include "quoted-printable.h"
31

    
32
#define ENCODED_WORD_BEGIN        "=?"
33
#define ENCODED_WORD_END        "?="
34

    
35
/* Decodes headers based on RFC2045 and RFC2047. */
36

    
37
void unmime_header(gchar *out, const gchar *str)
38
{
39
        const gchar *p = str;
40
        gchar *outp = out;
41
        const gchar *eword_begin_p, *encoding_begin_p, *text_begin_p,
42
                    *eword_end_p;
43
        gchar charset[32];
44
        gchar encoding;
45
        gchar *conv_str;
46
        gint len;
47

    
48
        while (*p != '\0') {
49
                gchar *decoded_text = NULL;
50

    
51
                eword_begin_p = strstr(p, ENCODED_WORD_BEGIN);
52
                if (!eword_begin_p) {
53
                        strcpy(outp, p);
54
                        return;
55
                }
56
                encoding_begin_p = strchr(eword_begin_p + 2, '?');
57
                if (!encoding_begin_p) {
58
                        strcpy(outp, p);
59
                        return;
60
                }
61
                text_begin_p = strchr(encoding_begin_p + 1, '?');
62
                if (!text_begin_p) {
63
                        strcpy(outp, p);
64
                        return;
65
                }
66
                eword_end_p = strstr(text_begin_p + 1, ENCODED_WORD_END);
67
                if (!eword_end_p) {
68
                        strcpy(outp, p);
69
                        return;
70
                }
71

    
72
                if (p == str) {
73
                        memcpy(outp, p, eword_begin_p - p);
74
                        outp += eword_begin_p - p;
75
                        p = eword_begin_p;
76
                } else {
77
                        /* ignore spaces between encoded words */
78
                        const gchar *sp;
79

    
80
                        for (sp = p; sp < eword_begin_p; sp++) {
81
                                if (!isspace(*(const guchar *)sp)) {
82
                                        memcpy(outp, p, eword_begin_p - p);
83
                                        outp += eword_begin_p - p;
84
                                        p = eword_begin_p;
85
                                        break;
86
                                }
87
                        }
88
                }
89

    
90
                len = MIN(sizeof(charset) - 1,
91
                          encoding_begin_p - (eword_begin_p + 2));
92
                memcpy(charset, eword_begin_p + 2, len);
93
                charset[len] = '\0';
94
                encoding = toupper(*(encoding_begin_p + 1));
95

    
96
                if (encoding == 'B') {
97
                        decoded_text = g_malloc
98
                                (eword_end_p - (text_begin_p + 1) + 1);
99
                        len = base64_decode(decoded_text, text_begin_p + 1,
100
                                            eword_end_p - (text_begin_p + 1));
101
                        decoded_text[len] = '\0';
102
                } else if (encoding == 'Q') {
103
                        decoded_text = g_malloc
104
                                (eword_end_p - (text_begin_p + 1) + 1);
105
                        len = qp_decode_q_encoding
106
                                (decoded_text, text_begin_p + 1,
107
                                 eword_end_p - (text_begin_p + 1));
108
                } else {
109
                        memcpy(outp, p, eword_end_p + 2 - p);
110
                        outp += eword_end_p + 2 - p;
111
                        p = eword_end_p + 2;
112
                        continue;
113
                }
114

    
115
                /* convert to locale encoding */
116
                conv_str = conv_codeset_strdup(decoded_text, charset, NULL);
117
                if (conv_str) {
118
                        len = strlen(conv_str);
119
                        memcpy(outp, conv_str, len);
120
                        g_free(conv_str);
121
                } else {
122
                        len = strlen(decoded_text);
123
                        conv_localetodisp(outp, len + 1, decoded_text);
124
                }
125
                outp += len;
126

    
127
                g_free(decoded_text);
128

    
129
                p = eword_end_p + 2;
130
        }
131

    
132
        *outp = '\0';
133
}