summaryrefslogtreecommitdiff
path: root/libmailutils
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-11-23 13:11:29 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-11-23 13:20:58 +0200
commit9763fd4a43128bcd08de8e88cce4142473d38d06 (patch)
treec4d298e58eb19dd46cc2a11652013827ef9c264d /libmailutils
parentae91979e9664d99204beb116b9b5e4122e43938e (diff)
downloadmailutils-9763fd4a43128bcd08de8e88cce4142473d38d06.tar.gz
mailutils-9763fd4a43128bcd08de8e88cce4142473d38d06.tar.bz2
Implement mboxrb format (a replacement for the mbox used currently)
* configure.ac: New format: mboxrb * include/mailutils/filter.h (mu_fromrb_filter): New extern. * include/mailutils/registrar.h (mu_mboxrb_record): New extern. (mu_register_all_mbox_formats) (mu_register_local_mbox_formats): Add mu_mboxrb_record. * libmailutils/filter/filter.c (mu_filter_get_list): Add mu_fromrb_filter * libproto/Makefile.am [MU_COND_SUPPORT_MBOXRB]: Add mboxrb * bootstrap.conf: Remove special handling for testsuite/maildir (fixes 1d846d2d92). * testsuite/mbop.c: Implement the -r (--read-only) option. * include/mailutils/sys/Makefile.am: Add mboxrb.h * include/mailutils/sys/mboxrb.h: New file. * libmailutils/filter/Makefile.am (libfilter_la_SOURCES): Add fromrb.c * libmailutils/filter/fromrb.c: New file. * libmailutils/tests/Makefile.am: New file. * libmailutils/tests/fromrb.at: New file. * libmailutils/tests/testsuite.at: New file. * libproto/mboxrb/Makefile.am: New file. * libproto/mboxrb/mboxrb.c: New file. * libproto/mboxrb/message.c: New file. * libproto/mboxrb/tests/.gitignore: New file. * libproto/mboxrb/tests/Makefile.am: New file. * libproto/mboxrb/tests/atlocal.in: New file. * libproto/mboxrb/tests/attr.at: New file. * libproto/mboxrb/tests/autodetect.at: New file. * libproto/mboxrb/tests/body.at: New file. * libproto/mboxrb/tests/count.at: New file. * libproto/mboxrb/tests/env.at: New file. * libproto/mboxrb/tests/header.at: New file. * libproto/mboxrb/tests/testsuite.at: New file.
Diffstat (limited to 'libmailutils')
-rw-r--r--libmailutils/filter/Makefile.am1
-rw-r--r--libmailutils/filter/filter.c2
-rw-r--r--libmailutils/filter/fromrb.c282
-rw-r--r--libmailutils/tests/Makefile.am1
-rw-r--r--libmailutils/tests/fromrb.at56
-rw-r--r--libmailutils/tests/testsuite.at1
6 files changed, 343 insertions, 0 deletions
diff --git a/libmailutils/filter/Makefile.am b/libmailutils/filter/Makefile.am
index 5a27dec15..353237b13 100644
--- a/libmailutils/filter/Makefile.am
+++ b/libmailutils/filter/Makefile.am
@@ -29,6 +29,7 @@ libfilter_la_SOURCES =\
filter.c\
fltchain.c\
fromflt.c\
+ fromrb.c\
header.c\
htmlent.c\
iconvflt.c\
diff --git a/libmailutils/filter/filter.c b/libmailutils/filter/filter.c
index e8d0b5ce7..381236b1e 100644
--- a/libmailutils/filter/filter.c
+++ b/libmailutils/filter/filter.c
@@ -87,6 +87,8 @@ mu_filter_get_list (mu_list_t *plist)
mu_list_append (filter_list, mu_xml_filter);
mu_list_append (filter_list, mu_percent_filter);
mu_list_append (filter_list, mu_dq_filter);
+ mu_list_append (filter_list, mu_fromrb_filter);
+
/* FIXME: add the default encodings? */
}
*plist = filter_list;
diff --git a/libmailutils/filter/fromrb.c b/libmailutils/filter/fromrb.c
new file mode 100644
index 000000000..40c1cae95
--- /dev/null
+++ b/libmailutils/filter/fromrb.c
@@ -0,0 +1,282 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/errno.h>
+#include <mailutils/filter.h>
+#include <mailutils/stream.h>
+
+enum
+ {
+ S_INIT, /* Initial state */
+ S_BOL, /* Beginning of line */
+ S_ESC, /* Collecting > escapes */
+ S_FROM, /* Collecting "From " characters */
+ };
+
+struct transcoder
+{
+ int state; /* Transcoder state */
+ int count; /* Number of consecutive '>' seen. */
+ int len; /* Number of "From" charactes collected */
+};
+
+static char from_line[] = "From ";
+
+/* Move min(isize,osize) bytes from iptr to optr, removing initial '>'
+ from each sequence '>+From ' at the beginning of line */
+static enum mu_filter_result
+_fromrb_decoder (void *xd,
+ enum mu_filter_command cmd,
+ struct mu_filter_io *iobuf)
+{
+ const unsigned char *iptr;
+ size_t isize;
+ char *optr;
+ size_t osize;
+ struct transcoder *xcode = xd;
+ size_t i, j, k;
+ size_t len, reqlen;
+
+ switch (cmd)
+ {
+ case mu_filter_init:
+ xcode->state = S_BOL;
+ xcode->count = 0;
+ xcode->len = 0;
+ return mu_filter_ok;
+
+ 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++;
+
+ switch (xcode->state)
+ {
+ case S_INIT:
+ optr[j++] = c;
+ if (c == '\n')
+ xcode->state = S_BOL;
+ break;
+
+ case S_BOL:
+ if (c == '>')
+ {
+ xcode->state = S_ESC;
+ xcode->count = 1;
+ }
+ else
+ {
+ optr[j++] = c;
+ xcode->state = S_INIT;
+ }
+ break;
+
+ case S_ESC:
+ if (c == '>')
+ {
+ xcode->count++;
+ }
+ else if (c == from_line[0])
+ {
+ xcode->state = S_FROM;
+ xcode->len = 1;
+ }
+ else
+ {
+ xcode->state = S_INIT;
+ goto emit;
+ }
+ break;
+
+ case S_FROM:
+ if (from_line[xcode->len] == 0)
+ {
+ xcode->count--;
+ }
+ else if (c == from_line[xcode->len])
+ {
+ xcode->len++;
+ continue;
+ }
+ else
+ {
+ //RESTORE
+ }
+ emit:
+ reqlen = xcode->len + xcode->count;
+ len = osize - j;
+ if (len < reqlen)
+ {
+ iobuf->osize = reqlen;
+ return mu_filter_moreoutput;
+ }
+ for (k = 0; k < xcode->count; k++, j++)
+ optr[j] = '>';
+ memcpy (optr + j, from_line, xcode->len);
+ j += xcode->len;
+
+ xcode->state = S_INIT;
+ xcode->count = xcode->len = 0;
+ i--;
+ iptr--;
+ }
+ }
+ iobuf->isize = i;
+ iobuf->osize = j;
+ return mu_filter_ok;
+}
+
+static enum mu_filter_result
+_fromrb_encoder (void *xd,
+ enum mu_filter_command cmd,
+ struct mu_filter_io *iobuf)
+{
+ const unsigned char *iptr;
+ size_t isize;
+ char *optr;
+ size_t osize;
+ struct transcoder *xcode = xd;
+ size_t i, j, k;
+ size_t len, reqlen;
+
+ switch (cmd)
+ {
+ case mu_filter_init:
+ xcode->state = S_BOL;
+ xcode->count = 0;
+ xcode->len = 0;
+ return mu_filter_ok;
+
+ 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++;
+
+ switch (xcode->state)
+ {
+ case S_INIT:
+ optr[j++] = c;
+ if (c == '\n')
+ xcode->state = S_BOL;
+ break;
+
+ case S_BOL:
+ if (c == '>')
+ {
+ xcode->state = S_ESC;
+ xcode->count = 1;
+ }
+ else if (c == from_line[0])
+ {
+ xcode->state = S_FROM;
+ xcode->count = 0;
+ xcode->len = 1;
+ }
+ else
+ {
+ optr[j++] = c;
+ xcode->state = S_INIT;
+ }
+ break;
+
+ case S_ESC:
+ if (c == '>')
+ {
+ xcode->count++;
+ }
+ else if (c == from_line[0])
+ {
+ xcode->state = S_FROM;
+ xcode->len = 1;
+ }
+ else
+ {
+ xcode->state = S_INIT;
+ goto emit;
+ }
+ break;
+
+ case S_FROM:
+ if (from_line[xcode->len] == 0)
+ {
+ xcode->count++;
+ }
+ else if (c == from_line[xcode->len])
+ {
+ xcode->len++;
+ continue;
+ }
+ else
+ {
+ //RESTORE
+ }
+ emit:
+ reqlen = xcode->len + xcode->count;
+ len = osize - j;
+ if (len < reqlen)
+ {
+ iobuf->osize = reqlen;
+ return mu_filter_moreoutput;
+ }
+ for (k = 0; k < xcode->count; k++, j++)
+ optr[j] = '>';
+ memcpy (optr + j, from_line, xcode->len);
+ j += xcode->len;
+
+ xcode->state = S_INIT;
+ xcode->count = xcode->len = 0;
+ i--;
+ iptr--;
+ }
+ }
+ iobuf->isize = i;
+ iobuf->osize = j;
+ return mu_filter_ok;
+}
+
+
+static int
+_fromrb_alloc_state (void **pret, int mode,
+ int argc MU_ARG_UNUSED, const char **argv MU_ARG_UNUSED)
+{
+ *pret = malloc (sizeof (struct transcoder));
+ if (!*pret)
+ return ENOMEM;
+ return 0;
+}
+
+static struct _mu_filter_record _fromrb_filter = {
+ "FROMRB",
+ _fromrb_alloc_state,
+ _fromrb_encoder,
+ _fromrb_decoder
+};
+
+mu_filter_record_t mu_fromrb_filter = &_fromrb_filter;
+
+
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 19aa995e6..6b5ea8bd5 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -103,6 +103,7 @@ TESTSUITE_AT += \
encode2047.at\
exp.at\
fromflt.at\
+ fromrb.at\
fsaf.at\
fsaftomod.at\
fsfolder00.at\
diff --git a/libmailutils/tests/fromrb.at b/libmailutils/tests/fromrb.at
new file mode 100644
index 000000000..022927bf2
--- /dev/null
+++ b/libmailutils/tests/fromrb.at
@@ -0,0 +1,56 @@
+AT_SETUP([FROMRB filter])
+AT_DATA([enc],
+[From me
+Fromme
+ From me
+Fram me
+From
+> From me
+>> From me
+> >From me
+>From me
+>>From me
+])
+AT_CHECK([fltst FROMRB encode read < enc],
+[0],
+[>From me
+Fromme
+ From me
+Fram me
+From
+> From me
+>> From me
+> >From me
+>>From me
+>>>From me
+])
+
+AT_DATA([dec],
+[From me
+>From me
+>>From me
+>>Fromme
+> From me
+>> From me
+> >From me
+>From
+>FroM X
+>FrOm X
+>FRom X
+])
+AT_CHECK([fltst FROMRB decode read < dec],
+[0],
+[From me
+From me
+>From me
+>>Fromme
+> From me
+>> From me
+> >From me
+>From
+>FroM X
+>FrOm X
+>FRom X
+])
+
+AT_CLEANUP
diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at
index 6888f39e6..b78a61767 100644
--- a/libmailutils/tests/testsuite.at
+++ b/libmailutils/tests/testsuite.at
@@ -220,6 +220,7 @@ m4_include([encode2047.at])
AT_BANNER(Filters)
m4_include([fromflt.at])
+m4_include([fromrb.at])
m4_include([inline-comment.at])
m4_include([hdrflt.at])
m4_include([hdrcpy.at])

Return to:

Send suggestions and report system problems to the System administrator.