summaryrefslogtreecommitdiff
path: root/libmailutils/filter/dq.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmailutils/filter/dq.c')
-rw-r--r--libmailutils/filter/dq.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/libmailutils/filter/dq.c b/libmailutils/filter/dq.c
new file mode 100644
index 000000000..d3bb18523
--- /dev/null
+++ b/libmailutils/filter/dq.c
@@ -0,0 +1,143 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2011-2012, 2014-2017 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/>. */
+
+/* Doble-quote escaping filter.
+ In encode mode, escapes each occurrence of double-quote and backslash
+ by prefixing it with backslash.
+ In decode mode, removes backslash prefixes.
+*/
+
+#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
+_dq_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 (strchr ("\\\"", c))
+ {
+ if (j + 1 == osize)
+ {
+ if (i == 0)
+ {
+ iobuf->osize = 2;
+ return mu_filter_moreoutput;
+ }
+ break;
+ }
+ else
+ {
+ optr[j++] = '\\';
+ optr[j++] = c;
+ }
+ }
+ 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
+_dq_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 == '\\')
+ {
+ if (i + 1 == isize)
+ break;
+ optr[j++] = *iptr++;
+ }
+ else
+ optr[j++] = c;
+ }
+
+ iobuf->isize = i;
+ iobuf->osize = j;
+ return mu_filter_ok;
+}
+
+static struct _mu_filter_record _dq_filter = {
+ "dq",
+ NULL,
+ _dq_encoder,
+ _dq_decoder,
+};
+
+mu_filter_record_t mu_dq_filter = &_dq_filter;
+

Return to:

Send suggestions and report system problems to the System administrator.