Commit c1d1ab07 c1d1ab07c72070d2ca92f729ab2454ad0b06f0ae by Sergey Poznyakoff

Bugfix.

* imap4d/append.c: Add a comment.
* imap4d/imap4d.h (imap4d_child_signal_setup): New proto.
* libmu_sieve/extensions/pipe.c (sieve_action_pipe): Use
mu_stream_copy, rewrite error handling.
* libmu_sieve/extensions/spamd.c (spamd_send_message): se
mu_stream_copy.
(spamd_test): Honor dry-run mode.
* libmu_sieve/extensions/vacation.c (build_mime): Remove
misleading FIXME. Use mu_stream_copy.
* libmu_sieve/extensions/moderator.c (moderator_message_get_part): Use
mu_body_get_streamref.
* examples/header.c (hstream): New global.
(cmd_load, cmd_free, cmd_remove, cmd_insert): Discard hstream.
(cmd_readline): Use hstream. Obtain it using mu_stream_readline.
* libproto/mbox/mbox.c (mbox_envelope_date): Remove trailing
newline from the obtained envelope line.
* mailbox/amd.c (amd_body_stream_seek): Allow for off == size
(imprtant for empty bodies).
1 parent 3ffda3e1
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
28 char *file; 28 char *file;
29 mu_header_t header; 29 mu_header_t header;
30 mu_iterator_t iterator; 30 mu_iterator_t iterator;
31 mu_stream_t hstream;
31 32
32 char *ps[] = { "> ", ". " }; 33 char *ps[] = { "> ", ". " };
33 int interactive; 34 int interactive;
...@@ -124,6 +125,7 @@ cmd_load (int argc, char **argv) ...@@ -124,6 +125,7 @@ cmd_load (int argc, char **argv)
124 { 125 {
125 if (check_args (argv[0], argc, 2, 2)) 126 if (check_args (argv[0], argc, 2, 2))
126 return; 127 return;
128 mu_stream_destroy (&hstream);
127 mu_header_destroy (&header); 129 mu_header_destroy (&header);
128 load_file (argv[1]); 130 load_file (argv[1]);
129 } 131 }
...@@ -134,6 +136,7 @@ cmd_free (int argc, char **argv) ...@@ -134,6 +136,7 @@ cmd_free (int argc, char **argv)
134 if (check_args (argv[0], argc, 1, 1)) 136 if (check_args (argv[0], argc, 1, 1))
135 return; 137 return;
136 mu_iterator_destroy (&iterator); 138 mu_iterator_destroy (&iterator);
139 mu_stream_destroy (&hstream);
137 mu_header_destroy (&header); 140 mu_header_destroy (&header);
138 } 141 }
139 142
...@@ -211,6 +214,7 @@ cmd_remove (int argc, char **argv) ...@@ -211,6 +214,7 @@ cmd_remove (int argc, char **argv)
211 status = mu_header_remove (header, fn, num); 214 status = mu_header_remove (header, fn, num);
212 if (status) 215 if (status)
213 mu_error ("%u: %s: %s", line_num, argv[0], mu_strerror (status)); 216 mu_error ("%u: %s: %s", line_num, argv[0], mu_strerror (status));
217 mu_stream_destroy (&hstream);
214 } 218 }
215 219
216 /* insert header value [ref [num] [before|after] [replace]] */ 220 /* insert header value [ref [num] [before|after] [replace]] */
...@@ -260,6 +264,7 @@ cmd_insert (int argc, char **argv) ...@@ -260,6 +264,7 @@ cmd_insert (int argc, char **argv)
260 } 264 }
261 status = mu_header_insert (header, argv[1], argv[2], 265 status = mu_header_insert (header, argv[1], argv[2],
262 ref, num, flags); 266 ref, num, flags);
267 mu_stream_destroy (&hstream);
263 if (status) 268 if (status)
264 mu_error ("%u: %s: %s", line_num, argv[0], mu_strerror (status)); 269 mu_error ("%u: %s: %s", line_num, argv[0], mu_strerror (status));
265 } 270 }
...@@ -289,6 +294,7 @@ cmd_write (int argc, char **argv) ...@@ -289,6 +294,7 @@ cmd_write (int argc, char **argv)
289 break; 294 break;
290 } 295 }
291 mu_stream_destroy (&str); 296 mu_stream_destroy (&str);
297 mu_stream_destroy (&hstream);
292 } 298 }
293 299
294 void 300 void
...@@ -341,18 +347,19 @@ void ...@@ -341,18 +347,19 @@ void
341 cmd_readline (int argc, char **argv) 347 cmd_readline (int argc, char **argv)
342 { 348 {
343 char *buf; 349 char *buf;
344 size_t size; 350 size_t size = 128;
345 mu_stream_t stream;
346 size_t nbytes; 351 size_t nbytes;
347 352
348 if (check_args (argv[0], argc, 1, 2)) 353 if (check_args (argv[0], argc, 1, 2))
349 return; 354 return;
355 if (argc == 2)
350 size = atoi (argv[1]); 356 size = atoi (argv[1]);
351 buf = malloc (size); 357 buf = malloc (size);
352 if (!buf) 358 if (!buf)
353 abort (); 359 abort ();
354 mu_header_get_stream (header, &stream); 360 if (!hstream)
355 mu_stream_readline (stream, buf, size, &nbytes); 361 mu_header_get_streamref (header, &hstream);
362 mu_stream_readline (hstream, buf, size, &nbytes);
356 printf ("\"%*.*s\"", (int) nbytes, (int) nbytes, buf); 363 printf ("\"%*.*s\"", (int) nbytes, (int) nbytes, buf);
357 free (buf); 364 free (buf);
358 } 365 }
......
...@@ -45,6 +45,7 @@ _append_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) ...@@ -45,6 +45,7 @@ _append_sender (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
45 return 0; 45 return 0;
46 } 46 }
47 47
48 /* FIXME: Why not use mu_message_size instead? */
48 static int 49 static int
49 _append_size (mu_message_t msg, size_t *psize) 50 _append_size (mu_message_t msg, size_t *psize)
50 { 51 {
......
...@@ -322,6 +322,7 @@ extern char *namespace_checkfullpath (const char *name, const char *pattern, ...@@ -322,6 +322,7 @@ extern char *namespace_checkfullpath (const char *name, const char *pattern,
322 const char *delim, int *pns); 322 const char *delim, int *pns);
323 int imap4d_session_setup (char *username); 323 int imap4d_session_setup (char *username);
324 int imap4d_session_setup0 (void); 324 int imap4d_session_setup0 (void);
325 void imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo));
325 326
326 /* Capability functions */ 327 /* Capability functions */
327 extern void imap4d_capability_add (const char *str); 328 extern void imap4d_capability_add (const char *str);
......
...@@ -213,7 +213,7 @@ moderator_message_get_part (mu_sieve_machine_t mach, ...@@ -213,7 +213,7 @@ moderator_message_get_part (mu_sieve_machine_t mach,
213 213
214 free (value); 214 free (value);
215 mu_message_get_body (tmp, &body); 215 mu_message_get_body (tmp, &body);
216 mu_body_get_stream (body, &str); 216 mu_body_get_streamref (body, &str);
217 217
218 rc = mu_stream_to_message (str, pmsg); 218 rc = mu_stream_to_message (str, pmsg);
219 if (rc) 219 if (rc)
...@@ -223,6 +223,7 @@ moderator_message_get_part (mu_sieve_machine_t mach, ...@@ -223,6 +223,7 @@ moderator_message_get_part (mu_sieve_machine_t mach,
223 mu_strerror (rc)); 223 mu_strerror (rc));
224 return 1; 224 return 1;
225 } 225 }
226 mu_stream_destroy (&str);
226 } 227 }
227 else if (value) 228 else if (value)
228 { 229 {
......
...@@ -41,38 +41,6 @@ ...@@ -41,38 +41,6 @@
41 #include <regex.h> 41 #include <regex.h>
42 #include <mailutils/sieve.h> 42 #include <mailutils/sieve.h>
43 43
44 #define ASSERT(expr, diag, ec) \
45 if (!(expr)) \
46 { \
47 if (ec) \
48 mu_sieve_error (mach, "%lu: %s: %s", \
49 (unsigned long) mu_sieve_get_message_num (mach), \
50 diag, \
51 mu_strerror (ec)); \
52 else \
53 mu_sieve_error (mach, "%lu: %s", \
54 (unsigned long) mu_sieve_get_message_num (mach), \
55 diag); \
56 mu_sieve_abort (mach); \
57 }
58
59 #define ASSERT2(expr, diag, arg, ec) \
60 if (!(expr)) \
61 { \
62 if (ec) \
63 mu_sieve_error (mach, "%lu: `%s': %s: %s", \
64 (unsigned long) mu_sieve_get_message_num (mach), \
65 arg, \
66 diag, \
67 mu_strerror (ec)); \
68 else \
69 mu_sieve_error (mach, "%lu: `%s': %s", \
70 (unsigned long) mu_sieve_get_message_num (mach), \
71 arg, \
72 diag); \
73 mu_sieve_abort (mach); \
74 }
75
76 int 44 int
77 sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) 45 sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
78 { 46 {
...@@ -81,12 +49,25 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -81,12 +49,25 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
81 mu_sieve_value_t *val; 49 mu_sieve_value_t *val;
82 char *cmd; 50 char *cmd;
83 mu_stream_t mstr, pstr; 51 mu_stream_t mstr, pstr;
84 char buf[512];
85 size_t n;
86 mu_envelope_t env; 52 mu_envelope_t env;
53 const char *error_diag = NULL;
54 const char *error_arg = NULL;
55 #define ONERR(rc, diag, arg) \
56 if (rc) \
57 { \
58 error_diag = diag; \
59 error_arg = arg; \
60 break; \
61 }
87 62
88 val = mu_sieve_value_get (args, 0); 63 val = mu_sieve_value_get (args, 0);
89 ASSERT (val, _("cannot get command!"), 0); 64 if (!val)
65 {
66 mu_sieve_error (mach, "%lu: %s",
67 (unsigned long) mu_sieve_get_message_num (mach),
68 _("cannot get command!"));
69 mu_sieve_abort (mach);
70 }
90 cmd = val->v.string; 71 cmd = val->v.string;
91 72
92 mu_sieve_log_action (mach, "PIPE", NULL); 73 mu_sieve_log_action (mach, "PIPE", NULL);
...@@ -105,47 +86,62 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -105,47 +86,62 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
105 msg = mu_sieve_get_message (mach); 86 msg = mu_sieve_get_message (mach);
106 mu_message_get_envelope (msg, &env); 87 mu_message_get_envelope (msg, &env);
107 88
108 rc = mu_message_get_stream (msg, &mstr); 89 do
109 ASSERT (rc == 0, _("cannot get message stream"), rc); 90 {
91 rc = mu_message_get_streamref (msg, &mstr);
92 ONERR (rc, _("cannot get message stream"), NULL);
110 93
111 rc = mu_prog_stream_create (&pstr, cmd, MU_STREAM_WRITE); 94 rc = mu_prog_stream_create (&pstr, cmd, MU_STREAM_WRITE);
112 ASSERT2 (rc == 0, _("cannot create command stream"), cmd, rc); 95 ONERR (rc, _("cannot create command stream"), cmd);
113 96
114 rc = mu_stream_open (pstr); 97 rc = mu_stream_open (pstr);
115 ASSERT2 (rc == 0, _("cannot open command stream"), cmd, rc); 98 ONERR (rc, _("cannot open command stream"), cmd);
116 99
117 if (mu_sieve_tag_lookup (tags, "envelope", &val)) 100 if (mu_sieve_tag_lookup (tags, "envelope", &val))
118 { 101 {
119 char *p; 102 char *p;
120 103
121 rc = mu_envelope_aget_sender (env, &p); 104 rc = mu_envelope_aget_sender (env, &p);
122 ASSERT (rc == 0, _("cannot get envelope sender"), rc); 105 ONERR (rc, _("cannot get envelope sender"), NULL);
123 rc = mu_stream_write (pstr, "From ", 5, NULL); 106 rc = mu_stream_write (pstr, "From ", 5, NULL);
124 ASSERT (rc == 0, _("stream write failed"), rc); 107 ONERR (rc, _("stream write failed"), NULL);
125 mu_stream_write (pstr, p, strlen (p), NULL); 108 mu_stream_write (pstr, p, strlen (p), NULL);
126 free (p); 109 free (p);
127 rc = mu_stream_write (pstr, " ", 1, NULL); 110 rc = mu_stream_write (pstr, " ", 1, NULL);
128 ASSERT (rc == 0, _("stream write failed"), rc); 111 ONERR (rc, _("stream write failed"), NULL);
129 rc = mu_envelope_aget_date (env, &p); 112 rc = mu_envelope_aget_date (env, &p);
130 ASSERT (rc == 0, _("cannot get envelope date"), rc); 113 ONERR (rc, _("cannot get envelope date"), NULL);
131 rc = mu_stream_write (pstr, p, strlen (p), NULL); 114 rc = mu_stream_write (pstr, p, strlen (p), NULL);
132 ASSERT (rc == 0, _("stream write failed"), rc); 115 ONERR (rc, _("stream write failed"), NULL);
133 free (p); 116 free (p);
134 rc = mu_stream_write (pstr, "\n", 1, NULL); 117 rc = mu_stream_write (pstr, "\n", 1, NULL);
135 ASSERT (rc == 0, _("stream write failed"), rc); 118 ONERR (rc, _("stream write failed"), NULL);
136 } 119 }
137 120
138 rc = mu_stream_seek (mstr, 0, SEEK_SET, NULL); 121 rc = mu_stream_copy (pstr, mstr, 0);
139 while (rc == 0 122 ONERR (rc, _("command failed"), cmd);
140 && mu_stream_read (mstr, buf, sizeof buf, &n) == 0 123 }
141 && n > 0) 124 while (0);
142 rc = mu_stream_write (pstr, buf, n, NULL);
143 125
126 mu_stream_destroy (&mstr);
144 mu_stream_close (pstr); 127 mu_stream_close (pstr);
145 mu_stream_destroy (&pstr); 128 mu_stream_destroy (&pstr);
146 129
147 130 if (rc)
148 ASSERT2 (rc == 0, _("command failed"), cmd, rc); 131 {
132 if (error_arg)
133 mu_sieve_error (mach, "%lu: %s: %s: %s",
134 (unsigned long) mu_sieve_get_message_num (mach),
135 error_diag,
136 error_arg,
137 mu_strerror (rc));
138 else
139 mu_sieve_error (mach, "%lu: %s: %s",
140 (unsigned long) mu_sieve_get_message_num (mach),
141 error_diag,
142 mu_strerror (rc));
143 mu_sieve_abort (mach);
144 }
149 145
150 return 0; 146 return 0;
151 } 147 }
...@@ -173,4 +169,3 @@ SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach) ...@@ -173,4 +169,3 @@ SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach)
173 return mu_sieve_register_action (mach, "pipe", sieve_action_pipe, 169 return mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
174 pipe_args, pipe_tag_groups, 1); 170 pipe_args, pipe_tag_groups, 1);
175 } 171 }
176
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
34 #include <mailutils/sieve.h> 34 #include <mailutils/sieve.h>
35 #include <mailutils/mu_auth.h> 35 #include <mailutils/mu_auth.h>
36 #include <mailutils/nls.h> 36 #include <mailutils/nls.h>
37 #include <mailutils/filter.h>
38 #include <mailutils/stream.h>
37 39
38 #define DEFAULT_SPAMD_PORT 783 40 #define DEFAULT_SPAMD_PORT 783
39 41
...@@ -98,29 +100,28 @@ spamd_send_command (mu_stream_t stream, const char *fmt, ...) ...@@ -98,29 +100,28 @@ spamd_send_command (mu_stream_t stream, const char *fmt, ...)
98 mu_stream_writeline (stream, buf, n); 100 mu_stream_writeline (stream, buf, n);
99 } 101 }
100 102
101 static void 103 static int
102 spamd_send_message (mu_stream_t stream, mu_message_t msg) 104 spamd_send_message (mu_stream_t stream, mu_message_t msg)
103 { 105 {
104 size_t size; 106 int rc;
105 char buf[512]; 107 mu_stream_t mstr, flt;
106 mu_stream_t mstr;
107
108 mu_message_get_stream (msg, &mstr);
109 mu_stream_seek (mstr, 0, SEEK_SET, NULL);
110 while (mu_stream_readline (mstr, buf, sizeof (buf), &size) == 0
111 && size > 0)
112 {
113 char *nl = NULL;
114 108
115 if (buf[size-1] == '\n') 109 rc = mu_message_get_streamref (msg, &mstr);
110 if (rc)
111 return rc;
112 rc = mu_filter_create (&flt, mstr, "rfc822", MU_FILTER_ENCODE,
113 MU_STREAM_READ|MU_STREAM_SEEK|MU_STREAM_NO_CLOSE);
114 if (rc)
116 { 115 {
117 size--; 116 mu_stream_destroy (&mstr);
118 nl = "\r\n"; 117 return rc;
119 }
120 mu_stream_write (stream, buf, size, NULL);
121 if (nl)
122 mu_stream_write (stream, nl, 2, NULL);
123 } 118 }
119
120 rc = mu_stream_copy (stream, flt, 0);
121
122 mu_stream_destroy (&mstr);
123 mu_stream_destroy (&flt);
124 return rc;
124 } 125 }
125 126
126 static size_t 127 static size_t
...@@ -284,6 +285,9 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -284,6 +285,9 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
284 (u_long) mu_sieve_get_message_num (mach)); 285 (u_long) mu_sieve_get_message_num (mach));
285 } 286 }
286 287
288 if (mu_sieve_is_dry_run (mach))
289 return 0;
290
287 if (mu_sieve_tag_lookup (tags, "host", &arg)) 291 if (mu_sieve_tag_lookup (tags, "host", &arg))
288 host = arg->v.string; 292 host = arg->v.string;
289 else 293 else
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
42 42
43 /* Build a mime response message from original message MSG. TEXT 43 /* Build a mime response message from original message MSG. TEXT
44 is the message text. 44 is the message text.
45 FIXME: This is for future use, when I add :mime tag
46 */ 45 */
47 static int 46 static int
48 build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime, 47 build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
...@@ -50,25 +49,25 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime, ...@@ -50,25 +49,25 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
50 { 49 {
51 mu_mime_t mime = NULL; 50 mu_mime_t mime = NULL;
52 mu_message_t newmsg; 51 mu_message_t newmsg;
53 mu_stream_t stream, input, save_input = NULL; 52 mu_stream_t stream, input;
54 mu_header_t hdr; 53 mu_header_t hdr;
55 mu_body_t body; 54 mu_body_t body;
56 char buf[512]; 55 const char *header =
57 char *header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" 56 "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n"
58 "Content-Transfer-Encoding: 8bit\n\n"; 57 "Content-Transfer-Encoding: 8bit\n\n";
59 int rc; 58 int rc;
60 size_t n;
61 59
62 mu_mime_create (&mime, NULL, 0); 60 mu_mime_create (&mime, NULL, 0);
63 mu_message_create (&newmsg, NULL); 61 mu_message_create (&newmsg, NULL);
64 mu_message_get_body (newmsg, &body); 62 mu_message_get_body (newmsg, &body);
65 mu_body_get_stream (body, &stream);
66 63
67 if ((rc = mu_memory_stream_create (&input, MU_STREAM_RDWR))) 64 if ((rc = mu_memory_stream_create (&input, MU_STREAM_RDWR)))
68 { 65 {
69 mu_sieve_error (mach, 66 mu_sieve_error (mach,
70 _("cannot create temporary stream: %s"), 67 _("cannot create temporary stream: %s"),
71 mu_strerror (rc)); 68 mu_strerror (rc));
69 mu_mime_destroy (&mime);
70 mu_message_destroy (&newmsg, NULL);
72 return 1; 71 return 1;
73 } 72 }
74 73
...@@ -77,6 +76,9 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime, ...@@ -77,6 +76,9 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
77 mu_sieve_error (mach, 76 mu_sieve_error (mach,
78 _("cannot open temporary stream: %s"), 77 _("cannot open temporary stream: %s"),
79 mu_strerror (rc)); 78 mu_strerror (rc));
79 mu_mime_destroy (&mime);
80 mu_message_destroy (&newmsg, NULL);
81 mu_stream_destroy (&input);
80 return 1; 82 return 1;
81 } 83 }
82 84
...@@ -91,19 +93,37 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime, ...@@ -91,19 +93,37 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
91 { 93 {
92 header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n" 94 header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n"
93 "Content-Transfer-Encoding: base64\n\n"; 95 "Content-Transfer-Encoding: base64\n\n";
94 save_input = input;
95 input = fstr; 96 input = fstr;
96 } 97 }
97 } 98 }
98 99
99 while (rc == 0 100 rc = mu_body_get_streamref (body, &stream);
100 && mu_stream_read (input, buf, sizeof buf, &n) == 0 101 if (rc)
101 && n > 0) 102 {
102 rc = mu_stream_write (stream, buf, n, NULL); 103 mu_sieve_error (mach,
104 _("cannot get input body stream: %s"),
105 mu_strerror (rc));
106 mu_mime_destroy (&mime);
107 mu_message_destroy (&newmsg, NULL);
108 mu_stream_destroy (&input);
109 return 1;
110 }
111
112 mu_stream_seek (input, 0, MU_SEEK_SET, NULL);
113 rc = mu_stream_copy (stream, input, 0);
114 if (rc)
115 {
116 mu_sieve_error (mach,
117 _("stream copy failed: %s"),
118 mu_strerror (rc));
119 mu_mime_destroy (&mime);
120 mu_message_destroy (&newmsg, NULL);
121 mu_stream_destroy (&input);
122 mu_stream_destroy (&stream);
123 return 1;
124 }
103 125
104 mu_stream_destroy (&input); 126 mu_stream_destroy (&input);
105 if (save_input)
106 mu_stream_destroy (&save_input);
107 127
108 mu_header_create (&hdr, header, strlen (header)); 128 mu_header_create (&hdr, header, strlen (header));
109 mu_message_set_header (newmsg, hdr, NULL); 129 mu_message_set_header (newmsg, hdr, NULL);
......
...@@ -382,6 +382,7 @@ mbox_envelope_date (mu_envelope_t envelope, char *buf, size_t len, ...@@ -382,6 +382,7 @@ mbox_envelope_date (mu_envelope_t envelope, char *buf, size_t len,
382 &n); 382 &n);
383 if (status) 383 if (status)
384 return status; 384 return status;
385 mu_rtrim_cset (buffer, "\r\n");
385 386
386 /* Format: "From [sender] [date]" */ 387 /* Format: "From [sender] [date]" */
387 /* strlen ("From ") == 5 */ 388 /* strlen ("From ") == 5 */
......
...@@ -1710,7 +1710,7 @@ amd_body_stream_seek (mu_stream_t str, mu_off_t off, mu_off_t *presult) ...@@ -1710,7 +1710,7 @@ amd_body_stream_seek (mu_stream_t str, mu_off_t off, mu_off_t *presult)
1710 1710
1711 amd_body_size (amdstr->body, &size); 1711 amd_body_size (amdstr->body, &size);
1712 1712
1713 if (off < 0 || off >= size) 1713 if (off < 0 || off > size)
1714 return ESPIPE; 1714 return ESPIPE;
1715 1715
1716 amdstr->off = off; 1716 amdstr->off = off;
......