diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-03-03 00:25:24 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-03-03 00:25:24 +0200 |
commit | 9db13766d47f640b5b0d57ba9c3392bdc382971e (patch) | |
tree | 842e3877ac1e005cfde7ea241d43e7be892a3770 | |
parent | bc61f890ce68761d7b713508cdb97cb08f058aa3 (diff) | |
download | mailutils-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.h | 2 | ||||
-rw-r--r-- | libproto/dotmail/dotmail.c | 13 | ||||
-rw-r--r-- | libproto/dotmail/message.c | 41 | ||||
-rw-r--r-- | libproto/dotmail/tests/body.at | 40 |
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: . +.. +... +.... +..... +...... + ]) |