Fixes in stream subsystem. Rewrite and optimize maidag lmtp mode using streams.
* libmailutils/file_stream.c (mu_fd_stream_create): Mark stream as open, do not call mu_stream_open explicitly. * libmailutils/message_stream.c (mu_stream_to_message): Bugfixes, wrong owner given to mu_envelope_set_ calls. * libmailutils/stream.c (_MU_STR_FLUSH_ALL) (_MU_STR_FLUSH_KEEP): New macros for _stream_flush_buffer. (_stream_flush_buffer): Change the meaning of the last argument. All callers updated. (mu_stream_seek): Fix operation with MU_SEEK_END. Call _mu_stream_cleareof on success. (mu_stream_read): Call _stream_flush_buffer in buffered mode. (mu_stream_getdelim, mu_stream_readdelim): Call _stream_flush_buffer. * libmailutils/streamcpy.c (mu_stream_copy): Reset size if mu_stream_seek fails. * libmailutils/temp_file_stream.c (mu_temp_file_stream_create): Set full buffering mode by default. * maidag/mailtmp.c: Remove. * maidag/Makefile.am (maidag_SOURCES): Remove mailtmp.c * po/POTFILES.in: Likewise. * maidag/deliver.c (make_tmp): Rewrite. Return mu_mailbox_t. All callers changed. * maidag/lmtp.c (lmtp_transcript): Remove static. (lmpt_transcript): New function. (lmtp_reply): Use mu_stream_t instead of FILE. (xlatnl): Remove. Superseded by mu_rtrim_cset and family. (mtmp, mbox): Remove globals. (mesg): New global. (cfun_unknown, cfun_mail_from, cfun_rcpt_to) (dot_temp_fail, dot_deliver, cfun_rset) (cfun_lhlo, cfun_quit, cfun_help): Use mu_stream_t instead of FILE. (cfun_data): Rewrite. (cfun_dot): Remove. (to_fgets): Rewrite using mu_stream_t. (lmtp_loop): Change signature. Rewrite using mu_stream_t. (lmtp_connection, maidag_lmtp_server): Update accordingly. * maidag/maidag.c (maidag_transcript): New global. (options, parse_opt): New option --transcript. * maidag/maidag.h (maidag_transcript): New extern. (mail_tmp_begin, mail_tmp_add_line, mail_tmp_finish) (mail_tmp_destroy): Remove.
Showing
12 changed files
with
176 additions
and
252 deletions
... | @@ -390,16 +390,12 @@ mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd, int flags) | ... | @@ -390,16 +390,12 @@ mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd, int flags) |
390 | struct _mu_file_stream *fstr; | 390 | struct _mu_file_stream *fstr; |
391 | int rc = _mu_file_stream_create (&fstr, | 391 | int rc = _mu_file_stream_create (&fstr, |
392 | sizeof (struct _mu_file_stream), | 392 | sizeof (struct _mu_file_stream), |
393 | filename, fd, flags); | 393 | filename, fd, flags|_MU_STR_OPEN); |
394 | if (rc == 0) | 394 | if (rc == 0) |
395 | { | 395 | { |
396 | mu_stream_t stream = (mu_stream_t) fstr; | 396 | mu_stream_t stream = (mu_stream_t) fstr; |
397 | mu_stream_set_buffer (stream, mu_buffer_full, 0); | 397 | mu_stream_set_buffer (stream, mu_buffer_full, 0); |
398 | rc = mu_stream_open (stream); | 398 | *pstream = stream; |
399 | if (rc) | ||
400 | mu_stream_unref (stream); | ||
401 | else | ||
402 | *pstream = stream; | ||
403 | } | 399 | } |
404 | return rc; | 400 | return rc; |
405 | } | 401 | } | ... | ... |
... | @@ -414,8 +414,8 @@ mu_stream_to_message (mu_stream_t instream, mu_message_t *pmsg) | ... | @@ -414,8 +414,8 @@ mu_stream_to_message (mu_stream_t instream, mu_message_t *pmsg) |
414 | return rc; | 414 | return rc; |
415 | } | 415 | } |
416 | 416 | ||
417 | mu_envelope_set_date (env, _env_msg_date, msg); | 417 | mu_envelope_set_date (env, _env_msg_date, draftstream); |
418 | mu_envelope_set_sender (env, _env_msg_sender, msg); | 418 | mu_envelope_set_sender (env, _env_msg_sender, draftstream); |
419 | mu_message_set_envelope (msg, env, draftstream); | 419 | mu_message_set_envelope (msg, env, draftstream); |
420 | 420 | ||
421 | mu_body_create (&body, msg); | 421 | mu_body_create (&body, msg); | ... | ... |
... | @@ -34,6 +34,9 @@ | ... | @@ -34,6 +34,9 @@ |
34 | 34 | ||
35 | size_t mu_stream_default_buffer_size = MU_STREAM_DEFBUFSIZ; | 35 | size_t mu_stream_default_buffer_size = MU_STREAM_DEFBUFSIZ; |
36 | 36 | ||
37 | #define _MU_STR_FLUSH_ALL 0x01 | ||
38 | #define _MU_STR_FLUSH_KEEP 0x02 | ||
39 | |||
37 | #define _stream_event(stream, code, n, p) \ | 40 | #define _stream_event(stream, code, n, p) \ |
38 | do \ | 41 | do \ |
39 | { \ | 42 | { \ |
... | @@ -167,12 +170,12 @@ _stream_buffer_full_p (struct _mu_stream *stream) | ... | @@ -167,12 +170,12 @@ _stream_buffer_full_p (struct _mu_stream *stream) |
167 | } | 170 | } |
168 | 171 | ||
169 | static int | 172 | static int |
170 | _stream_flush_buffer (struct _mu_stream *stream, int all) | 173 | _stream_flush_buffer (struct _mu_stream *stream, int flags) |
171 | { | 174 | { |
172 | int rc; | 175 | int rc; |
173 | char *start, *end; | 176 | char *start, *end; |
174 | size_t wrsize; | 177 | size_t wrsize; |
175 | 178 | ||
176 | if (stream->flags & _MU_STR_DIRTY) | 179 | if (stream->flags & _MU_STR_DIRTY) |
177 | { | 180 | { |
178 | if ((stream->flags & MU_STREAM_SEEK) && stream->seek) | 181 | if ((stream->flags & MU_STREAM_SEEK) && stream->seek) |
... | @@ -215,7 +218,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int all) | ... | @@ -215,7 +218,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int all) |
215 | if (wrsize == 0) | 218 | if (wrsize == 0) |
216 | break; | 219 | break; |
217 | } | 220 | } |
218 | if ((all && wrsize) || wrsize == stream->level) | 221 | if (((flags & _MU_STR_FLUSH_ALL) && wrsize) || |
222 | wrsize == stream->level) | ||
219 | { | 223 | { |
220 | rc = _stream_write_unbuffered (stream, | 224 | rc = _stream_write_unbuffered (stream, |
221 | stream->buffer, | 225 | stream->buffer, |
... | @@ -234,10 +238,11 @@ _stream_flush_buffer (struct _mu_stream *stream, int all) | ... | @@ -234,10 +238,11 @@ _stream_flush_buffer (struct _mu_stream *stream, int all) |
234 | stream->level = stream->pos = wrsize; | 238 | stream->level = stream->pos = wrsize; |
235 | return 0; | 239 | return 0; |
236 | } | 240 | } |
241 | _stream_clrflag (stream, _MU_STR_DIRTY); | ||
237 | } | 242 | } |
238 | 243 | ||
239 | _stream_clrflag (stream, _MU_STR_DIRTY); | 244 | if (!(flags & _MU_STR_FLUSH_KEEP)) |
240 | stream->pos = stream->level = 0; | 245 | stream->pos = stream->level = 0; |
241 | return 0; | 246 | return 0; |
242 | } | 247 | } |
243 | 248 | ||
... | @@ -400,8 +405,8 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, | ... | @@ -400,8 +405,8 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, |
400 | case MU_SEEK_END: | 405 | case MU_SEEK_END: |
401 | rc = mu_stream_size (stream, &size); | 406 | rc = mu_stream_size (stream, &size); |
402 | if (rc) | 407 | if (rc) |
403 | return mu_stream_seterr (stream, rc, 1); | 408 | return rc; |
404 | offset += size + stream->pos; | 409 | offset += size; |
405 | break; | 410 | break; |
406 | 411 | ||
407 | default: | 412 | default: |
... | @@ -414,7 +419,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, | ... | @@ -414,7 +419,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, |
414 | || offset < stream->offset | 419 | || offset < stream->offset |
415 | || offset > stream->offset + stream->level)) | 420 | || offset > stream->offset + stream->level)) |
416 | { | 421 | { |
417 | if ((rc = _stream_flush_buffer (stream, 1))) | 422 | if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL))) |
418 | return rc; | 423 | return rc; |
419 | rc = stream->seek (stream, offset, &stream->offset); | 424 | rc = stream->seek (stream, offset, &stream->offset); |
420 | if (rc == ESPIPE) | 425 | if (rc == ESPIPE) |
... | @@ -425,7 +430,9 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, | ... | @@ -425,7 +430,9 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, |
425 | } | 430 | } |
426 | else if (stream->buftype != mu_buffer_none) | 431 | else if (stream->buftype != mu_buffer_none) |
427 | stream->pos = offset - stream->offset; | 432 | stream->pos = offset - stream->offset; |
428 | 433 | ||
434 | _mu_stream_cleareof (stream); | ||
435 | |||
429 | if (pres) | 436 | if (pres) |
430 | *pres = stream->offset + stream->pos; | 437 | *pres = stream->offset + stream->pos; |
431 | return 0; | 438 | return 0; |
... | @@ -469,7 +476,7 @@ _stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres) | ... | @@ -469,7 +476,7 @@ _stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres) |
469 | { | 476 | { |
470 | for (pos = 0;;) | 477 | for (pos = 0;;) |
471 | { | 478 | { |
472 | if ((rc = _stream_flush_buffer (stream, 1))) | 479 | if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL))) |
473 | return rc; | 480 | return rc; |
474 | if (stream->pos == stream->level) | 481 | if (stream->pos == stream->level) |
475 | { | 482 | { |
... | @@ -693,10 +700,15 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread) | ... | @@ -693,10 +700,15 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread) |
693 | { | 700 | { |
694 | char *bufp = buf; | 701 | char *bufp = buf; |
695 | size_t nbytes = 0; | 702 | size_t nbytes = 0; |
703 | int rc; | ||
704 | |||
705 | if ((rc = _stream_flush_buffer (stream, | ||
706 | _MU_STR_FLUSH_ALL|_MU_STR_FLUSH_KEEP))) | ||
707 | return rc; | ||
708 | |||
696 | while (size) | 709 | while (size) |
697 | { | 710 | { |
698 | size_t n; | 711 | size_t n; |
699 | int rc; | ||
700 | 712 | ||
701 | if (stream->pos == stream->level) | 713 | if (stream->pos == stream->level) |
702 | { | 714 | { |
... | @@ -824,7 +836,12 @@ mu_stream_readdelim (mu_stream_t stream, char *buf, size_t size, | ... | @@ -824,7 +836,12 @@ mu_stream_readdelim (mu_stream_t stream, char *buf, size_t size, |
824 | rc = _stream_readdelim (stream, buf, size, delim, pread); | 836 | rc = _stream_readdelim (stream, buf, size, delim, pread); |
825 | } | 837 | } |
826 | else | 838 | else |
827 | rc = _stream_scandelim (stream, buf, size, delim, pread); | 839 | { |
840 | if ((rc = _stream_flush_buffer (stream, | ||
841 | _MU_STR_FLUSH_ALL|_MU_STR_FLUSH_KEEP))) | ||
842 | return rc; | ||
843 | rc = _stream_scandelim (stream, buf, size, delim, pread); | ||
844 | } | ||
828 | return rc; | 845 | return rc; |
829 | } | 846 | } |
830 | 847 | ||
... | @@ -850,6 +867,10 @@ mu_stream_getdelim (mu_stream_t stream, char **pbuf, size_t *psize, | ... | @@ -850,6 +867,10 @@ mu_stream_getdelim (mu_stream_t stream, char **pbuf, size_t *psize, |
850 | _stream_init (stream); | 867 | _stream_init (stream); |
851 | } | 868 | } |
852 | 869 | ||
870 | if ((rc = _stream_flush_buffer (stream, | ||
871 | _MU_STR_FLUSH_ALL|_MU_STR_FLUSH_KEEP))) | ||
872 | return rc; | ||
873 | |||
853 | if (lineptr == NULL || n == 0) | 874 | if (lineptr == NULL || n == 0) |
854 | { | 875 | { |
855 | char *new_lineptr; | 876 | char *new_lineptr; |
... | @@ -997,7 +1018,7 @@ mu_stream_flush (mu_stream_t stream) | ... | @@ -997,7 +1018,7 @@ mu_stream_flush (mu_stream_t stream) |
997 | return MU_ERR_NOT_OPEN; | 1018 | return MU_ERR_NOT_OPEN; |
998 | _stream_init (stream); | 1019 | _stream_init (stream); |
999 | } | 1020 | } |
1000 | rc = _stream_flush_buffer (stream, 1); | 1021 | rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL); |
1001 | if (rc) | 1022 | if (rc) |
1002 | return rc; | 1023 | return rc; |
1003 | if ((stream->flags & _MU_STR_WRT) && stream->flush) | 1024 | if ((stream->flags & _MU_STR_WRT) && stream->flush) |
... | @@ -1031,7 +1052,8 @@ int | ... | @@ -1031,7 +1052,8 @@ int |
1031 | mu_stream_size (mu_stream_t stream, mu_off_t *psize) | 1052 | mu_stream_size (mu_stream_t stream, mu_off_t *psize) |
1032 | { | 1053 | { |
1033 | int rc; | 1054 | int rc; |
1034 | 1055 | mu_off_t size; | |
1056 | |||
1035 | if (!(stream->flags & _MU_STR_OPEN)) | 1057 | if (!(stream->flags & _MU_STR_OPEN)) |
1036 | { | 1058 | { |
1037 | if (stream->open) | 1059 | if (stream->open) |
... | @@ -1040,7 +1062,13 @@ mu_stream_size (mu_stream_t stream, mu_off_t *psize) | ... | @@ -1040,7 +1062,13 @@ mu_stream_size (mu_stream_t stream, mu_off_t *psize) |
1040 | } | 1062 | } |
1041 | if (!stream->size) | 1063 | if (!stream->size) |
1042 | return mu_stream_seterr (stream, ENOSYS, 0); | 1064 | return mu_stream_seterr (stream, ENOSYS, 0); |
1043 | rc = stream->size (stream, psize); | 1065 | rc = stream->size (stream, &size); |
1066 | if (rc == 0) | ||
1067 | { | ||
1068 | if (stream->buftype != mu_buffer_none && stream->offset == size) | ||
1069 | size += stream->level; | ||
1070 | *psize = size; | ||
1071 | } | ||
1044 | return mu_stream_seterr (stream, rc, rc != 0); | 1072 | return mu_stream_seterr (stream, rc, rc != 0); |
1045 | } | 1073 | } |
1046 | 1074 | ||
... | @@ -1118,7 +1146,7 @@ mu_stream_truncate (mu_stream_t stream, mu_off_t size) | ... | @@ -1118,7 +1146,7 @@ mu_stream_truncate (mu_stream_t stream, mu_off_t size) |
1118 | { | 1146 | { |
1119 | int rc; | 1147 | int rc; |
1120 | 1148 | ||
1121 | if ((rc = _stream_flush_buffer (stream, 1))) | 1149 | if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL))) |
1122 | return rc; | 1150 | return rc; |
1123 | return stream->truncate (stream, size); | 1151 | return stream->truncate (stream, size); |
1124 | } | 1152 | } | ... | ... |
... | @@ -72,6 +72,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, | ... | @@ -72,6 +72,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, |
72 | case EACCES: | 72 | case EACCES: |
73 | mu_stream_clearerr (src); | 73 | mu_stream_clearerr (src); |
74 | case ENOSYS: | 74 | case ENOSYS: |
75 | size = 0; | ||
75 | break; | 76 | break; |
76 | 77 | ||
77 | default: | 78 | default: | ... | ... |
... | @@ -66,7 +66,10 @@ mu_temp_file_stream_create (mu_stream_t *pstream, const char *dir) | ... | @@ -66,7 +66,10 @@ mu_temp_file_stream_create (mu_stream_t *pstream, const char *dir) |
66 | if (rc) | 66 | if (rc) |
67 | mu_stream_unref (stream); | 67 | mu_stream_unref (stream); |
68 | else | 68 | else |
69 | *pstream = stream; | 69 | { |
70 | mu_stream_set_buffer (stream, mu_buffer_full, 0); | ||
71 | *pstream = stream; | ||
72 | } | ||
70 | } | 73 | } |
71 | return 0; | 74 | return 0; |
72 | } | 75 | } | ... | ... |
... | @@ -19,26 +19,110 @@ | ... | @@ -19,26 +19,110 @@ |
19 | 19 | ||
20 | #include "maidag.h" | 20 | #include "maidag.h" |
21 | 21 | ||
22 | void | 22 | static mu_mailbox_t |
23 | make_tmp (const char *from, mu_mailbox_t *mbox) | 23 | make_tmp (const char *from) |
24 | { | 24 | { |
25 | struct mail_tmp *mtmp; | ||
26 | char *buf = NULL; | ||
27 | size_t n = 0; | ||
28 | int rc; | 25 | int rc; |
26 | mu_stream_t in, out; | ||
27 | char *buf = NULL; | ||
28 | size_t size = 0, n; | ||
29 | mu_mailbox_t mbox; | ||
30 | |||
31 | rc = mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_READ); | ||
32 | if (rc) | ||
33 | { | ||
34 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", | ||
35 | "MU_STDIN_FD", rc); | ||
36 | exit (EX_TEMPFAIL); | ||
37 | } | ||
38 | |||
39 | rc = mu_temp_file_stream_create (&out, NULL); | ||
40 | if (rc) | ||
41 | { | ||
42 | maidag_error (_("unable to open temporary file: %s"), mu_strerror (rc)); | ||
43 | exit (EX_TEMPFAIL); | ||
44 | } | ||
29 | 45 | ||
30 | if (mail_tmp_begin (&mtmp, from)) | 46 | rc = mu_stream_getline (in, &buf, &size, &n); |
31 | exit (EX_TEMPFAIL); | 47 | if (rc) |
48 | { | ||
49 | maidag_error (_("read error: %s"), mu_strerror (rc)); | ||
50 | mu_stream_destroy (&in); | ||
51 | mu_stream_destroy (&out); | ||
52 | exit (EX_TEMPFAIL); | ||
53 | } | ||
54 | if (n == 0) | ||
55 | { | ||
56 | maidag_error (_("unexpected EOF on input")); | ||
57 | mu_stream_destroy (&in); | ||
58 | mu_stream_destroy (&out); | ||
59 | exit (EX_TEMPFAIL); | ||
60 | } | ||
32 | 61 | ||
33 | while (getline (&buf, &n, stdin) > 0) | 62 | if (n >= 5 && memcmp (buf, "From ", 5)) |
34 | if ((rc = mail_tmp_add_line (mtmp, buf, strlen (buf)))) | 63 | { |
35 | break; | 64 | struct mu_auth_data *auth = NULL; |
65 | if (!from) | ||
66 | { | ||
67 | auth = mu_get_auth_by_uid (getuid ()); | ||
68 | if (auth) | ||
69 | from = auth->name; | ||
70 | } | ||
71 | if (from) | ||
72 | { | ||
73 | time_t t; | ||
74 | |||
75 | time (&t); | ||
76 | mu_stream_printf (out, "From %s %s", from, ctime (&t)); | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | maidag_error (_("cannot determine sender address")); | ||
81 | mu_stream_destroy (&in); | ||
82 | mu_stream_destroy (&out); | ||
83 | exit (EX_TEMPFAIL); | ||
84 | } | ||
85 | if (auth) | ||
86 | mu_auth_data_free (auth); | ||
87 | } | ||
88 | |||
89 | mu_stream_write (out, buf, n, NULL); | ||
36 | free (buf); | 90 | free (buf); |
37 | if (rc == 0) | 91 | |
38 | rc = mail_tmp_finish (mtmp, mbox); | 92 | rc = mu_stream_copy (out, in, 0, NULL); |
39 | mail_tmp_destroy (&mtmp); | 93 | |
94 | mu_stream_destroy (&in); | ||
40 | if (rc) | 95 | if (rc) |
41 | exit (EX_TEMPFAIL); | 96 | { |
97 | maidag_error (_("copy error: %s"), mu_strerror (rc)); | ||
98 | mu_stream_destroy (&out); | ||
99 | exit (EX_TEMPFAIL); | ||
100 | } | ||
101 | |||
102 | mu_stream_flush (out); | ||
103 | if ((rc = mu_mailbox_create (&mbox, "mbox:/dev/null")) | ||
104 | || (rc = mu_mailbox_open (mbox, MU_STREAM_READ)) | ||
105 | || (rc = mu_mailbox_set_stream (mbox, out))) | ||
106 | { | ||
107 | maidag_error (_("error opening temporary file: %s"), | ||
108 | mu_strerror (rc)); | ||
109 | mu_stream_destroy (&out); | ||
110 | exit (EX_TEMPFAIL); | ||
111 | } | ||
112 | |||
113 | rc = mu_mailbox_messages_count (mbox, &n); | ||
114 | if (rc) | ||
115 | { | ||
116 | errno = rc; | ||
117 | maidag_error (_("error creating temporary message: %s"), | ||
118 | mu_strerror (rc)); | ||
119 | mu_stream_destroy (&out); | ||
120 | exit (EX_TEMPFAIL); | ||
121 | } | ||
122 | |||
123 | /* FIXME: mu_stream_unref (out); But mu_mailbox_set_stream | ||
124 | steals the reference */ | ||
125 | return mbox; | ||
42 | } | 126 | } |
43 | 127 | ||
44 | int | 128 | int |
... | @@ -65,9 +149,7 @@ mda (mu_mailbox_t mbx, char *username) | ... | @@ -65,9 +149,7 @@ mda (mu_mailbox_t mbx, char *username) |
65 | int | 149 | int |
66 | maidag_stdio_delivery (int argc, char **argv) | 150 | maidag_stdio_delivery (int argc, char **argv) |
67 | { | 151 | { |
68 | mu_mailbox_t mbox; | 152 | mu_mailbox_t mbox = make_tmp (sender_address); |
69 | |||
70 | make_tmp (sender_address, &mbox); | ||
71 | 153 | ||
72 | if (multiple_delivery) | 154 | if (multiple_delivery) |
73 | multiple_delivery = argc > 1; | 155 | multiple_delivery = argc > 1; | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -53,6 +53,7 @@ int lmtp_mode; | ... | @@ -53,6 +53,7 @@ int lmtp_mode; |
53 | int url_option; | 53 | int url_option; |
54 | char *lmtp_url_string; | 54 | char *lmtp_url_string; |
55 | int reuse_lmtp_address = 1; | 55 | int reuse_lmtp_address = 1; |
56 | int maidag_transcript; | ||
56 | 57 | ||
57 | const char *program_version = "maidag (" PACKAGE_STRING ")"; | 58 | const char *program_version = "maidag (" PACKAGE_STRING ")"; |
58 | static char doc[] = | 59 | static char doc[] = |
... | @@ -72,6 +73,7 @@ static char args_doc[] = N_("[recipient...]"); | ... | @@ -72,6 +73,7 @@ static char args_doc[] = N_("[recipient...]"); |
72 | #define LMTP_OPTION 258 | 73 | #define LMTP_OPTION 258 |
73 | #define FOREGROUND_OPTION 260 | 74 | #define FOREGROUND_OPTION 260 |
74 | #define URL_OPTION 261 | 75 | #define URL_OPTION 261 |
76 | #define TRANSCRIPT_OPTION 262 | ||
75 | 77 | ||
76 | static struct argp_option options[] = | 78 | static struct argp_option options[] = |
77 | { | 79 | { |
... | @@ -79,21 +81,23 @@ static struct argp_option options[] = | ... | @@ -79,21 +81,23 @@ static struct argp_option options[] = |
79 | { NULL, 0, NULL, 0, | 81 | { NULL, 0, NULL, 0, |
80 | N_("General options"), GRID }, | 82 | N_("General options"), GRID }, |
81 | 83 | ||
82 | { "foreground", FOREGROUND_OPTION, 0, 0, N_("remain in foreground"), | 84 | { "foreground", FOREGROUND_OPTION, 0, 0, N_("remain in foreground"), |
83 | GRID + 1 }, | 85 | GRID + 1 }, |
84 | { "inetd", 'i', 0, 0, N_("run in inetd mode"), GRID + 1 }, | 86 | { "inetd", 'i', 0, 0, N_("run in inetd mode"), GRID + 1 }, |
85 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, | 87 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, |
86 | N_("runs in daemon mode with a maximum of NUMBER children"), GRID + 1 }, | 88 | N_("runs in daemon mode with a maximum of NUMBER children"), GRID + 1 }, |
87 | { "url", URL_OPTION, 0, 0, N_("deliver to given URLs"), GRID + 1 }, | 89 | { "url", URL_OPTION, 0, 0, N_("deliver to given URLs"), GRID + 1 }, |
88 | { "from", 'f', N_("EMAIL"), 0, | 90 | { "from", 'f', N_("EMAIL"), 0, |
89 | N_("specify the sender's name"), GRID + 1 }, | 91 | N_("specify the sender's name"), GRID + 1 }, |
90 | { NULL, 'r', NULL, OPTION_ALIAS, NULL }, | 92 | { NULL, 'r', NULL, OPTION_ALIAS, NULL }, |
91 | { "lmtp", LMTP_OPTION, N_("URL"), OPTION_ARG_OPTIONAL, | 93 | { "lmtp", LMTP_OPTION, N_("URL"), OPTION_ARG_OPTIONAL, |
92 | N_("operate in LMTP mode"), GRID + 1 }, | 94 | N_("operate in LMTP mode"), GRID + 1 }, |
93 | { "debug", 'x', N_("FLAGS"), 0, | 95 | { "debug", 'x', N_("FLAGS"), 0, |
94 | N_("enable debugging"), GRID + 1 }, | 96 | N_("enable debugging"), GRID + 1 }, |
95 | { "stderr", STDERR_OPTION, NULL, 0, | 97 | { "stderr", STDERR_OPTION, NULL, 0, |
96 | N_("log to standard error"), GRID + 1 }, | 98 | N_("log to standard error"), GRID + 1 }, |
99 | { "transcript", TRANSCRIPT_OPTION, NULL, 0, | ||
100 | N_("enable session transcript"), GRID + 1 }, | ||
97 | #undef GRID | 101 | #undef GRID |
98 | 102 | ||
99 | #define GRID 2 | 103 | #define GRID 2 |
... | @@ -212,6 +216,10 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -212,6 +216,10 @@ parse_opt (int key, char *arg, struct argp_state *state) |
212 | mu_argp_node_list_new (lst, "listen", arg); | 216 | mu_argp_node_list_new (lst, "listen", arg); |
213 | break; | 217 | break; |
214 | 218 | ||
219 | case TRANSCRIPT_OPTION: | ||
220 | maidag_transcript = 1; | ||
221 | break; | ||
222 | |||
215 | case 'r': | 223 | case 'r': |
216 | case 'f': | 224 | case 'f': |
217 | if (sender_address != NULL) | 225 | if (sender_address != NULL) | ... | ... |
... | @@ -142,6 +142,7 @@ extern char *lmtp_url_string; | ... | @@ -142,6 +142,7 @@ extern char *lmtp_url_string; |
142 | extern int reuse_lmtp_address; | 142 | extern int reuse_lmtp_address; |
143 | extern mu_list_t lmtp_groups; | 143 | extern mu_list_t lmtp_groups; |
144 | extern mu_acl_t maidag_acl; | 144 | extern mu_acl_t maidag_acl; |
145 | extern int maidag_transcript; | ||
145 | 146 | ||
146 | void close_fds (void); | 147 | void close_fds (void); |
147 | int switch_user_id (struct mu_auth_data *auth, int user); | 148 | int switch_user_id (struct mu_auth_data *auth, int user); |
... | @@ -160,12 +161,6 @@ int deliver (mu_message_t msg, char *name, char **errp); | ... | @@ -160,12 +161,6 @@ int deliver (mu_message_t msg, char *name, char **errp); |
160 | int sieve_test (struct mu_auth_data *auth, mu_message_t msg); | 161 | int sieve_test (struct mu_auth_data *auth, mu_message_t msg); |
161 | int check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest); | 162 | int check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest); |
162 | 163 | ||
163 | struct mail_tmp; | ||
164 | int mail_tmp_begin (struct mail_tmp **pmtmp, const char *from); | ||
165 | int mail_tmp_add_line (struct mail_tmp *mtmp, char *buf, size_t buflen); | ||
166 | int mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox); | ||
167 | void mail_tmp_destroy (struct mail_tmp **pmtmp); | ||
168 | |||
169 | enum maidag_forward_result | 164 | enum maidag_forward_result |
170 | { | 165 | { |
171 | maidag_forward_none, | 166 | maidag_forward_none, | ... | ... |
maidag/mailtmp.c
deleted
100644 → 0
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2009, 2010 Free | ||
3 | Software Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils; if not, write to the Free Software | ||
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
18 | MA 02110-1301 USA */ | ||
19 | |||
20 | #include "maidag.h" | ||
21 | |||
22 | struct mail_tmp | ||
23 | { | ||
24 | mu_stream_t stream; | ||
25 | size_t line; | ||
26 | char *tempfile; | ||
27 | const char *from; | ||
28 | int had_nl; | ||
29 | }; | ||
30 | |||
31 | int | ||
32 | mail_tmp_begin (struct mail_tmp **pmtmp, const char *from) | ||
33 | { | ||
34 | int status; | ||
35 | struct mail_tmp *mtmp = malloc (sizeof *mtmp); | ||
36 | |||
37 | if (!mtmp) | ||
38 | return ENOMEM; | ||
39 | |||
40 | memset (mtmp, 0, sizeof *mtmp); | ||
41 | |||
42 | mtmp->tempfile = mu_tempname (NULL); | ||
43 | if ((status = mu_file_stream_create (&mtmp->stream, mtmp->tempfile, | ||
44 | MU_STREAM_RDWR))) | ||
45 | { | ||
46 | free (mtmp); | ||
47 | maidag_error (_("unable to open temporary file: %s"), | ||
48 | mu_strerror (status)); | ||
49 | return status; | ||
50 | } | ||
51 | |||
52 | mtmp->from = from; | ||
53 | *pmtmp = mtmp; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | int | ||
58 | mail_tmp_add_line (struct mail_tmp *mtmp, char *buf, size_t buflen) | ||
59 | { | ||
60 | int status = 0; | ||
61 | |||
62 | mtmp->line++; | ||
63 | if (mtmp->line == 1) | ||
64 | { | ||
65 | const char *from = mtmp->from; | ||
66 | |||
67 | if (buflen >= 5 && memcmp (buf, "From ", 5)) | ||
68 | { | ||
69 | struct mu_auth_data *auth = NULL; | ||
70 | if (!from) | ||
71 | { | ||
72 | auth = mu_get_auth_by_uid (getuid ()); | ||
73 | if (auth) | ||
74 | from = auth->name; | ||
75 | } | ||
76 | if (from) | ||
77 | { | ||
78 | time_t t; | ||
79 | char *envs; | ||
80 | |||
81 | time (&t); | ||
82 | asprintf (&envs, "From %s %s", from, ctime (&t)); | ||
83 | status = mu_stream_write (mtmp->stream, | ||
84 | envs, | ||
85 | strlen (envs), NULL); | ||
86 | free (envs); | ||
87 | } | ||
88 | else | ||
89 | { | ||
90 | maidag_error (_("cannot determine sender address")); | ||
91 | return EINVAL; | ||
92 | } | ||
93 | if (auth) | ||
94 | mu_auth_data_free (auth); | ||
95 | } | ||
96 | } | ||
97 | else if (buflen >= 5 && !memcmp (buf, "From ", 5)) | ||
98 | { | ||
99 | static char *escape = ">"; | ||
100 | status = mu_stream_write (mtmp->stream, escape, 1, NULL); | ||
101 | } | ||
102 | |||
103 | if (!status) | ||
104 | status = mu_stream_write (mtmp->stream, buf, buflen, NULL); | ||
105 | |||
106 | if (status) | ||
107 | { | ||
108 | maidag_error (_("error writing temporary file: %s"), | ||
109 | mu_strerror (status)); | ||
110 | mu_stream_destroy (&mtmp->stream); | ||
111 | } | ||
112 | mtmp->had_nl = buf[buflen-1] == '\n'; | ||
113 | return status; | ||
114 | } | ||
115 | |||
116 | int | ||
117 | mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox) | ||
118 | { | ||
119 | int status; | ||
120 | static char *newline = "\n"; | ||
121 | size_t n; | ||
122 | |||
123 | if (!mtmp->had_nl) | ||
124 | status = mu_stream_write (mtmp->stream, newline, 1, NULL); | ||
125 | |||
126 | status = mu_stream_write (mtmp->stream, newline, 1, NULL); | ||
127 | unlink (mtmp->tempfile); | ||
128 | free (mtmp->tempfile); | ||
129 | mtmp->tempfile = NULL; | ||
130 | |||
131 | if (status) | ||
132 | { | ||
133 | errno = status; | ||
134 | maidag_error (_("error writing temporary file: %s"), | ||
135 | mu_strerror (status)); | ||
136 | mu_stream_destroy (&mtmp->stream); | ||
137 | return status; | ||
138 | } | ||
139 | |||
140 | mu_stream_flush (mtmp->stream); | ||
141 | if ((status = mu_mailbox_create (mbox, "mbox:/dev/null")) | ||
142 | || (status = mu_mailbox_open (*mbox, MU_STREAM_READ)) | ||
143 | || (status = mu_mailbox_set_stream (*mbox, mtmp->stream))) | ||
144 | { | ||
145 | maidag_error (_("error opening temporary file: %s"), | ||
146 | mu_strerror (status)); | ||
147 | mu_stream_destroy (&mtmp->stream); | ||
148 | return status; | ||
149 | } | ||
150 | |||
151 | status = mu_mailbox_messages_count (*mbox, &n); | ||
152 | if (status) | ||
153 | { | ||
154 | errno = status; | ||
155 | maidag_error (_("error creating temporary message: %s"), | ||
156 | mu_strerror (status)); | ||
157 | mu_stream_destroy (&mtmp->stream); | ||
158 | return status; | ||
159 | } | ||
160 | |||
161 | mtmp->stream = NULL; | ||
162 | mtmp->line = 0; | ||
163 | |||
164 | return status; | ||
165 | |||
166 | } | ||
167 | |||
168 | void | ||
169 | mail_tmp_destroy (struct mail_tmp **pmtmp) | ||
170 | { | ||
171 | struct mail_tmp *mtmp = *pmtmp; | ||
172 | |||
173 | if (mtmp) | ||
174 | { | ||
175 | if (mtmp->tempfile) | ||
176 | { | ||
177 | unlink (mtmp->tempfile); | ||
178 | free (mtmp->tempfile); | ||
179 | } | ||
180 | mu_stream_destroy (&mtmp->stream); | ||
181 | free (*pmtmp); | ||
182 | *pmtmp = NULL; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | |||
187 |
-
Please register or sign in to post a comment