summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-03-22 17:27:00 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2011-03-23 09:58:43 +0200
commit5acfb2a37b1bb49474d3bbb0137f22604b508310 (patch)
tree64d7c297bf7d56324f975e5c268a1b03b5d4bdbc
parentdd33613b562970a194917f1934aeab56e3cfc4f9 (diff)
downloadmailutils-5acfb2a37b1bb49474d3bbb0137f22604b508310.tar.gz
mailutils-5acfb2a37b1bb49474d3bbb0137f22604b508310.tar.bz2
New filter "c-escape".
* libmailutils/filter/c-escape.c: New file. * include/mailutils/filter.h (mu_c_escape_filter): New extern. * libmailutils/filter/Makefile.am (libfilter_la_SOURCES): Add c-escape.c * libmailutils/filter/filter.c (mu_filter_get_list): Add mu_c_escape_filter to the list.
-rw-r--r--include/mailutils/filter.h1
-rw-r--r--libmailutils/filter/Makefile.am1
-rw-r--r--libmailutils/filter/c-escape.c157
-rw-r--r--libmailutils/filter/filter.c1
-rw-r--r--mh/etc/components6
5 files changed, 163 insertions, 3 deletions
diff --git a/include/mailutils/filter.h b/include/mailutils/filter.h
index 09d2b9276..d7230665c 100644
--- a/include/mailutils/filter.h
+++ b/include/mailutils/filter.h
@@ -123,6 +123,7 @@ extern mu_filter_record_t mu_header_filter;
extern mu_filter_record_t mu_linecon_filter;
extern mu_filter_record_t mu_linelen_filter;
extern mu_filter_record_t mu_iconv_filter;
+extern mu_filter_record_t mu_c_escape_filter;
enum mu_iconv_fallback_mode
{
diff --git a/libmailutils/filter/Makefile.am b/libmailutils/filter/Makefile.am
index 0788a5c1e..5208b7c4d 100644
--- a/libmailutils/filter/Makefile.am
+++ b/libmailutils/filter/Makefile.am
@@ -20,6 +20,7 @@ noinst_LTLIBRARIES = libfilter.la
libfilter_la_SOURCES =\
base64.c\
binflt.c\
+ c-escape.c\
crlfdot.c\
crlfflt.c\
decode.c\
diff --git a/libmailutils/filter/c-escape.c b/libmailutils/filter/c-escape.c
new file mode 100644
index 000000000..52ea48c5c
--- /dev/null
+++ b/libmailutils/filter/c-escape.c
@@ -0,0 +1,157 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* A C-escape filter.
+ In encode mode, replaces control characters with their C escapes.
+ For example, newline (ASCII 10) becomes \n, horizontal tab (ASCII 9)
+ becomes \t etc.
+ In decode mode, the reverse operation is performed, i.e. each C escape
+ is replaced with the corresponding character. Unrecognized escape
+ sequences are copied verbatim.
+
+ FIXME: Only named escapes are supported.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/errno.h>
+#include <mailutils/filter.h>
+#include <mailutils/wordsplit.h>
+#include <mailutils/cctype.h>
+
+/* Move min(isize,osize) bytes from iptr to optr, replacing each
+ escapable control character with its escape sequence. */
+static enum mu_filter_result
+_c_escape_encoder (void *xd MU_ARG_UNUSED,
+ enum mu_filter_command cmd,
+ struct mu_filter_io *iobuf)
+{
+ size_t i, j;
+ const unsigned char *iptr;
+ size_t isize;
+ char *optr;
+ size_t osize;
+
+ switch (cmd)
+ {
+ case mu_filter_init:
+ case mu_filter_done:
+ return mu_filter_ok;
+ default:
+ break;
+ }
+
+ iptr = (const unsigned char *) iobuf->input;
+ isize = iobuf->isize;
+ optr = iobuf->output;
+ osize = iobuf->osize;
+
+ for (i = j = 0; i < isize && j < osize; i++)
+ {
+ unsigned char c = *iptr++;
+
+ if (mu_iscntrl (c))
+ {
+ int x;
+
+ x = mu_wordsplit_c_quote_char (c);
+ if (x == -1)
+ optr[j++] = c;
+ else if (j + 1 == osize)
+ {
+ if (i == 0)
+ {
+ iobuf->osize = 2;
+ return mu_filter_moreoutput;
+ }
+ break;
+ }
+ else
+ {
+ optr[j++] = '\\';
+ optr[j++] = x;
+ }
+ }
+ else
+ optr[j++] = c;
+ }
+ iobuf->isize = i;
+ iobuf->osize = j;
+ return mu_filter_ok;
+}
+
+/* Move min(isize,osize) bytes from iptr to optr, replacing each escape
+ sequence with its ASCII code. */
+static enum mu_filter_result
+_c_escape_decoder (void *xd MU_ARG_UNUSED,
+ enum mu_filter_command cmd,
+ struct mu_filter_io *iobuf)
+{
+ size_t i, j;
+ const unsigned char *iptr;
+ size_t isize;
+ char *optr;
+ size_t osize;
+
+ switch (cmd)
+ {
+ case mu_filter_init:
+ case mu_filter_done:
+ return mu_filter_ok;
+ default:
+ break;
+ }
+
+ iptr = (const unsigned char *) iobuf->input;
+ isize = iobuf->isize;
+ optr = iobuf->output;
+ osize = iobuf->osize;
+
+ for (i = j = 0; i < isize && j < osize; i++)
+ {
+ unsigned char c = *iptr++;
+ if (c == '\\')
+ {
+ int x;
+ if (i + 1 == isize)
+ break;
+ c = *iptr++;
+ i++;
+ x = mu_wordsplit_c_unquote_char (c);
+ optr[j++] = (x == -1) ? c : x;
+ }
+ else
+ optr[j++] = c;
+ }
+
+ iobuf->isize = i;
+ iobuf->osize = j;
+ return mu_filter_ok;
+}
+
+static struct _mu_filter_record _c_escape_filter = {
+ "C-escape",
+ NULL,
+ _c_escape_encoder,
+ _c_escape_decoder,
+};
+
+mu_filter_record_t mu_c_escape_filter = &_c_escape_filter;
+
diff --git a/libmailutils/filter/filter.c b/libmailutils/filter/filter.c
index 9cc904504..a9e6eeb47 100644
--- a/libmailutils/filter/filter.c
+++ b/libmailutils/filter/filter.c
@@ -83,6 +83,7 @@ mu_filter_get_list (mu_list_t *plist)
mu_list_append (filter_list, mu_linecon_filter);
mu_list_append (filter_list, mu_linelen_filter);
mu_list_append (filter_list, mu_iconv_filter);
+ mu_list_append (filter_list, mu_c_escape_filter);
/* FIXME: add the default encodings? */
}
*plist = filter_list;
diff --git a/mh/etc/components b/mh/etc/components
index 512352e9d..e754508a2 100644
--- a/mh/etc/components
+++ b/mh/etc/components
@@ -1,6 +1,6 @@
;; Default components file for GNU MH.
;; Lines beginning with ; are ignored. Rest of lines is copied verbatim.
-To:
-cc:
-Subject:
+To:
+cc:
+Subject:
--------

Return to:

Send suggestions and report system problems to the System administrator.