summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 13:57:06 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 14:02:01 +0300
commit7262235cbe6dc9426ad6e37c5fe0f4b023b324a9 (patch)
treeab7c7984e16f8d6d201d94e537489b93a7770ef9
parent62db89e3dca29f9b931c62b25014955a4ede36c0 (diff)
downloadmailutils-7262235cbe6dc9426ad6e37c5fe0f4b023b324a9.tar.gz
mailutils-7262235cbe6dc9426ad6e37c5fe0f4b023b324a9.tar.bz2
Improve CRLF filter.
* include/mailutils/filter.h (mu_filter_new_data_t): Change prototype. * mailbox/filter.c (mu_filter_create): Reflect the above. * mailbox/crlfflt.c (crlf_state): New enum. (_crlf_encoder): Keep state info in xd. Do not modify eventual input CRLFs. (alloc_state): New function. (_rfc822_filter,_crlf_filter): Provide the `newdata' method.
-rw-r--r--include/mailutils/filter.h2
-rw-r--r--mailbox/crlfflt.c60
-rw-r--r--mailbox/filter.c6
3 files changed, 54 insertions, 14 deletions
diff --git a/include/mailutils/filter.h b/include/mailutils/filter.h
index 01a80cd0a..03c43c2b0 100644
--- a/include/mailutils/filter.h
+++ b/include/mailutils/filter.h
@@ -60,7 +60,7 @@ enum mu_filter_result
mu_filter_moreoutput,
};
-typedef void *(*mu_filter_new_data_t) (void *);
+typedef int (*mu_filter_new_data_t) (void **, int, void *);
typedef enum mu_filter_result (*mu_filter_xcode_t) (void *data,
enum mu_filter_command cmd,
struct mu_filter_io *iobuf);
diff --git a/mailbox/crlfflt.c b/mailbox/crlfflt.c
index 3e9bab0e6..9dc147c9e 100644
--- a/mailbox/crlfflt.c
+++ b/mailbox/crlfflt.c
@@ -22,11 +22,16 @@
#include <mailutils/errno.h>
#include <mailutils/filter.h>
+enum crlf_state
+{
+ state_init,
+ state_cr
+};
+
/* Move min(isize,osize) bytes from iptr to optr, replacing each \n
- with \r\n. Store number of bytes written to optr in *pnbytes.
- Return number of bytes read from iptr. */
+ with \r\n. Any input \r\n sequences remain untouched. */
static enum mu_filter_result
-_crlf_encoder (void *xd MU_ARG_UNUSED,
+_crlf_encoder (void *xd,
enum mu_filter_command cmd,
struct mu_filter_io *iobuf)
{
@@ -35,10 +40,12 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
size_t isize;
char *optr;
size_t osize;
-
+ enum crlf_state *state = xd;
+
switch (cmd)
{
case mu_filter_init:
+ *state = state_init;
case mu_filter_done:
return mu_filter_ok;
default:
@@ -55,7 +62,12 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
unsigned char c = *iptr++;
if (c == '\n')
{
- if (j + 1 == osize)
+ if (*state == state_cr)
+ {
+ *state = state_init;
+ optr[j++] = c;
+ }
+ else if (j + 1 == osize)
{
if (i == 0)
{
@@ -64,10 +76,17 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
}
break;
}
- optr[j++] = '\r';
- optr[j++] = '\n';
+ else
+ {
+ optr[j++] = '\r';
+ optr[j++] = '\n';
+ }
+ }
+ else if (c == '\r')
+ {
+ *state = state_cr;
+ optr[j++] = c;
}
- /*else if (c == '\r')*/
else
optr[j++] = c;
}
@@ -77,8 +96,7 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
}
/* Move min(isize,osize) bytes from iptr to optr, replacing each \r\n
- with \n. Store number of bytes written to optr in *pnbytes.
- Return number of bytes read from iptr. */
+ with \n. */
static enum mu_filter_result
_crlf_decoder (void *xd MU_ARG_UNUSED,
enum mu_filter_command cmd,
@@ -121,10 +139,28 @@ _crlf_decoder (void *xd MU_ARG_UNUSED,
return mu_filter_ok;
}
+static int
+alloc_state (void **pret, int mode, void *data MU_ARG_UNUSED)
+{
+ switch (mode)
+ {
+ case MU_FILTER_ENCODE:
+ *pret = malloc (sizeof (int));
+ if (!*pret)
+ return ENOMEM;
+ break;
+
+ case MU_FILTER_DECODE:
+ *pret = NULL;
+ }
+ return 0;
+}
+
+
static struct _mu_filter_record _crlf_filter = {
"CRLF",
0,
- NULL,
+ alloc_state,
_crlf_encoder,
_crlf_decoder
};
@@ -136,7 +172,7 @@ mu_filter_record_t mu_crlf_filter = &_crlf_filter;
static struct _mu_filter_record _rfc822_filter = {
"RFC822",
0,
- NULL,
+ alloc_state,
_crlf_encoder,
_crlf_decoder
};
diff --git a/mailbox/filter.c b/mailbox/filter.c
index ddefb9598..3a12b5694 100644
--- a/mailbox/filter.c
+++ b/mailbox/filter.c
@@ -169,7 +169,11 @@ mu_filter_create (mu_stream_t *pstream, mu_stream_t stream, const char *name,
return status;
if (frec->newdata)
- xdata = frec->newdata (NULL);
+ {
+ status = frec->newdata (&xdata, mode, NULL);
+ if (status)
+ return status;
+ }
status = ((flags & MU_STREAM_WRITE) ? filter_create_wr : filter_create_rd)
(pstream, stream,

Return to:

Send suggestions and report system problems to the System administrator.