Various fixes in imap4d.
Imap4d successfully passes all tests. * imap4d/close.c (imap4d_close0): Fix improper use of MU_STREAM_READ (flags changed their semantics since then). * imap4d/fetch.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. (fetch_io): Rewrite using CRLF encoder and util_copy_out. (_frt_header_fields): Rewind memory stream before reading from it. * imap4d/auth_gsasl.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. * imap4d/auth_gss.c: Likewise. * imap4d/capability.c: Likewise. * imap4d/copy.c: Likewise. * imap4d/id.c: Likewise. * imap4d/idle.c: Likewise. * imap4d/list.c: Likewise. * imap4d/namespace.c: Likewise. * imap4d/preauth.c: Likewise. * imap4d/search.c: Likewise. * imap4d/status.c: Likewise. * imap4d/store.c: Likewise. * imap4d/select.c: Likewise. (imap4d_select_status): Fix improper use of MU_STREAM_READ. * imap4d/util.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. (util_setio): Apply CRLF filters to both input and output streams (in opposite directions). (util_copy_out): New function. (remove_cr): Remove. * imap4d/imap4d.h (util_copy_out): New prototype.
Showing
17 changed files
with
66 additions
and
78 deletions
... | @@ -95,7 +95,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username) | ... | @@ -95,7 +95,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username) |
95 | while ((rc = gsasl_step64 (sess_ctx, input_str, &output)) | 95 | while ((rc = gsasl_step64 (sess_ctx, input_str, &output)) |
96 | == GSASL_NEEDS_MORE) | 96 | == GSASL_NEEDS_MORE) |
97 | { | 97 | { |
98 | util_send ("+ %s\r\n", output); | 98 | util_send ("+ %s\n", output); |
99 | imap4d_getline (&input_str, &input_size, &input_len); | 99 | imap4d_getline (&input_str, &input_size, &input_len); |
100 | } | 100 | } |
101 | 101 | ||
... | @@ -112,7 +112,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username) | ... | @@ -112,7 +112,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username) |
112 | returned, and clients must respond with an empty response. */ | 112 | returned, and clients must respond with an empty response. */ |
113 | if (output[0]) | 113 | if (output[0]) |
114 | { | 114 | { |
115 | util_send ("+ %s\r\n", output); | 115 | util_send ("+ %s\n", output); |
116 | imap4d_getline (&input_str, &input_size, &input_len); | 116 | imap4d_getline (&input_str, &input_size, &input_len); |
117 | if (input_len != 0) | 117 | if (input_len != 0) |
118 | { | 118 | { | ... | ... |
... | @@ -163,7 +163,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -163,7 +163,7 @@ auth_gssapi (struct imap4d_command *command, |
163 | 163 | ||
164 | /* Start the dialogue */ | 164 | /* Start the dialogue */ |
165 | 165 | ||
166 | util_send ("+ \r\n"); | 166 | util_send ("+ \n"); |
167 | util_flush_output (); | 167 | util_flush_output (); |
168 | 168 | ||
169 | context = GSS_C_NO_CONTEXT; | 169 | context = GSS_C_NO_CONTEXT; |
... | @@ -192,7 +192,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -192,7 +192,7 @@ auth_gssapi (struct imap4d_command *command, |
192 | if (outbuf.length) | 192 | if (outbuf.length) |
193 | { | 193 | { |
194 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 194 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
195 | util_send ("+ %s\r\n", tmp); | 195 | util_send ("+ %s\n", tmp); |
196 | free (tmp); | 196 | free (tmp); |
197 | gss_release_buffer (&min_stat, &outbuf); | 197 | gss_release_buffer (&min_stat, &outbuf); |
198 | } | 198 | } |
... | @@ -212,7 +212,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -212,7 +212,7 @@ auth_gssapi (struct imap4d_command *command, |
212 | if (outbuf.length) | 212 | if (outbuf.length) |
213 | { | 213 | { |
214 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 214 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
215 | util_send ("+ %s\r\n", tmp); | 215 | util_send ("+ %s\n", tmp); |
216 | free (tmp); | 216 | free (tmp); |
217 | gss_release_buffer (&min_stat, &outbuf); | 217 | gss_release_buffer (&min_stat, &outbuf); |
218 | imap4d_getline (&token_str, &token_size, &token_len); | 218 | imap4d_getline (&token_str, &token_size, &token_len); |
... | @@ -232,7 +232,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -232,7 +232,7 @@ auth_gssapi (struct imap4d_command *command, |
232 | } | 232 | } |
233 | 233 | ||
234 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); | 234 | mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size); |
235 | util_send ("+ %s\r\n", tmp); | 235 | util_send ("+ %s\n", tmp); |
236 | free (tmp); | 236 | free (tmp); |
237 | 237 | ||
238 | imap4d_getline (&token_str, &token_size, &token_len); | 238 | imap4d_getline (&token_str, &token_size, &token_len); | ... | ... |
... | @@ -80,7 +80,7 @@ imap4d_capability (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -80,7 +80,7 @@ imap4d_capability (struct imap4d_command *command, imap4d_tokbuf_t tok) |
80 | mu_list_do (capa_list, print_capa, NULL); | 80 | mu_list_do (capa_list, print_capa, NULL); |
81 | 81 | ||
82 | imap4d_auth_capability (); | 82 | imap4d_auth_capability (); |
83 | util_send ("\r\n"); | 83 | util_send ("\n"); |
84 | 84 | ||
85 | return util_finish (command, RESP_OK, "Completed"); | 85 | return util_finish (command, RESP_OK, "Completed"); |
86 | } | 86 | } | ... | ... |
... | @@ -30,7 +30,7 @@ imap4d_close0 (struct imap4d_command *command, imap4d_tokbuf_t tok, | ... | @@ -30,7 +30,7 @@ imap4d_close0 (struct imap4d_command *command, imap4d_tokbuf_t tok, |
30 | return util_finish (command, RESP_BAD, "Invalid arguments"); | 30 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
31 | 31 | ||
32 | mu_mailbox_get_flags (mbox, &flags); | 32 | mu_mailbox_get_flags (mbox, &flags); |
33 | if ((flags & MU_STREAM_READ) == 0) | 33 | if (flags & MU_STREAM_WRITE) |
34 | { | 34 | { |
35 | status = mu_mailbox_flush (mbox, expunge); | 35 | status = mu_mailbox_flush (mbox, expunge); |
36 | if (status) | 36 | if (status) | ... | ... |
... | @@ -52,7 +52,7 @@ imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -52,7 +52,7 @@ imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok) |
52 | int new_state = (rc == RESP_OK) ? command->success : command->failure; | 52 | int new_state = (rc == RESP_OK) ? command->success : command->failure; |
53 | if (new_state != STATE_NONE) | 53 | if (new_state != STATE_NONE) |
54 | state = new_state; | 54 | state = new_state; |
55 | return util_send ("%s %s\r\n", command->tag, text); | 55 | return util_send ("%s %s\n", command->tag, text); |
56 | } | 56 | } |
57 | return util_finish (command, rc, "%s", text); | 57 | return util_finish (command, rc, "%s", text); |
58 | } | 58 | } | ... | ... |
... | @@ -690,39 +690,36 @@ static int | ... | @@ -690,39 +690,36 @@ static int |
690 | fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) | 690 | fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) |
691 | { | 691 | { |
692 | mu_stream_t rfc = NULL; | 692 | mu_stream_t rfc = NULL; |
693 | |||
693 | size_t n = 0; | 694 | size_t n = 0; |
694 | 695 | ||
695 | mu_filter_create (&rfc, stream, "rfc822", MU_FILTER_ENCODE, | 696 | mu_filter_create (&rfc, stream, "rfc822", MU_FILTER_ENCODE, |
696 | MU_STREAM_READ|MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE); | 697 | MU_STREAM_READ|MU_STREAM_SEEK|MU_STREAM_NO_CLOSE); |
697 | 698 | ||
698 | if (start == 0 && size == (size_t) -1) | 699 | if (start == 0 && size == (size_t) -1) |
699 | { | 700 | { |
700 | char *buffer; | ||
701 | size_t bufsize; | ||
702 | int rc; | 701 | int rc; |
703 | 702 | ||
704 | for (bufsize = max; (buffer = malloc (bufsize)) == NULL; bufsize /= 2) | ||
705 | if (bufsize < 512) | ||
706 | imap4d_bye (ERR_NO_MEM); | ||
707 | |||
708 | rc = mu_stream_seek (rfc, 0, MU_SEEK_SET, NULL); | 703 | rc = mu_stream_seek (rfc, 0, MU_SEEK_SET, NULL); |
709 | if (rc) | 704 | if (rc) |
710 | { | 705 | { |
711 | mu_error ("seek error: %s", mu_stream_strerror (rfc, rc)); | 706 | mu_error ("seek error: %s", mu_stream_strerror (stream, rc)); |
712 | return RESP_BAD; | 707 | return RESP_BAD; |
713 | } | 708 | } |
714 | if (max) | 709 | if (max) |
715 | { | 710 | { |
716 | util_send (" {%lu}\r\n", (unsigned long) max); | 711 | util_send (" {%lu}\n", (unsigned long) max); |
717 | while (mu_stream_read (rfc, buffer, bufsize, &n) == 0 && n > 0) | 712 | util_copy_out (rfc, max); |
718 | util_send_bytes (buffer, n); | ||
719 | |||
720 | /* FIXME: Make sure exactly max bytes were sent */ | 713 | /* FIXME: Make sure exactly max bytes were sent */ |
721 | free (buffer); | ||
722 | } | 714 | } |
723 | else | 715 | else |
724 | util_send (" \"\""); | 716 | util_send (" \"\""); |
725 | } | 717 | } |
718 | else if (start > max) | ||
719 | { | ||
720 | util_send ("<%lu>", (unsigned long) start); | ||
721 | util_send (" \"\""); | ||
722 | } | ||
726 | else if (size + 2 < size) /* Check for integer overflow */ | 723 | else if (size + 2 < size) /* Check for integer overflow */ |
727 | { | 724 | { |
728 | mu_stream_destroy (&rfc); | 725 | mu_stream_destroy (&rfc); |
... | @@ -738,16 +735,17 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) | ... | @@ -738,16 +735,17 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) |
738 | if (!p) | 735 | if (!p) |
739 | imap4d_bye (ERR_NO_MEM); | 736 | imap4d_bye (ERR_NO_MEM); |
740 | 737 | ||
741 | rc = mu_stream_seek (stream, start, MU_SEEK_SET, NULL); | 738 | rc = mu_stream_seek (rfc, start, MU_SEEK_SET, NULL); |
742 | if (rc) | 739 | if (rc) |
743 | { | 740 | { |
744 | mu_error ("seek error: %s", mu_stream_strerror (rfc, rc)); | 741 | mu_error ("seek error: %s", mu_stream_strerror (rfc, rc)); |
745 | free (buffer); | 742 | free (buffer); |
743 | mu_stream_destroy (&rfc); | ||
746 | return RESP_BAD; | 744 | return RESP_BAD; |
747 | } | 745 | } |
748 | 746 | ||
749 | while (total < size | 747 | while (total < size |
750 | && mu_stream_read (rfc, p, size - total + 1, &n) == 0 | 748 | && mu_stream_read (rfc, p, size - total, &n) == 0 |
751 | && n > 0) | 749 | && n > 0) |
752 | { | 750 | { |
753 | total += n; | 751 | total += n; |
... | @@ -757,7 +755,7 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) | ... | @@ -757,7 +755,7 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max) |
757 | util_send ("<%lu>", (unsigned long) start); | 755 | util_send ("<%lu>", (unsigned long) start); |
758 | if (total) | 756 | if (total) |
759 | { | 757 | { |
760 | util_send (" {%lu}\r\n", (unsigned long) total); | 758 | util_send (" {%lu}\n", (unsigned long) total); |
761 | util_send_bytes (buffer, total); | 759 | util_send_bytes (buffer, total); |
762 | } | 760 | } |
763 | else | 761 | else |
... | @@ -1071,6 +1069,7 @@ _frt_header_fields (struct fetch_function_closure *ffc, | ... | @@ -1071,6 +1069,7 @@ _frt_header_fields (struct fetch_function_closure *ffc, |
1071 | 1069 | ||
1072 | /* Output collected data */ | 1070 | /* Output collected data */ |
1073 | mu_stream_size (stream, &size); | 1071 | mu_stream_size (stream, &size); |
1072 | mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); | ||
1074 | status = fetch_io (stream, ffc->start, ffc->size, size + lines); | 1073 | status = fetch_io (stream, ffc->start, ffc->size, size + lines); |
1075 | mu_stream_destroy (&stream); | 1074 | mu_stream_destroy (&stream); |
1076 | 1075 | ||
... | @@ -1648,7 +1647,7 @@ imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text) | ... | @@ -1648,7 +1647,7 @@ imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
1648 | util_send ("* %lu FETCH (", (unsigned long) frc.msgno); | 1647 | util_send ("* %lu FETCH (", (unsigned long) frc.msgno); |
1649 | frc.eltno = 0; | 1648 | frc.eltno = 0; |
1650 | rc = mu_list_do (pclos.fnlist, _do_fetch, &frc); | 1649 | rc = mu_list_do (pclos.fnlist, _do_fetch, &frc); |
1651 | util_send (")\r\n"); | 1650 | util_send (")\n"); |
1652 | } | 1651 | } |
1653 | } | 1652 | } |
1654 | } | 1653 | } |
... | @@ -1684,4 +1683,3 @@ imap4d_fetch (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -1684,4 +1683,3 @@ imap4d_fetch (struct imap4d_command *command, imap4d_tokbuf_t tok) |
1684 | rc = imap4d_fetch0 (tok, 0, &err_text); | 1683 | rc = imap4d_fetch0 (tok, 0, &err_text); |
1685 | return util_finish (command, rc, "%s", err_text); | 1684 | return util_finish (command, rc, "%s", err_text); |
1686 | } | 1685 | } |
1687 | ... | ... |
... | @@ -202,7 +202,7 @@ imap4d_id (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -202,7 +202,7 @@ imap4d_id (struct imap4d_command *command, imap4d_tokbuf_t tok) |
202 | } | 202 | } |
203 | mu_iterator_destroy (&itr); | 203 | mu_iterator_destroy (&itr); |
204 | if (outcnt) | 204 | if (outcnt) |
205 | util_send (")\r\n"); | 205 | util_send (")\n"); |
206 | } | 206 | } |
207 | return util_finish (command, RESP_OK, "Completed"); | 207 | return util_finish (command, RESP_OK, "Completed"); |
208 | } | 208 | } | ... | ... |
... | @@ -32,7 +32,7 @@ imap4d_idle (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -32,7 +32,7 @@ imap4d_idle (struct imap4d_command *command, imap4d_tokbuf_t tok) |
32 | if (util_wait_input (0) == -1) | 32 | if (util_wait_input (0) == -1) |
33 | return util_finish (command, RESP_NO, "Cannot idle"); | 33 | return util_finish (command, RESP_NO, "Cannot idle"); |
34 | 34 | ||
35 | util_send ("+ idling\r\n"); | 35 | util_send ("+ idling\n"); |
36 | util_flush_output (); | 36 | util_flush_output (); |
37 | 37 | ||
38 | start = time (NULL); | 38 | start = time (NULL); | ... | ... |
... | @@ -202,7 +202,7 @@ extern int imap4d_transcript; | ... | @@ -202,7 +202,7 @@ extern int imap4d_transcript; |
202 | extern mu_list_t imap4d_id_list; | 202 | extern mu_list_t imap4d_id_list; |
203 | extern int imap4d_argc; | 203 | extern int imap4d_argc; |
204 | extern char **imap4d_argv; | 204 | extern char **imap4d_argv; |
205 | 205 | ||
206 | #ifndef HAVE_STRTOK_R | 206 | #ifndef HAVE_STRTOK_R |
207 | extern char *strtok_r (char *s, const char *delim, char **save_ptr); | 207 | extern char *strtok_r (char *s, const char *delim, char **save_ptr); |
208 | #endif | 208 | #endif |
... | @@ -334,6 +334,8 @@ extern int util_send (const char *, ...) MU_PRINTFLIKE(1,2); | ... | @@ -334,6 +334,8 @@ extern int util_send (const char *, ...) MU_PRINTFLIKE(1,2); |
334 | extern int util_send_bytes (const char *buf, size_t size); | 334 | extern int util_send_bytes (const char *buf, size_t size); |
335 | extern int util_send_qstring (const char *); | 335 | extern int util_send_qstring (const char *); |
336 | extern int util_send_literal (const char *); | 336 | extern int util_send_literal (const char *); |
337 | extern int util_copy_out (mu_stream_t str, size_t size); | ||
338 | |||
337 | extern int util_start (char *); | 339 | extern int util_start (char *); |
338 | extern int util_finish (struct imap4d_command *, int, const char *, ...) | 340 | extern int util_finish (struct imap4d_command *, int, const char *, ...) |
339 | MU_PRINTFLIKE(3,4); | 341 | MU_PRINTFLIKE(3,4); | ... | ... |
... | @@ -97,11 +97,11 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) | ... | @@ -97,11 +97,11 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) |
97 | name = refinfo->buf; | 97 | name = refinfo->buf; |
98 | 98 | ||
99 | if (strpbrk (name, "\"{}")) | 99 | if (strpbrk (name, "\"{}")) |
100 | util_send ("{%lu}\r\n%s\r\n", (unsigned long) strlen (name), name); | 100 | util_send ("{%lu}\n%s\n", (unsigned long) strlen (name), name); |
101 | else if (is_atom (name)) | 101 | else if (is_atom (name)) |
102 | util_send ("%s\r\n", name); | 102 | util_send ("%s\n", name); |
103 | else | 103 | else |
104 | util_send ("\"%s\"\r\n", name); | 104 | util_send ("\"%s\"\n", name); |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | 107 | ... | ... |
... | @@ -126,7 +126,7 @@ imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -126,7 +126,7 @@ imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok) |
126 | print_namespace (NS_OTHER); | 126 | print_namespace (NS_OTHER); |
127 | util_send (" "); | 127 | util_send (" "); |
128 | print_namespace (NS_SHARED); | 128 | print_namespace (NS_SHARED); |
129 | util_send ("\r\n"); | 129 | util_send ("\n"); |
130 | 130 | ||
131 | return util_finish (command, RESP_OK, "Completed"); | 131 | return util_finish (command, RESP_OK, "Completed"); |
132 | } | 132 | } | ... | ... |
... | @@ -366,7 +366,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) | ... | @@ -366,7 +366,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa) |
366 | return NULL; | 366 | return NULL; |
367 | } | 367 | } |
368 | 368 | ||
369 | mu_stream_printf (stream, "%u , %u\r\n", | 369 | mu_stream_printf (stream, "%u , %u\n", |
370 | ntohs (clt_addr->sin_port), | 370 | ntohs (clt_addr->sin_port), |
371 | ntohs (srv_addr->sin_port)); | 371 | ntohs (srv_addr->sin_port)); |
372 | mu_stream_shutdown (stream, MU_STREAM_WRITE); | 372 | mu_stream_shutdown (stream, MU_STREAM_WRITE); | ... | ... |
... | @@ -363,7 +363,7 @@ do_search (struct parsebuf *pb) | ... | @@ -363,7 +363,7 @@ do_search (struct parsebuf *pb) |
363 | util_send (" %s", mu_umaxtostr (0, pb->msgno)); | 363 | util_send (" %s", mu_umaxtostr (0, pb->msgno)); |
364 | } | 364 | } |
365 | } | 365 | } |
366 | util_send ("\r\n"); | 366 | util_send ("\n"); |
367 | } | 367 | } |
368 | 368 | ||
369 | /* Parse buffer functions */ | 369 | /* Parse buffer functions */ | ... | ... |
... | @@ -74,9 +74,9 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, | ... | @@ -74,9 +74,9 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname, |
74 | { | 74 | { |
75 | free (mailbox_name); | 75 | free (mailbox_name); |
76 | /* Need to set the state explicitely for select. */ | 76 | /* Need to set the state explicitely for select. */ |
77 | return util_send ("%s OK [%s] %s Completed\r\n", command->tag, | 77 | return util_send ("%s OK [%s] %s Completed\n", command->tag, |
78 | (flags & MU_STREAM_READ) ? | 78 | ((flags & MU_STREAM_RDWR) == MU_STREAM_RDWR) ? |
79 | "READ-ONLY" : "READ-WRITE", command->name); | 79 | "READ-WRITE" : "READ-ONLY", command->name); |
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
... | @@ -119,7 +119,7 @@ imap4d_select_status () | ... | @@ -119,7 +119,7 @@ imap4d_select_status () |
119 | /* FIXME: | 119 | /* FIXME: |
120 | - '\*' can be supported if we use the attribute_set userflag() | 120 | - '\*' can be supported if we use the attribute_set userflag() |
121 | - Answered is still not set in the mailbox code. */ | 121 | - Answered is still not set in the mailbox code. */ |
122 | if (select_flags & MU_STREAM_READ) | 122 | if (!(select_flags & MU_STREAM_WRITE)) |
123 | util_out (RESP_OK, "[PERMANENTFLAGS ()] No Permanent flags"); | 123 | util_out (RESP_OK, "[PERMANENTFLAGS ()] No Permanent flags"); |
124 | else | 124 | else |
125 | util_out (RESP_OK, "[PERMANENTFLAGS (%s)] Permanent flags", pflags); | 125 | util_out (RESP_OK, "[PERMANENTFLAGS (%s)] Permanent flags", pflags); | ... | ... |
... | @@ -136,7 +136,7 @@ imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok) | ... | @@ -136,7 +136,7 @@ imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok) |
136 | 136 | ||
137 | 137 | ||
138 | if (count > 0) | 138 | if (count > 0) |
139 | util_send (")\r\n"); | 139 | util_send (")\n"); |
140 | mu_mailbox_close (smbox); | 140 | mu_mailbox_close (smbox); |
141 | } | 141 | } |
142 | mu_mailbox_destroy (&smbox); | 142 | mu_mailbox_destroy (&smbox); | ... | ... |
... | @@ -157,7 +157,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext) | ... | @@ -157,7 +157,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext) |
157 | util_send ("UID %lu ", (unsigned long) msgno); | 157 | util_send ("UID %lu ", (unsigned long) msgno); |
158 | util_send ("FLAGS ("); | 158 | util_send ("FLAGS ("); |
159 | util_print_flags (attr); | 159 | util_print_flags (attr); |
160 | util_send ("))\r\n"); | 160 | util_send ("))\n"); |
161 | } | 161 | } |
162 | /* Update the flags of uid table. */ | 162 | /* Update the flags of uid table. */ |
163 | imap4d_sync_flags (pclos.set[i]); | 163 | imap4d_sync_flags (pclos.set[i]); | ... | ... |
... | @@ -270,6 +270,12 @@ util_msgset (char *s, size_t ** set, int *n, int isuid) | ... | @@ -270,6 +270,12 @@ util_msgset (char *s, size_t ** set, int *n, int isuid) |
270 | } | 270 | } |
271 | 271 | ||
272 | int | 272 | int |
273 | util_copy_out (mu_stream_t str, size_t size) | ||
274 | { | ||
275 | return mu_stream_copy (ostream, str, size); | ||
276 | } | ||
277 | |||
278 | int | ||
273 | util_send_bytes (const char *buf, size_t size) | 279 | util_send_bytes (const char *buf, size_t size) |
274 | { | 280 | { |
275 | return mu_stream_write (ostream, buf, size, NULL); | 281 | return mu_stream_write (ostream, buf, size, NULL); |
... | @@ -325,7 +331,7 @@ util_send_qstring (const char *buffer) | ... | @@ -325,7 +331,7 @@ util_send_qstring (const char *buffer) |
325 | int | 331 | int |
326 | util_send_literal (const char *buffer) | 332 | util_send_literal (const char *buffer) |
327 | { | 333 | { |
328 | return util_send ("{%lu}\r\n%s", (unsigned long) strlen (buffer), buffer); | 334 | return util_send ("{%lu}\n%s", (unsigned long) strlen (buffer), buffer); |
329 | } | 335 | } |
330 | 336 | ||
331 | /* Send an unsolicited response. */ | 337 | /* Send an unsolicited response. */ |
... | @@ -337,7 +343,7 @@ util_out (int rc, const char *format, ...) | ... | @@ -337,7 +343,7 @@ util_out (int rc, const char *format, ...) |
337 | int status = 0; | 343 | int status = 0; |
338 | va_list ap; | 344 | va_list ap; |
339 | 345 | ||
340 | asprintf (&tempbuf, "* %s%s\r\n", sc2string (rc), format); | 346 | asprintf (&tempbuf, "* %s%s\n", sc2string (rc), format); |
341 | va_start (ap, format); | 347 | va_start (ap, format); |
342 | vasprintf (&buf, tempbuf, ap); | 348 | vasprintf (&buf, tempbuf, ap); |
343 | va_end (ap); | 349 | va_end (ap); |
... | @@ -346,7 +352,7 @@ util_out (int rc, const char *format, ...) | ... | @@ -346,7 +352,7 @@ util_out (int rc, const char *format, ...) |
346 | 352 | ||
347 | if (imap4d_transcript) | 353 | if (imap4d_transcript) |
348 | { | 354 | { |
349 | int len = strcspn (buf, "\r\n"); | 355 | int len = strcspn (buf, "\n"); |
350 | mu_diag_output (MU_DIAG_DEBUG, "sent: %*.*s", len, len, buf); | 356 | mu_diag_output (MU_DIAG_DEBUG, "sent: %*.*s", len, len, buf); |
351 | } | 357 | } |
352 | 358 | ||
... | @@ -393,7 +399,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) | ... | @@ -393,7 +399,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...) |
393 | 399 | ||
394 | mu_stream_write (ostream, buf, strlen (buf), NULL); | 400 | mu_stream_write (ostream, buf, strlen (buf), NULL); |
395 | free (buf); | 401 | free (buf); |
396 | mu_stream_write (ostream, "\r\n", 2, NULL); | 402 | mu_stream_write (ostream, "\n", 2, NULL); |
397 | 403 | ||
398 | /* Reset the state. */ | 404 | /* Reset the state. */ |
399 | if (rc == RESP_OK) | 405 | if (rc == RESP_OK) |
... | @@ -800,16 +806,24 @@ util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp) | ... | @@ -800,16 +806,24 @@ util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp) |
800 | void | 806 | void |
801 | util_setio (FILE *in, FILE *out) | 807 | util_setio (FILE *in, FILE *out) |
802 | { | 808 | { |
809 | mu_stream_t tmp; | ||
810 | |||
803 | if (!in) | 811 | if (!in) |
804 | imap4d_bye (ERR_NO_IFILE); | 812 | imap4d_bye (ERR_NO_IFILE); |
805 | if (!out) | 813 | if (!out) |
806 | imap4d_bye (ERR_NO_OFILE); | 814 | imap4d_bye (ERR_NO_OFILE); |
807 | 815 | ||
808 | if (mu_stdio_stream_create (&istream, fileno (in), MU_STREAM_NO_CLOSE)) | 816 | if (mu_stdio_stream_create (&tmp, fileno (in), MU_STREAM_NO_CLOSE)) |
809 | imap4d_bye (ERR_NO_IFILE); | 817 | imap4d_bye (ERR_NO_IFILE); |
810 | if (mu_stdio_stream_create (&ostream, fileno (out), MU_STREAM_NO_CLOSE)) | 818 | mu_stream_set_buffer (tmp, mu_buffer_line, 1024); |
811 | imap4d_bye (ERR_NO_OFILE); | 819 | mu_filter_create (&istream, tmp, "rfc822", MU_FILTER_DECODE, MU_STREAM_READ); |
812 | mu_stream_set_buffer (istream, mu_buffer_line, 1024); | 820 | mu_stream_set_buffer (istream, mu_buffer_line, 1024); |
821 | |||
822 | if (mu_stdio_stream_create (&tmp, fileno (out), MU_STREAM_NO_CLOSE)) | ||
823 | imap4d_bye (ERR_NO_OFILE); | ||
824 | mu_stream_set_buffer (tmp, mu_buffer_line, 1024); | ||
825 | mu_filter_create (&ostream, tmp, "rfc822", MU_FILTER_ENCODE, | ||
826 | MU_STREAM_WRITE); | ||
813 | mu_stream_set_buffer (ostream, mu_buffer_line, 1024); | 827 | mu_stream_set_buffer (ostream, mu_buffer_line, 1024); |
814 | } | 828 | } |
815 | 829 | ||
... | @@ -917,7 +931,7 @@ void | ... | @@ -917,7 +931,7 @@ void |
917 | util_bye () | 931 | util_bye () |
918 | { | 932 | { |
919 | int rc = istream != ostream; | 933 | int rc = istream != ostream; |
920 | 934 | ||
921 | mu_stream_close (istream); | 935 | mu_stream_close (istream); |
922 | mu_stream_destroy (&istream); | 936 | mu_stream_destroy (&istream); |
923 | 937 | ||
... | @@ -926,7 +940,6 @@ util_bye () | ... | @@ -926,7 +940,6 @@ util_bye () |
926 | mu_stream_close (ostream); | 940 | mu_stream_close (ostream); |
927 | mu_stream_destroy (&ostream); | 941 | mu_stream_destroy (&ostream); |
928 | } | 942 | } |
929 | |||
930 | mu_list_do (atexit_list, atexit_run, 0); | 943 | mu_list_do (atexit_list, atexit_run, 0); |
931 | } | 944 | } |
932 | 945 | ||
... | @@ -1021,30 +1034,6 @@ is_atom (const char *s) | ... | @@ -1021,30 +1034,6 @@ is_atom (const char *s) |
1021 | 1034 | ||
1022 | 1035 | ||
1023 | static size_t | 1036 | static size_t |
1024 | remove_cr (char *line, size_t len) | ||
1025 | { | ||
1026 | char *prev = NULL; | ||
1027 | size_t rlen = len; | ||
1028 | char *p; | ||
1029 | while ((p = memchr (line, '\r', len))) | ||
1030 | { | ||
1031 | if (prev) | ||
1032 | { | ||
1033 | memmove (prev, line, p - line); | ||
1034 | prev += p - line; | ||
1035 | } | ||
1036 | else | ||
1037 | prev = p; | ||
1038 | rlen--; | ||
1039 | len -= p - line + 1; | ||
1040 | line = p + 1; | ||
1041 | } | ||
1042 | if (prev) | ||
1043 | memmove (prev, line, len); | ||
1044 | return rlen; | ||
1045 | } | ||
1046 | |||
1047 | static size_t | ||
1048 | unquote (char *line, size_t len) | 1037 | unquote (char *line, size_t len) |
1049 | { | 1038 | { |
1050 | char *prev = NULL; | 1039 | char *prev = NULL; |
... | @@ -1318,7 +1307,7 @@ imap4d_readline (struct imap4d_tokbuf *tok) | ... | @@ -1318,7 +1307,7 @@ imap4d_readline (struct imap4d_tokbuf *tok) |
1318 | /* Client can ask for non-synchronised literal, | 1307 | /* Client can ask for non-synchronised literal, |
1319 | if a '+' is appended to the octet count. */ | 1308 | if a '+' is appended to the octet count. */ |
1320 | if (*sp == '}') | 1309 | if (*sp == '}') |
1321 | util_send ("+ GO AHEAD\r\n"); | 1310 | util_send ("+ GO AHEAD\n"); |
1322 | else if (*sp != '+') | 1311 | else if (*sp != '+') |
1323 | break; | 1312 | break; |
1324 | imap4d_tokbuf_expand (tok, number + 1); | 1313 | imap4d_tokbuf_expand (tok, number + 1); |
... | @@ -1334,7 +1323,6 @@ imap4d_readline (struct imap4d_tokbuf *tok) | ... | @@ -1334,7 +1323,6 @@ imap4d_readline (struct imap4d_tokbuf *tok) |
1334 | len += sz; | 1323 | len += sz; |
1335 | } | 1324 | } |
1336 | check_input_err (rc, len); | 1325 | check_input_err (rc, len); |
1337 | len = remove_cr (buf, len); | ||
1338 | imap4d_tokbuf_unquote (tok, &off, &len); | 1326 | imap4d_tokbuf_unquote (tok, &off, &len); |
1339 | tok->level += len; | 1327 | tok->level += len; |
1340 | tok->buffer[tok->level++] = 0; | 1328 | tok->buffer[tok->level++] = 0; | ... | ... |
-
Please register or sign in to post a comment