summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-03-03 00:25:24 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-03-03 00:25:24 +0200
commit9db13766d47f640b5b0d57ba9c3392bdc382971e (patch)
tree842e3877ac1e005cfde7ea241d43e7be892a3770
parentbc61f890ce68761d7b713508cdb97cb08f058aa3 (diff)
downloadmailutils-9db13766d47f640b5b0d57ba9c3392bdc382971e.tar.gz
mailutils-9db13766d47f640b5b0d57ba9c3392bdc382971e.tar.bz2
Implement automatic dot-unstuffing in dotmail mailboxes
* include/mailutils/sys/dotmail.h (mu_dotmail_message): New members: body_size and body_dot_stuffed. * libproto/dotmail/dotmail.c (dotmail_rescan_unlocked): Count dot-unstuffed octets in the body. Set dmsg->body_dot_stuffed to 1 if at least one byte was dot-stuffed. * libproto/dotmail/message.c (dotmail_body_size): Return unstuffed size. (_msg_body_setup): If the body was dot-stuffed, return rdcache stream built over the "DOT" decoder. * libproto/dotmail/tests/body.at: Check dot-unstuffing.
-rw-r--r--include/mailutils/sys/dotmail.h2
-rw-r--r--libproto/dotmail/dotmail.c13
-rw-r--r--libproto/dotmail/message.c41
-rw-r--r--libproto/dotmail/tests/body.at40
4 files changed, 84 insertions, 12 deletions
diff --git a/include/mailutils/sys/dotmail.h b/include/mailutils/sys/dotmail.h
index 05795ab8a..7fa65795c 100644
--- a/include/mailutils/sys/dotmail.h
+++ b/include/mailutils/sys/dotmail.h
@@ -34,9 +34,11 @@ struct mu_dotmail_message
mu_off_t body_start; /* Start of body */
mu_off_t message_end; /* End of message */
/* Additional info */
+ size_t body_size; /* Number of octets in unstuffed message body */
size_t body_lines; /* Number of lines in message body */
unsigned long uid; /* IMAP-style uid. */
char *hdr[MU_DOTMAIL_HDR_MAX]; /* Pre-scanned headers */
+ unsigned body_dot_stuffed:1; /* True if body is dot-stuffed */
unsigned headers_scanned:1; /* True if hdr is filled */
unsigned attr_scanned:1; /* True if attr_flags is initialized */
unsigned body_lines_scanned:1; /* True if body_lines is initialized */
diff --git a/libproto/dotmail/dotmail.c b/libproto/dotmail/dotmail.c
index 223dcf442..8e2898530 100644
--- a/libproto/dotmail/dotmail.c
+++ b/libproto/dotmail/dotmail.c
@@ -355,13 +355,14 @@ dotmail_rescan_unlocked (mu_mailbox_t mailbox, mu_off_t offset)
mu_strerror (rc)));
return rc;
}
- state = dotmail_scan_body;
+ state = dotmail_scan_body_newline;
}
else
state = dotmail_scan_header;
break;
case dotmail_scan_body:
+ dmsg->body_size++;
if (cur == '\n')
{
dmsg->body_lines++;
@@ -370,6 +371,7 @@ dotmail_rescan_unlocked (mu_mailbox_t mailbox, mu_off_t offset)
break;
case dotmail_scan_body_newline:
+ dmsg->body_size++;
if (cur == '.')
state = dotmail_scan_dot;
else if (cur == '\n')
@@ -395,6 +397,7 @@ dotmail_rescan_unlocked (mu_mailbox_t mailbox, mu_off_t offset)
return rc;
}
dmsg->message_end -= 2;
+ dmsg->body_size--;
/* Every 100 mesgs update the lock, it should be every minute. */
if (mailbox->locker && (dmp->mesg_count % 100) == 0)
@@ -406,7 +409,13 @@ dotmail_rescan_unlocked (mu_mailbox_t mailbox, mu_off_t offset)
state = dotmail_scan_init;
}
else
- state = dotmail_scan_body;
+ {
+ if (cur == '.')
+ dmsg->body_dot_stuffed = 1;
+ else
+ dmsg->body_size++;
+ state = dotmail_scan_body;
+ }
break;
}
}
diff --git a/libproto/dotmail/message.c b/libproto/dotmail/message.c
index 651ca0bd3..76c1a97b1 100644
--- a/libproto/dotmail/message.c
+++ b/libproto/dotmail/message.c
@@ -211,7 +211,7 @@ dotmail_body_size (mu_body_t body, size_t *psize)
if (!dmsg)
return EINVAL;
if (psize)
- *psize = dmsg->message_end - dmsg->body_start;
+ *psize = dmsg->body_size;
return 0;
}
@@ -252,19 +252,40 @@ static int
_msg_body_setup (mu_message_t msg, struct mu_dotmail_message *dmsg)
{
mu_body_t body;
- mu_stream_t stream;
+ mu_stream_t stream, flt;
int rc;
- rc = mu_body_create (&body, msg);
+ if (dmsg->body_dot_stuffed)
+ {
+ rc = mu_streamref_create_abridged (&stream,
+ dmsg->mbox->mailbox->stream,
+ dmsg->body_start,
+ dmsg->message_end + 1);
+ if (rc)
+ return rc;
+
+ rc = mu_filter_create (&flt, stream, "DOT",
+ MU_FILTER_DECODE, MU_STREAM_READ);
+ mu_stream_unref (stream);
+ if (rc)
+ return rc;
+
+ rc = mu_rdcache_stream_create (&stream, flt,
+ MU_STREAM_READ|MU_STREAM_SEEK);
+ mu_stream_unref (flt);
+ }
+ else
+ {
+ rc = mu_streamref_create_abridged (&stream,
+ dmsg->mbox->mailbox->stream,
+ dmsg->body_start,
+ dmsg->message_end - 1);
+ }
if (rc)
return rc;
- rc = mu_streamref_create_abridged (&stream,
- dmsg->mbox->mailbox->stream,
- dmsg->body_start,
- dmsg->message_end - 1);
- if (rc)
- mu_body_destroy (&body, msg);
- else
+
+ rc = mu_body_create (&body, msg);
+ if (rc == 0)
{
mu_body_set_stream (body, stream, msg);
mu_body_set_size (body, dotmail_body_size, msg);
diff --git a/libproto/dotmail/tests/body.at b/libproto/dotmail/tests/body.at
index cb16cac02..9f3c43c1c 100644
--- a/libproto/dotmail/tests/body.at
+++ b/libproto/dotmail/tests/body.at
@@ -42,19 +42,59 @@ Not the same thing a bit! You might just
as well say that "I see what I eat" is the same thing as "I eat
what I see"!
.
+Received: (from hare@wonder.land)
+ by wonder.land id 3316
+ for alice@wonder.land; Mon, 29 Jul 2002 22:00:21 +0100
+Date: Mon, 29 Jul 2002 22:00:16 +0100
+From: March Hare <hare@wonder.land>
+Message-Id: <200207292200.3316@wonder.land>
+To: Alice <alice@wonder.land>
+Subject: Re: Be specific
+Return-Path: hare@wonder.land
+
+..
+...
+....
+.....
+......
+.......
+.
],
[],[],
[1
body_lines
body_size
+body_text
2
body_lines
body_size
+body_text
+3
+body_lines
+body_size
+body_text
],
[1 current message
1 body_lines: 2
1 body_size: 77
+1 body_text: I do, at least--at least I mean what
+I say--that's the same thing, you know.
+
2 current message
2 body_lines: 3
2 body_size: 118
+2 body_text: Not the same thing a bit! You might just
+as well say that "I see what I eat" is the same thing as "I eat
+what I see"!
+
+3 current message
+3 body_lines: 6
+3 body_size: 27
+3 body_text: .
+..
+...
+....
+.....
+......
+
])

Return to:

Send suggestions and report system problems to the System administrator.