annotate mime-support.sl @ 0:cdc3d19f5ba5 default tip

Initial revision
author Guido Berhoerster <guido+slrn@berhoerster.name>
date Sat, 21 May 2016 11:12:14 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
1 % Copyright (C) 2013 Guido Berhoerster <guido+slrn@berhoerster.name>
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
2 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
3 % This file incorporates work from the file mime.sl distributed with slrn under
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
4 % the terms of the GNU General Public Licens version 2 or later.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
5 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
6 % Copyright (C) 2012 John E. Davis <jed@jedsoft.org>
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
7 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
8 % This program is free software; you can redistribute it and/or modify
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
9 % it under the terms of the GNU General Public License as published by
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
10 % the Free Software Foundation; either version 2 of the License, or
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
11 % (at your option) any later version.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
12 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
13 % This program is distributed in the hope that it will be useful,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
14 % but WITHOUT ANY WARRANTY; without even the implied warranty of
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
15 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
16 % GNU General Public License for more details.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
17 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
18 % You should have received a copy of the GNU General Public License along
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
19 % with this program; if not, write to the Free Software Foundation, Inc.,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
20 % 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
21
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
22 %open_log_file(make_home_filename("slrn-debug.log"));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
23 %_traceback = 1;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
24
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
25 require("rand");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
26 require("mailcap");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
27
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
28 implements("MIMESupport");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
29
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
30 private variable FILENAME_CHARS =
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
31 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
32 private variable FILENAME_CHARS_LEN = strlen(FILENAME_CHARS);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
33 private variable mime_save_dir = make_home_filename("");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
34
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
35 private define quote_shell_arg(arg)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
36 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
37 variable c;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
38 variable result = "'";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
39
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
40 foreach c (arg) using ("bytes") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
41 if (c == '\'')
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
42 result += "'\"'\"'";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
43 else
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
44 result += char(c);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
45 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
46 result += "'";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
47
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
48 return result;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
49 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
50
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
51 private define mkstemps(template, suffix_len)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
52 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
53 variable fd;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
54 variable temp_filename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
55 variable suffix;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
56 variable template_len = strlen(@template);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
57 variable c;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
58
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
59 if (template_len < 6)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
60 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
61 c = template_len - suffix_len - 6;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
62 suffix = substr(@template, template_len - suffix_len + 1, suffix_len);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
63 if (substr(@template, c + 1, 6) != "XXXXXX")
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
64 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
65
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
66 loop (10000) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
67 temp_filename = substr(@template, 1, c);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
68 loop(6) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
69 temp_filename += FILENAME_CHARS[[rand() mod FILENAME_CHARS_LEN]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
70 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
71 temp_filename += suffix;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
72 fd = open(temp_filename, O_CREAT|O_EXCL|O_RDWR, 0600);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
73 if (fd != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
74 @template = temp_filename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
75 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
76 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
77 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
78
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
79 return fd;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
80 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
81
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
82 private define mkstemp(template)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
83 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
84 return mkstemps(template, 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
85 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
86
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
87 private variable mime_save_charset = get_charset("display");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
88 private variable raw_article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
89 private variable rendered_article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
90 private variable article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
91 private variable mime_object_list;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
92 private variable tmpdir = getenv("TMPDIR");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
93 if (tmpdir == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
94 tmpdir = "/tmp";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
95 private variable pager_command = getenv("PAGER");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
96 if (pager_command == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
97 pager_command = "more";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
98 private variable auto_view_mailcap_entries = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
99 static variable config = struct {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
100 auto_view = ["text/html"]
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
101 };
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
102
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
103 private define mime_set_save_charset(charset)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
104 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
105 mime_save_charset = charset;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
106 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
107
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
108 private define mime_get_save_charset()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
109 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
110 return mime_save_charset;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
111 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
112
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
113 private define mime_set_header_key(hash, name, value)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
114 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
115 hash[strlow(name)] = struct {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
116 name = name,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
117 value = strtrim(value),
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
118 };
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
119 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
120
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
121 private define mime_get_header_key(hash, name, lowercase)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
122 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
123 try {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
124 variable h = hash[strlow(name)];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
125 return h.value;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
126 } catch AnyError;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
127
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
128 return "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
129 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
130
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
131 private define mime_split_article(art)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
132 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
133 variable ofs = is_substrbytes(art, "\n\n");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
134
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
135 if (ofs == 0) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
136 throw DataError, "Unable to find the header separator";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
137 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
138
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
139 variable header = substrbytes(art, 1, ofs - 1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
140 (header,) = strreplace(header, "\n ", " ", strbytelen(header));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
141 (header,) = strreplace(header, "\n\t", " ", strbytelen(header));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
142 header = strchop(header, '\n', 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
143
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
144 variable hash = Assoc_Type[Struct_Type];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
145 _for (0, length(header) - 1, 1) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
146 variable i = ();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
147 variable fields = strchop(header[i], ':', 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
148 mime_set_header_key(hash, fields[0], strjoin(fields[[1:]], ":"));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
149 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
150 variable body = substrbytes(art, ofs + 2, -1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
151
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
152 return hash, body;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
153 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
154
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
155 private define mime_parse_subkeyword(key, word)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
156 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
157 variable val = string_matches(key, `\C` + word + ` *= *"\([^"]+\)"`);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
158 if (val == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
159 val = string_matches(key, `\C` + word + ` *= *\([^; ]+\)`);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
160 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
161 if (val == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
162 return val;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
163 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
164
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
165 return val[1];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
166 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
167
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
168 private define get_multipart_boundary(header)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
169 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
170 variable ct = mime_get_header_key(header, "Content-Type", 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
171 if (ct == "") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
172 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
173 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
174
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
175 ifnot (is_substr(strlow(ct), "multipart/")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
176 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
177 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
178
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
179 variable boundary = mime_parse_subkeyword(ct, "boundary");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
180 if (boundary == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
181 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
182 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
183
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
184 return boundary;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
185 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
186
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
187 % The idea here is to represent an article as a list of mime objects
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
188 % in the form of a tree. For a non-multipart article, there is only
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
189 % one node. For a multipart message, there will be a linked list of
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
190 % nodes, one for each subpart. If the subpart is a multipart, a new
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
191 % subtree will begin. For example, here is an article with a
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
192 % two-multiparts, with the second contained in the first.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
193 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
194 % article
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
195 % / \
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
196 % /\
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
197 %
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
198 private variable Mime_Node_Type = struct {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
199 mimetype, % lowercase type/subtype, from content-type
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
200 disposition, % content-disposition header
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
201 content_type, % full content-type header
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
202 header, % assoc array of header keywords
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
203 list, % non-null list of nodes if multipart
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
204 message, % non-multipart decoded message
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
205 charset,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
206 encoding
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
207 };
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
208
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
209 private define mime_parse_mime();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
210 private define parse_multipart(node, body)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
211 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
212 variable boundary = get_multipart_boundary(node.header);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
213 if (boundary == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
214 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
215 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
216
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
217 boundary = "--" + boundary;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
218 variable blen = strbytelen(boundary);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
219 variable boundary_end = boundary + "--";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
220 variable blen_end = blen + 2;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
221
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
222 node.list = {};
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
223
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
224 body = strchop(body, '\n', 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
225 variable i = 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
226 variable imax = length(body);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
227 while (i < imax) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
228 if (strnbytecmp(body[i], boundary, blen)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
229 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
230 continue;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
231 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
232
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
233 if (strnbytecmp(body[i], boundary_end, blen_end) == 0) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
234 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
235 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
236
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
237 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
238 variable i0 = i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
239 if (i0 == imax) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
240 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
241 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
242
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
243 while (i < imax) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
244 if (strnbytecmp(body[i], boundary, blen)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
245 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
246 continue;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
247 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
248 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
249 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
250 variable new_node = mime_parse_mime(strjoin(body[[i0:i-1]], "\n"));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
251 if (new_node != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
252 list_append(node.list, new_node);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
253 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
254 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
255 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
256
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
257 private define mime_extract_mimetype(content_type)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
258 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
259 return strlow(strtrim(strchop(content_type, ';', 0)[0]));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
260 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
261
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
262 private define mime_parse_mime(art)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
263 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
264 variable header, body;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
265 (header, body) = mime_split_article(art);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
266
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
267 variable node = @Mime_Node_Type;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
268 node.content_type = mime_get_header_key(header, "Content-Type", 1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
269 node.disposition = mime_get_header_key(header, "Content-Disposition", 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
270 node.header = header;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
271 node.mimetype = mime_extract_mimetype(node.content_type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
272
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
273 if (is_substr(node.mimetype, "multipart/")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
274 parse_multipart(node, body);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
275 return node;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
276 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
277
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
278 node.message = body;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
279
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
280 variable encoding = mime_get_header_key(header,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
281 "Content-Transfer-Encoding", 1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
282 encoding = strlow(encoding);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
283 if (is_substr(encoding, "base64")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
284 node.encoding = "base64";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
285 } else if (is_substr(encoding, "quoted-printable")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
286 node.encoding = "quoted-printable";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
287 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
288
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
289 node.charset = mime_parse_subkeyword(node.content_type, "charset");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
290
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
291 return node;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
292 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
293
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
294 private define mime_flatten_node_tree(node, leaves); % recursive
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
295 private define mime_flatten_node_tree(node, leaves)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
296 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
297 if (node.list == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
298 list_append(leaves, node);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
299 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
300 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
301
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
302 foreach node (node.list) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
303 mime_flatten_node_tree(node, leaves);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
304 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
305 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
306
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
307 % Returns NULL if the message is not Mime Encoded, otherwise it
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
308 % returns the value of the Content-Type header.
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
309 private define mime_is_mime_message()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
310 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
311 variable h = extract_article_header("Mime-Version");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
312 if ((h == NULL) || (h == "")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
313 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
314 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
315
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
316 h = extract_article_header("Content-Type");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
317 if (h == "") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
318 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
319 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
320 return h;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
321 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
322
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
323 private define mime_is_attachment(node)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
324 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
325 return is_substrbytes(strlow(node.disposition), "attachment");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
326 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
327
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
328 private define mime_is_text(node)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
329 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
330 return is_substrbytes(node.mimetype, "text/");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
331 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
332
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
333 private define mime_get_mime_filename(node)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
334 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
335 variable file = mime_parse_subkeyword(node.disposition, "filename");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
336 if (file != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
337 return file;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
338 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
339 file = mime_parse_subkeyword(node.content_type, "name");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
340 if (file != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
341 return file;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
342 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
343
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
344 return "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
345 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
346
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
347 private define mime_convert_mime_object(obj)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
348 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
349 variable str = obj.message;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
350 if (str == "") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
351 return str;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
352 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
353
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
354 if (obj.encoding == "base64") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
355 str = decode_base64_string(str);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
356 } else if (obj.encoding == "quoted-printable") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
357 str = decode_qp_string(str);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
358 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
359
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
360 variable charset = obj.charset;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
361 if ((charset != NULL) && (charset != "") && (mime_save_charset != NULL) &&
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
362 (strlow(charset) != strlow(mime_save_charset))) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
363 str = charset_convert_string(str, charset, mime_save_charset, 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
364 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
365 return str;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
366 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
367
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
368 private define mime_save_mime_object(obj, fp)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
369 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
370 if (typeof(fp) == String_Type) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
371 variable file = fp;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
372 fp = fopen(file, "w");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
373 if (fp == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
374 throw OpenError, "Could not open $file for writing"$;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
375 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
376 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
377
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
378 variable str = mime_convert_mime_object(obj);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
379
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
380 () = fwrite(str, fp);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
381 () = fflush(fp);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
382 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
383
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
384 private define find_filename_placeholder(template)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
385 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
386 variable i = 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
387 variable s;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
388 variable len = strbytelen(template);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
389
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
390 while (i + 1 < len) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
391 s = template[[i:i + 1]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
392 if (s == "\\%") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
393 i += 2;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
394 } else if (s == "%s") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
395 return i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
396 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
397 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
398 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
399 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
400
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
401 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
402 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
403
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
404 private define mailcap_substitute(template, filename, content_type)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
405 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
406 variable mimetype = mime_extract_mimetype(content_type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
407 variable i = 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
408 variable j;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
409 variable s;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
410 variable len = strbytelen(template);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
411 variable key;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
412 variable value;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
413 variable result = "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
414
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
415 while (i < len) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
416 if (i + 1 < len) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
417 s = template[[i:i + 1]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
418 switch(s)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
419 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
420 case "\\%":
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
421 result += "%";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
422 i += 2;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
423 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
424 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
425 case "%s":
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
426 result += filename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
427 i += 2;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
428 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
429 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
430 case "%t":
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
431 result += mimetype;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
432 i += 2;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
433 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
434 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
435 case "%{":
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
436 key = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
437 for (j = i + 2; j < len; j++) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
438 if (template[j] == '}') {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
439 key = template[[i + 2:j -1]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
440 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
441 } else ifnot (isalnum(template[j])) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
442 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
443 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
444 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
445 if (key != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
446 if (key == "charset")
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
447 value = mime_get_save_charset();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
448 else
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
449 value = mime_parse_subkeyword(content_type, key);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
450 if (value == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
451 value = "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
452 result += quote_shell_arg(value);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
453 i = j + 1;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
454 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
455 result += template[[i]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
456 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
457 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
458 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
459 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
460 result += template[[i]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
461 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
462 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
463 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
464 result += template[[i]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
465 i++;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
466 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
467 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
468
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
469 return result;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
470 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
471
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
472 private define mailcap_view_part(mc_entry, data)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
473 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
474 variable filter = qualifier_exists("filter");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
475 variable lines;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
476 variable command;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
477 variable use_input_tmpfile;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
478 variable mask;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
479 variable fd = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
480 variable fp_in = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
481 variable fp_out = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
482 variable fp_pager = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
483 variable i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
484 variable tmpfilename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
485 variable suffixlen;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
486 variable command_status = 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
487 variable pager_status = 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
488 variable text;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
489
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
490 if (filter && (mc_entry._copiousoutput == 0))
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
491 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
492
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
493 try {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
494 command = mc_entry._command;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
495 use_input_tmpfile = (find_filename_placeholder(command) != NULL);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
496 if (use_input_tmpfile) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
497 % the command reads the input from a temporary file
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
498 tmpfilename = mc_entry._nametemplate;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
499 if ((tmpfilename == NULL) ||
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
500 (find_filename_placeholder(tmpfilename) == NULL))
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
501 tmpfilename = "slrn%s";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
502 tmpfilename = path_concat(tmpdir, path_basename(tmpfilename));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
503 i = find_filename_placeholder(tmpfilename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
504 suffixlen = strbytelen(tmpfilename) - (i + 2);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
505 tmpfilename = tmpfilename[[0:i - 1]] + "XXXXXX" +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
506 tmpfilename[[i + 2:]];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
507 mask = umask(077);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
508 fd = mkstemps(&tmpfilename, suffixlen);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
509 if (fd == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
510 throw OpenError, "Could not create temporary file";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
511 fp_in = fdopen(fd, "w+");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
512 if (fp_in == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
513 throw OpenError, "Could not open temporary file";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
514 if (fwrite(data, fp_in) == -1) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
515 throw WriteError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
516 "Failed to write to file \"$tmpfilename\": "$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
517 errno_string(errno);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
518 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
519 () = fflush(fp_in);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
520
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
521 command = mailcap_substitute(command, tmpfilename, mc_entry._type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
522 if (mc_entry._copiousoutput) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
523 % output is read back from the command's stdout
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
524 fp_out = popen(command, "r");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
525 if (fp_out == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
526 throw OSError, "Failed to execute $command"$;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
527 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
528 system(command);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
529 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
530 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
531 % the command reads the input from its stdin
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
532 command = mailcap_substitute(command, "", mc_entry._type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
533 if (mc_entry._copiousoutput) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
534 % create temporary file for the output if the command is
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
535 % non-interactive
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
536 tmpfilename = path_concat(tmpdir, "slrnXXXXXX");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
537 mask = umask(077);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
538 fd = mkstemp(&tmpfilename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
539 if (fd == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
540 throw OpenError, "Could not create temporary file";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
541 fp_out = fdopen(fd, "r+");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
542 if (fp_out == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
543 throw OpenError, "Could not open temporary file";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
544
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
545 command += " > " + tmpfilename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
546 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
547
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
548 fp_in = popen(command, "w");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
549 if (fp_in == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
550 throw OSError, "Failed to execute $command"$;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
551 if (fputs(data, fp_in) == -1)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
552 throw WriteError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
553 "Failed to write to command \"$command\": "$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
554 errno_string(errno);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
555 () = fflush(fp_in);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
556 command_status = pclose(fp_in);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
557 fp_in = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
558 ifnot (command_status == 0) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
559 throw OSError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
560 "Command \"$command\" returned a non-zero exit "$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
561 "status: " + string(command_status);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
562 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
563 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
564
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
565 % read back the output if the command is non-interactive
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
566 if (mc_entry._copiousoutput) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
567 lines = fgetslines(fp_out);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
568 if (lines == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
569 throw ReadError, "Failed to read output: " +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
570 errno_string(errno);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
571 text = strjoin(lines, "");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
572
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
573 if (filter) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
574 return text;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
575 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
576 fp_pager = popen(pager_command, "w");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
577 if (fp_pager == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
578 throw OSError, "Failed to execute $pager_command"$;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
579 if (fputs(text, fp_pager) == -1)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
580 throw WriteError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
581 "Failed to write to command \"$command\": "$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
582 errno_string(errno);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
583 () = fflush(fp_pager);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
584 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
585 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
586
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
587 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
588 } finally {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
589 % remove temporary input or output file
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
590 if (fd != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
591 () = remove(tmpfilename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
592
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
593 if (use_input_tmpfile) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
594 if (fp_in != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
595 () = fclose(fp_in);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
596 else if (fd != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
597 () = close(fd);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
598
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
599 if (fp_out != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
600 command_status = pclose(fp_out);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
601 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
602 if (mc_entry._copiousoutput) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
603 if (fp_out != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
604 () = fclose(fp_out);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
605 else if (fd != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
606 () = close(fd);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
607 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
608
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
609 if (fp_in != NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
610 command_status = pclose(fp_in);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
611 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
612
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
613 if (fp_pager != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
614 pager_status = pclose(fp_pager);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
615 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
616
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
617 if (command_status != 0)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
618 throw OSError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
619 "Command \"$command\" returned a non-zero exit "$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
620 "status: " + string(command_status);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
621
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
622 if (pager_status != 0)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
623 throw OSError,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
624 "Command \"$pager_command\" returned a"$ +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
625 "non-zero exit status: " + string(pager_status);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
626 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
627 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
628
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
629 private define render_part(node, rendered_message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
630 private define render_part(node, rendered_message)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
631 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
632 variable mc_entry;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
633 variable i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
634 variable j;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
635 variable best_match_node = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
636 variable text_node = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
637 variable subnode;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
638 variable text;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
639 variable raw_message;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
640 variable header;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
641 variable value;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
642
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
643 if (node.mimetype == "multipart/alternative") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
644 % select best match based on the order of the entries in
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
645 % config.auto_view, text/plain is always preferred and the first text
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
646 % part is used as a fallback in case there is no match
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
647 j = length(auto_view_mailcap_entries);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
648 foreach subnode (node.list) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
649 if (subnode.mimetype == "text/plain") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
650 best_match_node = subnode;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
651 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
652 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
653 for (i = 0; i < j; i++) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
654 if (subnode.mimetype == auto_view_mailcap_entries[i]._type) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
655 best_match_node = subnode;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
656 j = i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
657 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
658 } else if ((text_node == NULL) && mime_is_text(subnode)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
659 text_node = subnode;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
660 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
661 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
662 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
663 if (best_match_node != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
664 render_part(best_match_node, rendered_message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
665 } else if (text_node != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
666 render_part(text_node, rendered_message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
667 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
668 @rendered_message += "[-- Unhandled MIME Alternative Parts --]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
669 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
670 } else if ((node.mimetype == "multipart/mixed") ||
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
671 (node.mimetype == "multipart/digest") ||
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
672 (node.mimetype == "multipart/related") ||
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
673 (node.mimetype == "multipart/signed")) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
674 foreach subnode (node.list) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
675 render_part(subnode, rendered_message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
676 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
677 } else if (node.mimetype == "message/rfc822") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
678 % inline message
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
679 subnode = mime_parse_mime(node.message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
680
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
681 @rendered_message += "[-- MIME Message (" + node.mimetype + ") --]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
682 foreach header (strchop(get_visible_headers(), ',', 0)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
683 value = mime_get_header_key(subnode.header, strtrim_end(header, ":"),
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
684 1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
685 ifnot (value == "") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
686 @rendered_message += sprintf("%s %s\n", header, value);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
687 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
688 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
689 @rendered_message += "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
690
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
691 if (subnode.mimetype != "") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
692 render_part(subnode, rendered_message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
693 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
694 @rendered_message += subnode.message + "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
695 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
696 } else if (node.mimetype == "text/plain") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
697 @rendered_message += mime_convert_mime_object(node) + "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
698 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
699 foreach mc_entry (auto_view_mailcap_entries) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
700 % check if the MIME type is in config.auto_view and if a
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
701 % corresponding mailcap entry exists
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
702 if (node.mimetype == mc_entry._type) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
703 @rendered_message += "[-- MIME Part (" + node.mimetype +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
704 ") --]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
705 text = mailcap_view_part(mc_entry,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
706 mime_convert_mime_object(node); filter);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
707 if (text == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
708 text = "[-- Failed to convert MIME Part to text/plain " +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
709 "--]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
710 @rendered_message += text + "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
711 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
712 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
713 } then {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
714 if (mime_is_text(node)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
715 % otherwise check if the part has a text MIME type and display
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
716 % that as-is
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
717 @rendered_message += "[-- MIME Part (" + node.mimetype +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
718 ") --]\n\n" + mime_convert_mime_object(node) + "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
719 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
720 @rendered_message += "[-- Unhandled MIME Part (" +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
721 node.mimetype + ") --]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
722 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
723 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
724 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
725 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
726
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
727 static define mime_process_article()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
728 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
729 variable content_type = extract_article_header("Content-Type");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
730 variable mimetype;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
731 variable mc_entry;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
732 variable header;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
733 variable body = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
734 variable text;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
735 variable node;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
736 variable value;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
737
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
738 % initialize list of existing config.auto_view mailcap entries
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
739 if (auto_view_mailcap_entries == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
740 auto_view_mailcap_entries = {};
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
741 foreach mimetype (config.auto_view) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
742 mc_entry = mailcap_lookup_entry(mimetype);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
743 if ((mc_entry != NULL) && mc_entry._copiousoutput)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
744 list_append(auto_view_mailcap_entries, mc_entry);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
745 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
746 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
747
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
748 raw_article = raw_article_as_string();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
749 rendered_article = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
750 article = &raw_article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
751
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
752 if (mime_is_mime_message() == NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
753 mime_object_list = NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
754 mimetype = mime_extract_mimetype(content_type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
755
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
756 % handle non-MIME-encoded articles with a Content-Type
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
757 foreach mc_entry (auto_view_mailcap_entries) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
758 % check if the MIME type is in config.auto_view and if a
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
759 % corresponding mailcap entry exists
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
760 if (mimetype == mc_entry._type) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
761 (header, body) = mime_split_article(raw_article);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
762
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
763 rendered_article = "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
764 foreach value (header) using ("values") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
765 rendered_article += sprintf("%s: %s\n", value.name,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
766 value.value);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
767 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
768 rendered_article += "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
769 text = mailcap_view_part(mc_entry, body; filter);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
770 if (text != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
771 rendered_article += "[-- Content (" + mimetype +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
772 ") --]\n\n" + text + "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
773 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
774 rendered_article += "[-- Failed to convert content to " +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
775 "text/plain --]\n\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
776 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
777 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
778 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
779 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
780
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
781 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
782 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
783 mime_object_list = {};
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
784 node = mime_parse_mime(raw_article);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
785
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
786 mime_flatten_node_tree(node, mime_object_list);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
787
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
788 rendered_article = "";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
789 foreach value (node.header) using ("values") {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
790 rendered_article += sprintf("%s: %s\n", value.name, value.value);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
791 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
792 rendered_article += "\n";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
793
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
794 render_part(node, &rendered_article);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
795
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
796 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
797 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
798
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
799 static define mime_show_raw_article()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
800 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
801 if (article != &raw_article) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
802 article = &raw_article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
803 replace_article(raw_article);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
804 update();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
805 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
806 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
807
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
808 static define mime_show_rendered_article()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
809 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
810 if ((article != &rendered_article) && (rendered_article != NULL)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
811 article = &rendered_article;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
812 replace_article(rendered_article);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
813 update();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
814 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
815 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
816
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
817 static define mime_toggle_view()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
818 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
819 if (article == &raw_article)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
820 mime_show_rendered_article();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
821 else
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
822 mime_show_raw_article();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
823 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
824
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
825 static define mime_select_part(title)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
826 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
827 variable selection_list = {};
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
828 variable i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
829 variable len;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
830 variable selection;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
831
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
832 if (mime_object_list == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
833 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
834
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
835 len = length(mime_object_list);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
836 for (i = 0; i < len; i++) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
837 list_append(selection_list, sprintf("%d. %s", i + 1,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
838 mime_object_list[i].mimetype));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
839 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
840 if (i < 1)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
841 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
842
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
843 title;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
844 __push_list(selection_list);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
845 i;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
846 0;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
847 selection = select_list_box();
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
848 if (selection == "")
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
849 return NULL;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
850
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
851 return mime_object_list[integer(substr(selection, 1, 1)) - 1];
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
852 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
853
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
854 static define mime_save_part()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
855 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
856 variable node = mime_select_part("Select MIME part to save");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
857 variable filename;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
858 variable st;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
859 variable n;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
860
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
861 if (node == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
862 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
863
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
864 filename = path_basename(rfc1522_decode_string(mime_get_mime_filename(node)));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
865 filename = path_concat(mime_save_dir, filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
866 filename = strtrim(filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
867 forever {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
868 filename = read_mini_filename("Save to:", "", filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
869 filename = strtrim(filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
870 if ((filename == "") || (filename == mime_save_dir)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
871 message_now("Cancelled");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
872 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
873 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
874 st = stat_file(filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
875 if (st != NULL) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
876 if (stat_is("lnk", st.st_mode) || stat_is("reg", st.st_mode)) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
877 n = get_yes_no_cancel("File '$filename' exists, Overwrite?"$,
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
878 0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
879 if (n == 0)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
880 continue;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
881 else if (n == -1)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
882 message_now("Cancelled");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
883 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
884 } else {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
885 throw OpenError, "Could not open '$filename' for writing"$;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
886 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
887 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
888 mime_save_mime_object(node, filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
889 message_now("Saved to '$filename'"$);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
890 mime_save_dir = path_dirname(filename);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
891 break;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
892 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
893 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
894
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
895 static define mime_view_part()
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
896 {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
897 variable mc;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
898 variable e;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
899 variable line;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
900 variable node = mime_select_part("Select MIME part to view");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
901 if (node == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
902 return;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
903
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
904 mc = mailcap_lookup_entry(node.content_type);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
905 if (mc == NULL)
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
906 throw NotImplementedError, "No viewer for '" + node.mimetype +
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
907 "' available";
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
908 mc.view = &mailcap_view_part;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
909
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
910 try (e) {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
911 set_display_state(0);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
912 mc.view(mime_convert_mime_object(node));
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
913 } catch OSError: {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
914 () = fprintf(stdout, "\n*** ERROR: %S\n\nPress enter to continue.",
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
915 e.message);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
916 () = fgets(&line, stdin);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
917 throw;
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
918 } finally {
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
919 set_display_state(1);
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
920 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
921 }
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
922
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
923 () = register_hook("read_article_hook",
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
924 "MIMESupport->mime_show_rendered_article");
cdc3d19f5ba5 Initial revision
Guido Berhoerster <guido+slrn@berhoerster.name>
parents:
diff changeset
925 () = register_hook("read_article_hook", "MIMESupport->mime_process_article");