diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-10-07 13:23:45 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-10-07 13:23:45 +0300 |
commit | dd8d091ba3cae58fd437c664478de8bcbdf25ac6 (patch) | |
tree | 8ffdc4ca5a4a05808d247a69ca87635a9f92a71a /libmailutils | |
parent | f24df125b4a5f7e29eee39e89127871a38856281 (diff) | |
download | mailutils-dd8d091ba3cae58fd437c664478de8bcbdf25ac6.tar.gz mailutils-dd8d091ba3cae58fd437c664478de8bcbdf25ac6.tar.bz2 |
Implement a filter for quoting ^From. Use it for appending to UNIX mailboxes.
* libmailutils/fromflt.c: New file.
* libmailutils/Makefile.am (libmailutils_la_SOURCES): Add fromflt.c
* libmailutils/tests/testsuite.at: Include fromflt.at.
* include/mailutils/filter.h (mu_from_filter): New filter type.
* libmailutils/filter.c (mu_filter_get_list): Register mu_from_filter.
* libmailutils/fromflt.at: New file.
* libmailutils/tests/Makefile.am (TESTSUITE_AT): Add fromflt.at.
* libmailutils/tests/base64d.at: Mention `filter' in the keywords.
* libmailutils/tests/base64e.at: Likewise.
* libmailutils/tests/fltst.c (main): Fix argc check.
* libproto/mbox/mbox.c (append_message_to_stream): Use "FROM" filter.
Diffstat (limited to 'libmailutils')
-rw-r--r-- | libmailutils/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/filter.c | 1 | ||||
-rw-r--r-- | libmailutils/fromflt.c | 283 | ||||
-rw-r--r-- | libmailutils/tests/Makefile.am | 1 | ||||
-rw-r--r-- | libmailutils/tests/base64d.at | 4 | ||||
-rw-r--r-- | libmailutils/tests/base64e.at | 4 | ||||
-rw-r--r-- | libmailutils/tests/fltst.c | 2 | ||||
-rw-r--r-- | libmailutils/tests/fromflt.at | 96 | ||||
-rw-r--r-- | libmailutils/tests/testsuite.at | 1 |
9 files changed, 388 insertions, 5 deletions
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index 3f083e01d..07a0a4e54 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am | |||
@@ -83,6 +83,7 @@ libmailutils_la_SOURCES = \ | |||
83 | fltstream.c\ | 83 | fltstream.c\ |
84 | folder.c\ | 84 | folder.c\ |
85 | freeitem.c\ | 85 | freeitem.c\ |
86 | fromflt.c\ | ||
86 | gdebug.c\ | 87 | gdebug.c\ |
87 | getpass.c\ | 88 | getpass.c\ |
88 | gocs.c\ | 89 | gocs.c\ |
diff --git a/libmailutils/filter.c b/libmailutils/filter.c index 8fdc25f90..0008ba0f1 100644 --- a/libmailutils/filter.c +++ b/libmailutils/filter.c | |||
@@ -78,6 +78,7 @@ mu_filter_get_list (mu_list_t *plist) | |||
78 | mu_list_append (filter_list, mu_dot_filter); | 78 | mu_list_append (filter_list, mu_dot_filter); |
79 | mu_list_append (filter_list, mu_rfc_2047_Q_filter); | 79 | mu_list_append (filter_list, mu_rfc_2047_Q_filter); |
80 | mu_list_append (filter_list, mu_rfc_2047_B_filter); | 80 | mu_list_append (filter_list, mu_rfc_2047_B_filter); |
81 | mu_list_append (filter_list, mu_from_filter); | ||
81 | /* FIXME: add the default encodings? */ | 82 | /* FIXME: add the default encodings? */ |
82 | } | 83 | } |
83 | *plist = filter_list; | 84 | *plist = filter_list; |
diff --git a/libmailutils/fromflt.c b/libmailutils/fromflt.c new file mode 100644 index 000000000..d96d46d85 --- /dev/null +++ b/libmailutils/fromflt.c | |||
@@ -0,0 +1,283 @@ | |||
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2003, 2007, 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library; if not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | Boston, MA 02110-1301 USA */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include <config.h> | ||
21 | #endif | ||
22 | |||
23 | #include <stdlib.h> | ||
24 | #include <string.h> | ||
25 | #include <mailutils/errno.h> | ||
26 | #include <mailutils/filter.h> | ||
27 | #include <mailutils/stream.h> | ||
28 | |||
29 | enum from_decode_state | ||
30 | { | ||
31 | from_decode_init, | ||
32 | from_decode_nl, | ||
33 | from_decode_char | ||
34 | }; | ||
35 | |||
36 | #define GT_FROM_MARK_STR ">From " | ||
37 | #define GT_FROM_MARK_LEN (sizeof (GT_FROM_MARK_STR) - 1) | ||
38 | |||
39 | /* Move min(isize,osize) bytes from iptr to optr, replacing each '>From ' | ||
40 | at the beginning of line with 'From '. */ | ||
41 | static enum mu_filter_result | ||
42 | _from_decoder (void *xd, | ||
43 | enum mu_filter_command cmd, | ||
44 | struct mu_filter_io *iobuf) | ||
45 | { | ||
46 | int *pstate = xd; | ||
47 | const unsigned char *iptr; | ||
48 | size_t isize; | ||
49 | char *optr; | ||
50 | size_t osize; | ||
51 | enum from_decode_state state; | ||
52 | size_t i, j; | ||
53 | |||
54 | switch (cmd) | ||
55 | { | ||
56 | case mu_filter_init: | ||
57 | *pstate = from_decode_init; | ||
58 | return mu_filter_ok; | ||
59 | |||
60 | case mu_filter_done: | ||
61 | return mu_filter_ok; | ||
62 | |||
63 | default: | ||
64 | state = *pstate; | ||
65 | break; | ||
66 | } | ||
67 | |||
68 | iptr = (const unsigned char *) iobuf->input; | ||
69 | isize = iobuf->isize; | ||
70 | optr = iobuf->output; | ||
71 | osize = iobuf->osize; | ||
72 | |||
73 | for (i = j = 0; i < isize && j < osize; i++) | ||
74 | { | ||
75 | unsigned char c = *iptr++; | ||
76 | |||
77 | if (c == '\n') | ||
78 | state = from_decode_nl; | ||
79 | else if (state == from_decode_init || state == from_decode_nl) | ||
80 | { | ||
81 | size_t len = isize - i; | ||
82 | |||
83 | if (len < GT_FROM_MARK_LEN) | ||
84 | { | ||
85 | if (memcmp (iptr - 1, GT_FROM_MARK_STR, len) == 0) | ||
86 | { | ||
87 | if (i == 0) | ||
88 | { | ||
89 | iobuf->isize = GT_FROM_MARK_LEN - len; | ||
90 | return mu_filter_moreinput; | ||
91 | } | ||
92 | break; | ||
93 | } | ||
94 | else | ||
95 | state = from_decode_char; | ||
96 | } | ||
97 | else if (memcmp (iptr - 1, GT_FROM_MARK_STR, GT_FROM_MARK_LEN) == 0) | ||
98 | { | ||
99 | /* Skip > */ | ||
100 | state = from_decode_char; | ||
101 | continue; | ||
102 | } | ||
103 | } | ||
104 | optr[j++] = c; | ||
105 | } | ||
106 | |||
107 | *pstate = state; | ||
108 | iobuf->isize = i; | ||
109 | iobuf->osize = j; | ||
110 | return mu_filter_ok; | ||
111 | } | ||
112 | |||
113 | #define FROM_MARK_STR "From " | ||
114 | #define FROM_MARK_LEN (sizeof (FROM_MARK_STR) - 1) | ||
115 | |||
116 | enum from_encode_state | ||
117 | { | ||
118 | from_encode_init, | ||
119 | from_encode_nl, | ||
120 | from_encode_char, | ||
121 | from_encode_gt, | ||
122 | from_encode_f, | ||
123 | from_encode_r, | ||
124 | from_encode_o, | ||
125 | from_encode_m, | ||
126 | from_encode_sp | ||
127 | }; | ||
128 | |||
129 | static int length_to_state_tab[] = { | ||
130 | from_encode_gt, | ||
131 | from_encode_f, | ||
132 | from_encode_r, | ||
133 | from_encode_o, | ||
134 | from_encode_m, | ||
135 | from_encode_sp | ||
136 | }; | ||
137 | |||
138 | static int state_to_length_tab[] = { | ||
139 | 0, 0, 0, | ||
140 | GT_FROM_MARK_LEN, | ||
141 | GT_FROM_MARK_LEN-1, | ||
142 | GT_FROM_MARK_LEN-2, | ||
143 | GT_FROM_MARK_LEN-3, | ||
144 | GT_FROM_MARK_LEN-4, | ||
145 | GT_FROM_MARK_LEN-5 | ||
146 | }; | ||
147 | |||
148 | /* Move min(isize,osize) bytes from iptr to optr, replacing each 'From ' | ||
149 | at the beginning of line with '>From '. */ | ||
150 | |||
151 | static enum mu_filter_result | ||
152 | _from_encoder (void *xd, | ||
153 | enum mu_filter_command cmd, | ||
154 | struct mu_filter_io *iobuf) | ||
155 | { | ||
156 | int *pstate = xd; | ||
157 | const unsigned char *iptr; | ||
158 | size_t isize; | ||
159 | char *optr; | ||
160 | size_t osize; | ||
161 | enum from_encode_state state; | ||
162 | size_t i, j; | ||
163 | |||
164 | switch (cmd) | ||
165 | { | ||
166 | case mu_filter_init: | ||
167 | *pstate = from_encode_init; | ||
168 | return mu_filter_ok; | ||
169 | |||
170 | case mu_filter_done: | ||
171 | return mu_filter_ok; | ||
172 | |||
173 | default: | ||
174 | state = *pstate; | ||
175 | switch (state) | ||
176 | { | ||
177 | case from_encode_init: | ||
178 | case from_encode_nl: | ||
179 | case from_encode_char: | ||
180 | break; | ||
181 | |||
182 | default: | ||
183 | osize = state_to_length_tab[state]; | ||
184 | if (iobuf->osize < osize) | ||
185 | { | ||
186 | iobuf->osize = osize; | ||
187 | return mu_filter_moreoutput; | ||
188 | } | ||
189 | memcpy (iobuf->output, GT_FROM_MARK_STR + GT_FROM_MARK_LEN - osize, | ||
190 | osize); | ||
191 | iobuf->osize = osize; | ||