Fix input operations and RFC-compliance in imap4d.
* imap4d/util.c (util_getword, util_getitem, util_token) (util_unquote): Remove. (imap4d_readline): Rewrite to reduce memory reallocation. Add support for non-synchronizing literals (RFC 2088). (imap4d_readline_ex): Remove. (util_do_command): Rewrite using new imap4d_readline. (util_parse_internal_date0): Remove. (imap4d_tokbuf_init, imap4d_tokbuf_destroy, imap4d_tokbuf_argc) (imap4d_tokbuf_getarg, util_isdelim) (imap4d_tokbuf_from_string): New functions. * imap4d/append.c, imap4d/auth_gss.c, imap4d/authenticate.c, imap4d/check.c, imap4d/close.c, imap4d/commands.c, imap4d/copy.c, imap4d/create.c, imap4d/delete.c, imap4d/examine.c, imap4d/imap4d.h, imap4d/list.c, imap4d/login.c, imap4d/logout.c, imap4d/lsub.c, imap4d/expunge.c, imap4d/idle.c, imap4d/noop.c, imap4d/rename.c, imap4d/search.c, imap4d/select.c, imap4d/starttls.c, imap4d/status.c, imap4d/store.c, imap4d/subscribe.c, imap4d/uid.c, imap4d/unsubscribe.c, imap4d/version.c: Rewrite using new imap4d_readline. * imap4d/namespace.c: Use new imap4d_readline. Ensure that each reported prefix ends with a hierarchy delimiter. * imap4d/imap4d.c (imap4d_mainloop): Use new imap4d_readline. * imap4d/fetch.c: Rewrite parser from scratch. * imap4d/capability.c (imap4d_capability_init): Report LITERAL+ capability. * imap4d/testsuite/imap4d/anystate.exp: Account for the LITERAL+ capability. * imap4d/testsuite/imap4d/append.exp: Fix APPEND arguments (imap4d requires exactly three arguments, as per RFC3501. Fix octet count in literals returned by fetch (previous versions failed to include the trailing CRLF). * imap4d/testsuite/imap4d/create.exp: Likewise. * imap4d/testsuite/imap4d/fetch.exp: Fix FETCH arguments (previous versions incorrectly accepted header-list without parentheses. Fix result of FETCH 4 BODY[2.2.1]: it returns entire part, in the contrast to previous versions, which treated it as BODY[2.2.1.TEXT]. * maidag/mailtmp.c (mail_tmp_finish): Ensure /dev/null is treated as mailbox.
Showing
40 changed files
with
765 additions
and
487 deletions
1 | 2008-08-11 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | Fix input operations and RFC-compliance in imap4d. | ||
4 | |||
5 | * imap4d/util.c (util_getword, util_getitem, util_token) | ||
6 | (util_unquote): Remove. | ||
7 | (imap4d_readline): Rewrite to reduce memory reallocation. Add | ||
8 | support for non-synchronizing literals (RFC 2088). | ||
9 | (imap4d_readline_ex): Remove. | ||
10 | (util_do_command): Rewrite using new imap4d_readline. | ||
11 | (util_parse_internal_date0): Remove. | ||
12 | (imap4d_tokbuf_init, imap4d_tokbuf_destroy, imap4d_tokbuf_argc) | ||
13 | (imap4d_tokbuf_getarg, util_isdelim) | ||
14 | (imap4d_tokbuf_from_string): New functions. | ||
15 | * imap4d/append.c, imap4d/auth_gss.c, imap4d/authenticate.c, | ||
16 | imap4d/check.c, imap4d/close.c, imap4d/commands.c, imap4d/copy.c, | ||
17 | imap4d/create.c, imap4d/delete.c, imap4d/examine.c, | ||
18 | imap4d/imap4d.h, imap4d/list.c, imap4d/login.c, imap4d/logout.c, | ||
19 | imap4d/lsub.c, imap4d/expunge.c, imap4d/idle.c, imap4d/noop.c, | ||
20 | imap4d/rename.c, imap4d/search.c, imap4d/select.c, | ||
21 | imap4d/starttls.c, imap4d/status.c, imap4d/store.c, | ||
22 | imap4d/subscribe.c, imap4d/uid.c, imap4d/unsubscribe.c, | ||
23 | imap4d/version.c: Rewrite using new imap4d_readline. | ||
24 | * imap4d/namespace.c: Use new imap4d_readline. Ensure that | ||
25 | each reported prefix ends with a hierarchy delimiter. | ||
26 | * imap4d/imap4d.c (imap4d_mainloop): Use new imap4d_readline. | ||
27 | * imap4d/fetch.c: Rewrite parser from scratch. | ||
28 | * imap4d/capability.c (imap4d_capability_init): Report LITERAL+ | ||
29 | capability. | ||
30 | |||
31 | * imap4d/testsuite/imap4d/anystate.exp: Account for the LITERAL+ | ||
32 | capability. | ||
33 | * imap4d/testsuite/imap4d/append.exp: Fix APPEND arguments (imap4d | ||
34 | requires exactly three arguments, as per RFC3501. | ||
35 | Fix octet count in literals returned by fetch (previous versions | ||
36 | failed to include the trailing CRLF). | ||
37 | * imap4d/testsuite/imap4d/create.exp: Likewise. | ||
38 | * imap4d/testsuite/imap4d/fetch.exp: Fix FETCH arguments (previous | ||
39 | versions incorrectly accepted header-list without parentheses. | ||
40 | Fix result of FETCH 4 BODY[2.2.1]: it returns entire part, in the | ||
41 | contrast to previous versions, which treated it as | ||
42 | BODY[2.2.1.TEXT]. | ||
43 | |||
44 | * maidag/mailtmp.c (mail_tmp_finish): Ensure /dev/null is treated | ||
45 | as mailbox. | ||
46 | |||
1 | 2008-08-08 Sergey Poznyakoff <gray@gnu.org.ua> | 47 | 2008-08-08 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 48 | ||
3 | Fix imap appends for AMD mailboxes. | 49 | Fix imap appends for AMD mailboxes. | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2006, 2007, |
3 | 2008 Free Software Foundation, Inc. | ||
3 | 4 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -18,49 +19,6 @@ | ... | @@ -18,49 +19,6 @@ |
18 | 19 | ||
19 | #include "imap4d.h" | 20 | #include "imap4d.h" |
20 | 21 | ||
21 | /* APPEND mbox [(flags)] [date_time] message_literal */ | ||
22 | int | ||
23 | imap4d_append (struct imap4d_command *command, char *arg) | ||
24 | { | ||
25 | char *sp; | ||
26 | char *mboxname; | ||
27 | int flags = 0; | ||
28 | mu_mailbox_t dest_mbox = NULL; | ||
29 | int status; | ||
30 | |||
31 | mboxname = util_getword (arg, &sp); | ||
32 | if (!mboxname) | ||
33 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
34 | |||
35 | util_unquote (&mboxname); | ||
36 | |||
37 | if (*sp == '(' && util_parse_attributes (sp+1, &sp, &flags)) | ||
38 | return util_finish (command, RESP_BAD, "Missing closing parenthesis"); | ||
39 | |||
40 | mboxname = namespace_getfullpath (mboxname, "/"); | ||
41 | if (!mboxname) | ||
42 | return util_finish (command, RESP_NO, "Couldn't open mailbox"); | ||
43 | |||
44 | status = mu_mailbox_create_default (&dest_mbox, mboxname); | ||
45 | if (status == 0) | ||
46 | { | ||
47 | /* It SHOULD NOT automatifcllly create the mailbox. */ | ||
48 | status = mu_mailbox_open (dest_mbox, MU_STREAM_RDWR); | ||
49 | if (status == 0) | ||
50 | { | ||
51 | status = imap4d_append0 (dest_mbox, flags, sp); | ||
52 | mu_mailbox_close (dest_mbox); | ||
53 | } | ||
54 | mu_mailbox_destroy (&dest_mbox); | ||
55 | } | ||
56 | |||
57 | free (mboxname); | ||
58 | if (status == 0) | ||
59 | return util_finish (command, RESP_OK, "Completed"); | ||
60 | |||
61 | return util_finish (command, RESP_NO, "[TRYCREATE] failed"); | ||
62 | } | ||
63 | |||
64 | static int | 22 | static int |
65 | _append_date (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) | 23 | _append_date (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite) |
66 | { | 24 | { |
... | @@ -93,12 +51,18 @@ _append_size (mu_message_t msg, size_t *psize) | ... | @@ -93,12 +51,18 @@ _append_size (mu_message_t msg, size_t *psize) |
93 | mu_stream_t str; | 51 | mu_stream_t str; |
94 | int status = mu_message_get_stream (msg, &str); | 52 | int status = mu_message_get_stream (msg, &str); |
95 | if (status == 0) | 53 | if (status == 0) |
96 | status = mu_stream_size (str, psize); | 54 | { |
55 | mu_off_t size; | ||
56 | status = mu_stream_size (str, &size); | ||
57 | if (status == 0 && psize) | ||
58 | *psize = size; | ||
59 | } | ||
97 | return status; | 60 | return status; |
98 | } | 61 | } |
99 | 62 | ||
100 | int | 63 | int |
101 | imap4d_append0 (mu_mailbox_t mbox, int flags, char *text) | 64 | imap4d_append0 (mu_mailbox_t mbox, int flags, char *date_time, char *text, |
65 | char **err_text) | ||
102 | { | 66 | { |
103 | mu_stream_t stream; | 67 | mu_stream_t stream; |
104 | int rc = 0; | 68 | int rc = 0; |
... | @@ -118,23 +82,25 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text) | ... | @@ -118,23 +82,25 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text) |
118 | return 1; | 82 | return 1; |
119 | } | 83 | } |
120 | 84 | ||
121 | while (*text && isspace (*text)) | ||
122 | text++; | ||
123 | |||
124 | /* If a date_time is specified, the internal date SHOULD be set in the | 85 | /* If a date_time is specified, the internal date SHOULD be set in the |
125 | resulting message; otherwise, the internal date of the resulting | 86 | resulting message; otherwise, the internal date of the resulting |
126 | message is set to the current date and time by default. */ | 87 | message is set to the current date and time by default. */ |
127 | if (util_parse_internal_date0 (text, &t, &text) == 0) | 88 | if (date_time) |
128 | { | 89 | { |
129 | while (*text && isspace(*text)) | 90 | if (util_parse_internal_date (date_time, &t)) |
130 | text++; | 91 | { |
92 | *err_text = "Invalid date/time format"; | ||
93 | return 1; | ||
94 | } | ||
131 | } | 95 | } |
132 | else | 96 | else |
133 | { | 97 | time(&t); |
134 | time(&t); | 98 | |
135 | } | ||
136 | tm = gmtime(&t); | 99 | tm = gmtime(&t); |
137 | 100 | ||
101 | while (*text && isspace (*text)) | ||
102 | text++; | ||
103 | |||
138 | mu_stream_write (stream, text, strlen (text), len, &len); | 104 | mu_stream_write (stream, text, strlen (text), len, &len); |
139 | mu_message_set_stream (msg, stream, &tm); | 105 | mu_message_set_stream (msg, stream, &tm); |
140 | mu_message_set_size (msg, _append_size, &tm); | 106 | mu_message_set_size (msg, _append_size, &tm); |
... | @@ -158,4 +124,87 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text) | ... | @@ -158,4 +124,87 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text) |
158 | return rc; | 124 | return rc; |
159 | } | 125 | } |
160 | 126 | ||
127 | |||
128 | /* APPEND mbox [(flags)] [date_time] message_literal */ | ||
129 | int | ||
130 | imap4d_append (struct imap4d_command *command, imap4d_tokbuf_t tok) | ||
131 | { | ||
132 | int i; | ||
133 | char *mboxname; | ||
134 | int flags = 0; | ||
135 | mu_mailbox_t dest_mbox = NULL; | ||
136 | int status; | ||
137 | int argc = imap4d_tokbuf_argc (tok); | ||
138 | char *date_time; | ||
139 | char *msg_text; | ||
140 | char *err_text = "[TRYCREATE] failed"; | ||
141 | |||
142 | if (argc < 4) | ||
143 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
144 | |||
145 | mboxname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); | ||
146 | if (!mboxname) | ||
147 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
148 | |||
149 | i = IMAP4_ARG_2; | ||
150 | if (imap4d_tokbuf_getarg (tok, i)[0] == '(') | ||
151 | { | ||
152 | while (++i < argc) | ||
153 | { | ||
154 | int type; | ||
155 | char *arg = imap4d_tokbuf_getarg (tok, i); | ||
156 | |||
157 | if (!util_attribute_to_type (arg, &type)) | ||
158 | flags |= type; | ||
159 | else if (arg[0] == ')') | ||
160 | break; | ||
161 | } | ||
162 | if (i == argc) | ||
163 | return util_finish (command, RESP_BAD, "Missing closing parenthesis"); | ||
164 | i++; | ||
165 | } | ||
166 | |||
167 | switch (argc - i) | ||
168 | { | ||
169 | case 2: | ||
170 | /* Date/time is present */ | ||
171 | date_time = imap4d_tokbuf_getarg (tok, i); | ||
172 | i++; | ||
173 | break; | ||
174 | |||
175 | case 1: | ||
176 | date_time = NULL; | ||
177 | break; | ||
178 | |||
179 | default: | ||
180 | return util_finish (command, RESP_BAD, "Too many arguments"); | ||
181 | } | ||
182 | |||
183 | msg_text = imap4d_tokbuf_getarg (tok, i); | ||
184 | |||
185 | mboxname = namespace_getfullpath (mboxname, "/"); | ||
186 | if (!mboxname) | ||
187 | return util_finish (command, RESP_NO, "Couldn't open mailbox"); | ||
188 | |||
189 | status = mu_mailbox_create_default (&dest_mbox, mboxname); | ||
190 | if (status == 0) | ||
191 | { | ||
192 | /* It SHOULD NOT automatically create the mailbox. */ | ||
193 | status = mu_mailbox_open (dest_mbox, MU_STREAM_RDWR); | ||
194 | if (status == 0) | ||
195 | { | ||
196 | status = imap4d_append0 (dest_mbox, flags, date_time, msg_text, | ||
197 | &err_text); | ||
198 | mu_mailbox_close (dest_mbox); | ||
199 | } | ||
200 | mu_mailbox_destroy (&dest_mbox); | ||
201 | } | ||
202 | |||
203 | free (mboxname); | ||
204 | if (status == 0) | ||
205 | return util_finish (command, RESP_OK, "Completed"); | ||
206 | |||
207 | return util_finish (command, RESP_NO, err_text); | ||
208 | } | ||
209 | |||
161 | 210 | ... | ... |
... | @@ -119,7 +119,9 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -119,7 +119,9 @@ auth_gssapi (struct imap4d_command *command, |
119 | gss_ctx_id_t context; | 119 | gss_ctx_id_t context; |
120 | gss_cred_id_t cred_handle, server_creds; | 120 | gss_cred_id_t cred_handle, server_creds; |
121 | gss_OID mech_type; | 121 | gss_OID mech_type; |
122 | char *token_str; | 122 | char *token_str = NULL; |
123 | size_t token_size = 0; | ||
124 | size_t token_len; | ||
123 | unsigned char *tmp = NULL; | 125 | unsigned char *tmp = NULL; |
124 | size_t size; | 126 | size_t size; |
125 | gss_name_t server_name; | 127 | gss_name_t server_name; |
... | @@ -168,11 +170,10 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -168,11 +170,10 @@ auth_gssapi (struct imap4d_command *command, |
168 | 170 | ||
169 | for (;;) | 171 | for (;;) |
170 | { | 172 | { |
171 | token_str = imap4d_readline_ex (); | 173 | imap4d_getline (&token_str, &token_size, &token_len); |
172 | util_base64_decode (token_str, strlen (token_str), &tmp, &size); | 174 | util_base64_decode (token_str, token_len, &tmp, &size); |
173 | tokbuf.value = tmp; | 175 | tokbuf.value = tmp; |
174 | tokbuf.length = size; | 176 | tokbuf.length = size; |
175 | free (token_str); | ||
176 | 177 | ||
177 | maj_stat = gss_accept_sec_context (&min_stat, | 178 | maj_stat = gss_accept_sec_context (&min_stat, |
178 | &context, | 179 | &context, |
... | @@ -202,6 +203,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -202,6 +203,7 @@ auth_gssapi (struct imap4d_command *command, |
202 | display_status ("accept context", maj_stat, min_stat); | 203 | display_status ("accept context", maj_stat, min_stat); |
203 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); | 204 | maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf); |
204 | gss_release_buffer (&min_stat, &outbuf); | 205 | gss_release_buffer (&min_stat, &outbuf); |
206 | free (token_str); | ||
205 | return RESP_NO; | 207 | return RESP_NO; |
206 | } | 208 | } |
207 | 209 | ||
... | @@ -211,8 +213,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -211,8 +213,7 @@ auth_gssapi (struct imap4d_command *command, |
211 | util_send ("+ %*.*s\r\n", size, size, tmp); | 213 | util_send ("+ %*.*s\r\n", size, size, tmp); |
212 | free (tmp); | 214 | free (tmp); |
213 | gss_release_buffer (&min_stat, &outbuf); | 215 | gss_release_buffer (&min_stat, &outbuf); |
214 | token_str = imap4d_readline_ex (); | 216 | imap4d_getline (&token_str, &token_size, &token_len); |
215 | free (token_str); | ||
216 | } | 217 | } |
217 | 218 | ||
218 | /* Construct security-level data */ | 219 | /* Construct security-level data */ |
... | @@ -224,6 +225,7 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -224,6 +225,7 @@ auth_gssapi (struct imap4d_command *command, |
224 | if (maj_stat != GSS_S_COMPLETE) | 225 | if (maj_stat != GSS_S_COMPLETE) |
225 | { | 226 | { |
226 | display_status ("wrap", maj_stat, min_stat); | 227 | display_status ("wrap", maj_stat, min_stat); |
228 | free (token_str); | ||
227 | return RESP_NO; | 229 | return RESP_NO; |
228 | } | 230 | } |
229 | 231 | ||
... | @@ -231,8 +233,8 @@ auth_gssapi (struct imap4d_command *command, | ... | @@ -231,8 +233,8 @@ auth_gssapi (struct imap4d_command *command, |
231 | util_send ("+ %*.*s\r\n", size, size, tmp); | 233 | util_send ("+ %*.*s\r\n", size, size, tmp); |
232 | free (tmp); | 234 | free (tmp); |
233 | 235 | ||
234 | token_str = imap4d_readline_ex (); | 236 | imap4d_getline (&token_str, &token_size, &token_len); |
235 | util_base64_decode (token_str, strlen (token_str), | 237 | util_base64_decode (token_str, token_len, |
236 | (unsigned char **) &tokbuf.value, &tokbuf.length); | 238 | (unsigned char **) &tokbuf.value, &tokbuf.length); |
237 | free (token_str); | 239 | free (token_str); |
238 | 240 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2006, 2007, |
3 | 2008 Free Software Foundation, Inc. | ||
3 | 4 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -93,24 +94,30 @@ imap4d_auth_capability () | ... | @@ -93,24 +94,30 @@ imap4d_auth_capability () |
93 | mu_list_do (imap_auth_list, _auth_capa, NULL); | 94 | mu_list_do (imap_auth_list, _auth_capa, NULL); |
94 | } | 95 | } |
95 | 96 | ||
97 | /* | ||
98 | 6.2.1. AUTHENTICATE Command | ||
99 | |||
100 | Arguments: authentication mechanism name | ||
101 | */ | ||
102 | |||
96 | int | 103 | int |
97 | imap4d_authenticate (struct imap4d_command *command, char *arg) | 104 | imap4d_authenticate (struct imap4d_command *command, imap4d_tokbuf_t tok) |
98 | { | 105 | { |
99 | char *sp = NULL; | ||
100 | char *auth_type; | 106 | char *auth_type; |
101 | struct auth_data adata; | 107 | struct auth_data adata; |
108 | |||
109 | if (imap4d_tokbuf_argc (tok) != 3) | ||
110 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
102 | 111 | ||
103 | auth_type = util_getword (arg, &sp); | 112 | auth_type = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
104 | util_unquote (&auth_type); | ||
105 | if (!auth_type) | ||
106 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
107 | 113 | ||
108 | if (tls_required) | 114 | if (tls_required) |
109 | return util_finish (command, RESP_NO, "Command disabled: Use STARTTLS first"); | 115 | return util_finish (command, RESP_NO, |
116 | "Command disabled: Use STARTTLS first"); | ||
110 | 117 | ||
111 | adata.command = command; | 118 | adata.command = command; |
112 | adata.auth_type = auth_type; | 119 | adata.auth_type = auth_type; |
113 | adata.arg = sp; | 120 | adata.arg = NULL; |
114 | adata.username = NULL; | 121 | adata.username = NULL; |
115 | 122 | ||
116 | if (mu_list_do (imap_auth_list, _auth_try, &adata) == 0) | 123 | if (mu_list_do (imap_auth_list, _auth_try, &adata) == 0) | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2003, 2005, 2007, |
3 | 2008 Free Software Foundation, Inc. | ||
3 | 4 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -50,6 +51,7 @@ imap4d_capability_init () | ... | @@ -50,6 +51,7 @@ imap4d_capability_init () |
50 | "IMAP4rev1", | 51 | "IMAP4rev1", |
51 | "NAMESPACE", | 52 | "NAMESPACE", |
52 | "IDLE", | 53 | "IDLE", |
54 | "LITERAL+", | ||
53 | "X-VERSION", | 55 | "X-VERSION", |
54 | NULL | 56 | NULL |
55 | }; | 57 | }; |
... | @@ -67,8 +69,11 @@ print_capa (void *item, void *data) | ... | @@ -67,8 +69,11 @@ print_capa (void *item, void *data) |
67 | } | 69 | } |
68 | 70 | ||
69 | int | 71 | int |
70 | imap4d_capability (struct imap4d_command *command, char *arg MU_ARG_UNUSED) | 72 | imap4d_capability (struct imap4d_command *command, imap4d_tokbuf_t tok) |
71 | { | 73 | { |
74 | if (imap4d_tokbuf_argc (tok) != 2) | ||
75 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
76 | |||
72 | util_send ("* CAPABILITY"); | 77 | util_send ("* CAPABILITY"); |
73 | 78 | ||
74 | mu_list_do (capa_list, print_capa, NULL); | 79 | mu_list_do (capa_list, print_capa, NULL); | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,13 +19,20 @@ | ... | @@ -19,13 +19,20 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Do we need to do anything here? | 22 | 6.4.1. CHECK Command |
23 | * FIXME: This is like noop we need to notify the client of | 23 | |
24 | * new mails etc ... and do housekeeping. | 24 | Arguments: none |
25 | */ | 25 | |
26 | Responses: no specific responses for this command | ||
27 | |||
28 | Result: OK - check completed | ||
29 | BAD - command unknown or arguments invalid | ||
30 | */ | ||
26 | 31 | ||
27 | int | 32 | int |
28 | imap4d_check (struct imap4d_command *command, char *arg MU_ARG_UNUSED) | 33 | imap4d_check (struct imap4d_command *command, imap4d_tokbuf_t tok) |
29 | { | 34 | { |
35 | if (imap4d_tokbuf_argc (tok) != 2) | ||
36 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
30 | return util_finish (command, RESP_OK, "Completed"); | 37 | return util_finish (command, RESP_OK, "Completed"); |
31 | } | 38 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2004, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2004, 2005, 2007, |
3 | 2008 Free Software Foundation, Inc. | ||
3 | 4 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -19,16 +20,27 @@ | ... | @@ -19,16 +20,27 @@ |
19 | #include "imap4d.h" | 20 | #include "imap4d.h" |
20 | 21 | ||
21 | /* | 22 | /* |
22 | */ | 23 | 6.4.2. CLOSE Command |
23 | 24 | ||
24 | /* The CLOSE command permanently removes from the currently selected | 25 | Arguments: none |
26 | |||
27 | Responses: no specific responses for this command | ||
28 | |||
29 | Result: OK - close completed, now in authenticated state | ||
30 | NO - close failure: no mailbox selected | ||
31 | BAD - command unknown or arguments invalid | ||
32 | |||
33 | The CLOSE command permanently removes from the currently selected | ||
25 | mailbox all messages that have the \\Deleted flag set, and returns | 34 | mailbox all messages that have the \\Deleted flag set, and returns |
26 | to authenticated state from selected state. */ | 35 | to authenticated state from selected state. */ |
27 | int | 36 | int |
28 | imap4d_close (struct imap4d_command *command, char *arg MU_ARG_UNUSED) | 37 | imap4d_close (struct imap4d_command *command, imap4d_tokbuf_t tok) |
29 | { | 38 | { |
30 | const char *msg = NULL; | 39 | const char *msg = NULL; |
31 | int status, flags; | 40 | int status, flags; |
41 | |||
42 | if (imap4d_tokbuf_argc (tok) != 2) | ||
43 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
32 | 44 | ||
33 | mu_mailbox_get_flags (mbox, &flags); | 45 | mu_mailbox_get_flags (mbox, &flags); |
34 | if ((flags & MU_STREAM_READ) == 0) | 46 | if ((flags & MU_STREAM_READ) == 0) | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2003, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2003, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,55 +19,69 @@ | ... | @@ -19,55 +19,69 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * copy messages in argv[2] to mailbox in argv[3] | 22 | 6.4.7. COPY Command |
23 | |||
24 | Arguments: message set | ||
25 | mailbox name | ||
26 | |||
27 | Responses: no specific responses for this command | ||
28 | |||
29 | Result: OK - copy completed | ||
30 | NO - copy error: can't copy those messages or to that | ||
31 | name | ||
32 | BAD - command unknown or arguments invalid | ||
33 | |||
34 | copy messages in argv[2] to mailbox in argv[3] | ||
23 | */ | 35 | */ |
24 | 36 | ||
25 | int | 37 | int |
26 | imap4d_copy (struct imap4d_command *command, char *arg) | 38 | imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 39 | { |
28 | int rc; | 40 | int rc; |
29 | char buffer[64]; | 41 | char *text; |
30 | 42 | ||
31 | rc = imap4d_copy0 (arg, 0, buffer, sizeof buffer); | 43 | if (imap4d_tokbuf_argc (tok) != 4) |
44 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
45 | |||
46 | rc = imap4d_copy0 (tok, 0, &text); | ||
47 | |||
32 | if (rc == RESP_NONE) | 48 | if (rc == RESP_NONE) |
33 | { | 49 | { |
34 | /* Reset the state ourself. */ | 50 | /* Reset the state ourself. */ |
35 | int new_state = (rc == RESP_OK) ? command->success : command->failure; | 51 | int new_state = (rc == RESP_OK) ? command->success : command->failure; |
36 | if (new_state != STATE_NONE) | 52 | if (new_state != STATE_NONE) |
37 | state = new_state; | 53 | state = new_state; |
38 | return util_send ("%s %s\r\n", command->tag, buffer); | 54 | return util_send ("%s %s\r\n", command->tag, text); |
39 | } | 55 | } |
40 | return util_finish (command, rc, "%s", buffer); | 56 | return util_finish (command, rc, "%s", text); |
41 | } | 57 | } |
42 | 58 | ||
43 | int | 59 | int |
44 | imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) | 60 | imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
45 | { | 61 | { |
46 | int status; | 62 | int status; |
47 | char *msgset; | 63 | char *msgset; |
48 | char *name; | 64 | char *name; |
49 | char *mailbox_name; | 65 | char *mailbox_name; |
50 | const char *delim = "/"; | 66 | const char *delim = "/"; |
51 | char *sp = NULL; | ||
52 | size_t *set = NULL; | 67 | size_t *set = NULL; |
53 | int n = 0; | 68 | int n = 0; |
54 | mu_mailbox_t cmbox = NULL; | 69 | mu_mailbox_t cmbox = NULL; |
70 | int arg = IMAP4_ARG_1 + !!isuid; | ||
55 | 71 | ||
56 | msgset = util_getword (arg, &sp); | 72 | if (imap4d_tokbuf_argc (tok) != arg + 2) |
57 | name = util_getword (NULL, &sp); | ||
58 | |||
59 | util_unquote (&name); | ||
60 | if (!msgset || !name || *name == '\0') | ||
61 | { | 73 | { |
62 | snprintf (resp, resplen, "Too few args"); | 74 | *err_text = "Invalid arguments"; |
63 | return RESP_BAD; | 75 | return 1; |
64 | } | 76 | } |
65 | 77 | ||
78 | msgset = imap4d_tokbuf_getarg (tok, arg); | ||
79 | name = imap4d_tokbuf_getarg (tok, arg + 1); | ||
66 | /* Get the message numbers in set[]. */ | 80 | /* Get the message numbers in set[]. */ |
67 | status = util_msgset (msgset, &set, &n, isuid); | 81 | status = util_msgset (msgset, &set, &n, isuid); |
68 | if (status != 0) | 82 | if (status != 0) |
69 | { | 83 | { |
70 | snprintf (resp, resplen, "Bogus number set"); | 84 | *err_text = "Bogus number set"; |
71 | return RESP_BAD; | 85 | return RESP_BAD; |
72 | } | 86 | } |
73 | 87 | ||
... | @@ -75,7 +89,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) | ... | @@ -75,7 +89,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) |
75 | 89 | ||
76 | if (!mailbox_name) | 90 | if (!mailbox_name) |
77 | { | 91 | { |
78 | snprintf (resp, resplen, "NO Create failed."); | 92 | *err_text = "NO Create failed."; |
79 | return RESP_NO; | 93 | return RESP_NO; |
80 | } | 94 | } |
81 | 95 | ||
... | @@ -105,7 +119,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) | ... | @@ -105,7 +119,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) |
105 | 119 | ||
106 | if (status == 0) | 120 | if (status == 0) |
107 | { | 121 | { |
108 | snprintf (resp, resplen, "Completed"); | 122 | *err_text = "Completed"; |
109 | return RESP_OK; | 123 | return RESP_OK; |
110 | } | 124 | } |
111 | 125 | ||
... | @@ -114,6 +128,6 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) | ... | @@ -114,6 +128,6 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen) |
114 | of the text of the tagged NO response. This gives a hint to the | 128 | of the text of the tagged NO response. This gives a hint to the |
115 | client that it can attempt a CREATE command and retry the copy if | 129 | client that it can attempt a CREATE command and retry the copy if |
116 | the CREATE is successful. */ | 130 | the CREATE is successful. */ |
117 | snprintf (resp, resplen, "NO [TRYCREATE] failed"); | 131 | *err_text = "NO [TRYCREATE] failed"; |
118 | return RESP_NONE; | 132 | return RESP_NONE; |
119 | } | 133 | } | ... | ... |
... | @@ -63,25 +63,34 @@ mkdir_p (char *name, int delim) | ... | @@ -63,25 +63,34 @@ mkdir_p (char *name, int delim) |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
66 | /* | ||
67 | 6.3.3. CREATE Command | ||
68 | |||
69 | Arguments: mailbox name | ||
70 | |||
71 | Responses: no specific responses for this command | ||
72 | |||
73 | Result: OK - create completed | ||
74 | NO - create failure: can't create mailbox with that name | ||
75 | BAD - command unknown or arguments invalid | ||
76 | */ | ||
66 | /* FIXME: How do we do this ??????: | 77 | /* FIXME: How do we do this ??????: |
67 | IF a new mailbox is created with the same name as a mailbox which was | 78 | IF a new mailbox is created with the same name as a mailbox which was |
68 | deleted, its unique identifiers MUST be greater than any unique identifiers | 79 | deleted, its unique identifiers MUST be greater than any unique identifiers |
69 | used in the previous incarnation of the mailbox. */ | 80 | used in the previous incarnation of the mailbox. */ |
70 | int | 81 | int |
71 | imap4d_create (struct imap4d_command *command, char *arg) | 82 | imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok) |
72 | { | 83 | { |
73 | char *name; | 84 | char *name; |
74 | char *sp = NULL; | ||
75 | const char *delim = "/"; | 85 | const char *delim = "/"; |
76 | int isdir = 0; | 86 | int isdir = 0; |
77 | int rc = RESP_OK; | 87 | int rc = RESP_OK; |
78 | const char *msg = "Completed"; | 88 | const char *msg = "Completed"; |
79 | 89 | ||
80 | name = util_getword (arg, &sp); | 90 | if (imap4d_tokbuf_argc (tok) != 3) |
81 | if (!name) | 91 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
82 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
83 | 92 | ||
84 | util_unquote (&name); | 93 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
85 | 94 | ||
86 | if (*name == '\0') | 95 | if (*name == '\0') |
87 | return util_finish (command, RESP_BAD, "Too few arguments"); | 96 | return util_finish (command, RESP_BAD, "Too few arguments"); |
... | @@ -152,6 +161,5 @@ imap4d_create (struct imap4d_command *command, char *arg) | ... | @@ -152,6 +161,5 @@ imap4d_create (struct imap4d_command *command, char *arg) |
152 | msg = "already exists"; | 161 | msg = "already exists"; |
153 | } | 162 | } |
154 | 163 | ||
155 | free (name); | ||
156 | return util_finish (command, rc, msg); | 164 | return util_finish (command, rc, msg); |
157 | } | 165 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,20 +19,27 @@ | ... | @@ -19,20 +19,27 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * | 22 | 6.3.4. DELETE Command |
23 | */ | ||
24 | 23 | ||
24 | Arguments: mailbox name | ||
25 | |||
26 | Responses: no specific responses for this command | ||
27 | |||
28 | Result: OK - delete completed | ||
29 | NO - delete failure: can't delete mailbox with that name | ||
30 | BAD - command unknown or arguments invalid | ||
31 | */ | ||
25 | int | 32 | int |
26 | imap4d_delete (struct imap4d_command *command, char *arg) | 33 | imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 34 | { |
28 | char *sp = NULL; | ||
29 | int rc = RESP_OK; | 35 | int rc = RESP_OK; |
30 | const char *msg = "Completed"; | 36 | const char *msg = "Completed"; |
31 | const char *delim = "/"; | 37 | const char *delim = "/"; |
32 | char *name; | 38 | char *name; |
33 | 39 | ||
34 | name = util_getword (arg, &sp); | 40 | if (imap4d_tokbuf_argc (tok) != 3) |
35 | util_unquote (&name); | 41 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
42 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); | ||
36 | if (!name || *name == '\0') | 43 | if (!name || *name == '\0') |
37 | return util_finish (command, RESP_BAD, "Too few arguments"); | 44 | return util_finish (command, RESP_BAD, "Too few arguments"); |
38 | 45 | ||
... | @@ -51,6 +58,5 @@ imap4d_delete (struct imap4d_command *command, char *arg) | ... | @@ -51,6 +58,5 @@ imap4d_delete (struct imap4d_command *command, char *arg) |
51 | rc = RESP_NO; | 58 | rc = RESP_NO; |
52 | msg = "Cannot remove"; | 59 | msg = "Cannot remove"; |
53 | } | 60 | } |
54 | free (name); | ||
55 | return util_finish (command, rc, msg); | 61 | return util_finish (command, rc, msg); |
56 | } | 62 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,11 +19,23 @@ | ... | @@ -19,11 +19,23 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * copy things from select.c | 22 | 6.3.2. EXAMINE Command |
23 | */ | ||
24 | 23 | ||
24 | Arguments: mailbox name | ||
25 | |||
26 | Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT | ||
27 | OPTIONAL OK untagged responses: UNSEEN, PERMANENTFLAGS | ||
28 | |||
29 | Result: OK - examine completed, now in selected state | ||
30 | NO - examine failure, now in authenticated state: no | ||
31 | such mailbox, can't access mailbox | ||
32 | BAD - command unknown or arguments invalid | ||
33 | */ | ||
25 | int | 34 | int |
26 | imap4d_examine (struct imap4d_command *command, char *arg) | 35 | imap4d_examine (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 36 | { |
28 | return imap4d_select0 (command, arg, MU_STREAM_READ); | 37 | if (imap4d_tokbuf_argc (tok) != 3) |
38 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
39 | return imap4d_select0 (command, imap4d_tokbuf_getarg (tok, IMAP4_ARG_1), | ||
40 | MU_STREAM_READ); | ||
29 | } | 41 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,16 +19,23 @@ | ... | @@ -19,16 +19,23 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * | 22 | 6.4.3. EXPUNGE Command |
23 | */ | 23 | |
24 | Arguments: none | ||
25 | |||
26 | Responses: untagged responses: EXPUNGE | ||
27 | |||
28 | Result: OK - expunge completed | ||
29 | NO - expunge failure: can't expunge (e.g. permission | ||
30 | denied) | ||
31 | BAD - command unknown or arguments invalid | ||
32 | */ | ||
24 | 33 | ||
25 | int | 34 | int |
26 | imap4d_expunge (struct imap4d_command *command, char *arg) | 35 | imap4d_expunge (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 36 | { |
28 | char *sp = NULL; | 37 | if (imap4d_tokbuf_argc (tok) != 2) |
29 | 38 | return util_finish (command, RESP_BAD, "Invalid arguments"); | |
30 | if (util_getword (arg, &sp)) | ||
31 | return util_finish (command, RESP_NO, "Too many args"); | ||
32 | 39 | ||
33 | /* FIXME: check for errors. */ | 40 | /* FIXME: check for errors. */ |
34 | mu_mailbox_expunge (mbox); | 41 | mu_mailbox_expunge (mbox); | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -19,13 +19,12 @@ | ... | @@ -19,13 +19,12 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | int | 21 | int |
22 | imap4d_idle (struct imap4d_command *command, char *arg) | 22 | imap4d_idle (struct imap4d_command *command, imap4d_tokbuf_t tok) |
23 | { | 23 | { |
24 | char *sp; | ||
25 | time_t start; | 24 | time_t start; |
26 | 25 | ||
27 | if (util_getword (arg, &sp)) | 26 | if (imap4d_tokbuf_argc (tok) != 2) |
28 | return util_finish (command, RESP_BAD, "Too many args"); | 27 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
29 | 28 | ||
30 | if (util_wait_input (0) == -1) | 29 | if (util_wait_input (0) == -1) |
31 | return util_finish (command, RESP_NO, "Cannot idle"); | 30 | return util_finish (command, RESP_NO, "Cannot idle"); |
... | @@ -38,15 +37,10 @@ imap4d_idle (struct imap4d_command *command, char *arg) | ... | @@ -38,15 +37,10 @@ imap4d_idle (struct imap4d_command *command, char *arg) |
38 | { | 37 | { |
39 | if (util_wait_input (5)) | 38 | if (util_wait_input (5)) |
40 | { | 39 | { |
41 | int rc; | 40 | imap4d_readline (tok); |
42 | char *p; | 41 | if (imap4d_tokbuf_argc (tok) == 1 |
43 | char *cmd = imap4d_readline (); | 42 | && strcasecmp (imap4d_tokbuf_getarg (tok, IMAP4_ARG_TAG), |
44 | 43 | "done") == 0) | |
45 | p = util_getword (cmd, &sp); | ||
46 | rc = strcasecmp (p, "done") == 0; | ||
47 | |||
48 | free (cmd); | ||
49 | if (rc) | ||
50 | break; | 44 | break; |
51 | } | 45 | } |
52 | else if (time (NULL) - start > idle_timeout) | 46 | else if (time (NULL) - start > idle_timeout) | ... | ... |
... | @@ -370,6 +370,7 @@ get_client_address (int fd, struct sockaddr_in *pcs) | ... | @@ -370,6 +370,7 @@ get_client_address (int fd, struct sockaddr_in *pcs) |
370 | static int | 370 | static int |
371 | imap4d_mainloop (int fd, FILE *infile, FILE *outfile) | 371 | imap4d_mainloop (int fd, FILE *infile, FILE *outfile) |
372 | { | 372 | { |
373 | imap4d_tokbuf_t tokp; | ||
373 | char *text; | 374 | char *text; |
374 | int debug_mode = isatty (fd); | 375 | int debug_mode = isatty (fd); |
375 | static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE, | 376 | static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE, |
... | @@ -400,14 +401,14 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile) | ... | @@ -400,14 +401,14 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile) |
400 | util_out ((state == STATE_AUTH) ? RESP_PREAUTH : RESP_OK, "%s", text); | 401 | util_out ((state == STATE_AUTH) ? RESP_PREAUTH : RESP_OK, "%s", text); |
401 | util_flush_output (); | 402 | util_flush_output (); |
402 | 403 | ||
404 | tokp = imap4d_tokbuf_init (); | ||
403 | while (1) | 405 | while (1) |
404 | { | 406 | { |
405 | char *cmd = imap4d_readline (); | 407 | imap4d_readline (tokp); |
406 | /* check for updates */ | 408 | /* check for updates */ |
407 | imap4d_sync (); | 409 | imap4d_sync (); |
408 | util_do_command (cmd); | 410 | util_do_command (tokp); |
409 | imap4d_sync (); | 411 | imap4d_sync (); |
410 | free (cmd); | ||
411 | util_flush_output (); | 412 | util_flush_output (); |
412 | } | 413 | } |
413 | 414 | ... | ... |
... | @@ -41,6 +41,7 @@ | ... | @@ -41,6 +41,7 @@ |
41 | #include <stdlib.h> | 41 | #include <stdlib.h> |
42 | #include <unistd.h> | 42 | #include <unistd.h> |
43 | #include <string.h> | 43 | #include <string.h> |
44 | #include <setjmp.h> | ||
44 | #include <sys/wait.h> | 45 | #include <sys/wait.h> |
45 | #include <sys/types.h> | 46 | #include <sys/types.h> |
46 | #include <syslog.h> | 47 | #include <syslog.h> |
... | @@ -108,10 +109,12 @@ | ... | @@ -108,10 +109,12 @@ |
108 | extern "C" { | 109 | extern "C" { |
109 | #endif | 110 | #endif |
110 | 111 | ||
112 | typedef struct imap4d_tokbuf *imap4d_tokbuf_t; | ||
113 | |||
111 | struct imap4d_command | 114 | struct imap4d_command |
112 | { | 115 | { |
113 | const char *name; | 116 | const char *name; |
114 | int (*func) (struct imap4d_command *, char *); | 117 | int (*func) (struct imap4d_command *, imap4d_tokbuf_t); |
115 | int states; | 118 | int states; |
116 | int failure; | 119 | int failure; |
117 | int success; | 120 | int success; |
... | @@ -191,48 +194,63 @@ extern int imap4d_transcript; | ... | @@ -191,48 +194,63 @@ extern int imap4d_transcript; |
191 | #ifndef HAVE_STRTOK_R | 194 | #ifndef HAVE_STRTOK_R |
192 | extern char *strtok_r (char *s, const char *delim, char **save_ptr); | 195 | extern char *strtok_r (char *s, const char *delim, char **save_ptr); |
193 | #endif | 196 | #endif |
197 | |||
198 | /* Input functions */ | ||
199 | imap4d_tokbuf_t imap4d_tokbuf_init (void); | ||
200 | void imap4d_tokbuf_destroy (imap4d_tokbuf_t *tok); | ||
201 | int imap4d_tokbuf_argc (imap4d_tokbuf_t tok); | ||
202 | char *imap4d_tokbuf_getarg (imap4d_tokbuf_t tok, int n); | ||
203 | void imap4d_readline (imap4d_tokbuf_t tok); | ||
204 | struct imap4d_tokbuf *imap4d_tokbuf_from_string (char *str); | ||
205 | int imap4d_getline (char **pbuf, size_t *psize, size_t *pnbytes); | ||
206 | |||
207 | #define IMAP4_ARG_TAG 0 | ||
208 | #define IMAP4_ARG_COMMAND 1 | ||
209 | #define IMAP4_ARG_1 2 | ||
210 | #define IMAP4_ARG_2 3 | ||
211 | #define IMAP4_ARG_3 4 | ||
212 | #define IMAP4_ARG_4 5 | ||
194 | 213 | ||
195 | /* Imap4 commands */ | 214 | /* Imap4 commands */ |
196 | extern int imap4d_append (struct imap4d_command *, char *); | 215 | extern int imap4d_append (struct imap4d_command *, imap4d_tokbuf_t); |
197 | extern int imap4d_append0 (mu_mailbox_t mbox, int flags, char *text); | 216 | extern int imap4d_authenticate (struct imap4d_command *, imap4d_tokbuf_t); |
198 | extern int imap4d_authenticate (struct imap4d_command *, char *); | ||
199 | extern void imap4d_auth_capability (void); | 217 | extern void imap4d_auth_capability (void); |
200 | extern int imap4d_capability (struct imap4d_command *, char *); | 218 | extern int imap4d_capability (struct imap4d_command *, imap4d_tokbuf_t); |
201 | extern int imap4d_check (struct imap4d_command *, char *); | 219 | extern int imap4d_check (struct imap4d_command *, imap4d_tokbuf_t); |
202 | extern int imap4d_close (struct imap4d_command *, char *); | 220 | extern int imap4d_close (struct imap4d_command *, imap4d_tokbuf_t); |
203 | extern int imap4d_copy (struct imap4d_command *, char *); | 221 | extern int imap4d_copy (struct imap4d_command *, imap4d_tokbuf_t); |
204 | extern int imap4d_copy0 (char *, int, char *, size_t); | 222 | extern int imap4d_copy0 (imap4d_tokbuf_t, int isuid, char **err_text); |
205 | extern int imap4d_create (struct imap4d_command *, char *); | 223 | extern int imap4d_create (struct imap4d_command *, imap4d_tokbuf_t); |
206 | extern int imap4d_delete (struct imap4d_command *, char *); | 224 | extern int imap4d_delete (struct imap4d_command *, imap4d_tokbuf_t); |
207 | extern int imap4d_examine (struct imap4d_command *, char *); | 225 | extern int imap4d_examine (struct imap4d_command *, imap4d_tokbuf_t); |
208 | extern int imap4d_expunge (struct imap4d_command *, char *); | 226 | extern int imap4d_expunge (struct imap4d_command *, imap4d_tokbuf_t); |
209 | extern int imap4d_fetch (struct imap4d_command *, char *); | 227 | extern int imap4d_fetch (struct imap4d_command *, imap4d_tokbuf_t); |
210 | extern int imap4d_fetch0 (char *, int, char *, size_t); | 228 | extern int imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text); |
211 | extern int imap4d_list (struct imap4d_command *, char *); | 229 | extern int imap4d_list (struct imap4d_command *, imap4d_tokbuf_t); |
212 | extern int imap4d_lsub (struct imap4d_command *, char *); | 230 | extern int imap4d_lsub (struct imap4d_command *, imap4d_tokbuf_t); |
213 | extern int imap4d_login (struct imap4d_command *, char *); | 231 | extern int imap4d_login (struct imap4d_command *, imap4d_tokbuf_t); |
214 | extern int imap4d_logout (struct imap4d_command *, char *); | 232 | extern int imap4d_logout (struct imap4d_command *, imap4d_tokbuf_t); |
215 | extern int imap4d_noop (struct imap4d_command *, char *); | 233 | extern int imap4d_noop (struct imap4d_command *, imap4d_tokbuf_t); |
216 | extern int imap4d_rename (struct imap4d_command *, char *); | 234 | extern int imap4d_rename (struct imap4d_command *, imap4d_tokbuf_t); |
217 | extern int imap4d_preauth_setup (int fd); | 235 | extern int imap4d_preauth_setup (int fd); |
218 | extern int imap4d_search (struct imap4d_command *, char *); | 236 | extern int imap4d_search (struct imap4d_command *, imap4d_tokbuf_t); |
219 | extern int imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize); | 237 | extern int imap4d_search0 (imap4d_tokbuf_t, int isuid, char **repyptr); |
220 | extern int imap4d_select (struct imap4d_command *, char *); | 238 | extern int imap4d_select (struct imap4d_command *, imap4d_tokbuf_t); |
221 | extern int imap4d_select0 (struct imap4d_command *, char *, int); | 239 | extern int imap4d_select0 (struct imap4d_command *, char *, int); |
222 | extern int imap4d_select_status (void); | 240 | extern int imap4d_select_status (void); |
223 | #ifdef WITH_TLS | 241 | #ifdef WITH_TLS |
224 | extern int imap4d_starttls (struct imap4d_command *, char *); | 242 | extern int imap4d_starttls (struct imap4d_command *, imap4d_tokbuf_t); |
225 | extern void starttls_init (void); | 243 | extern void starttls_init (void); |
226 | #endif /* WITH_TLS */ | 244 | #endif /* WITH_TLS */ |
227 | extern int imap4d_status (struct imap4d_command *, char *); | 245 | extern int imap4d_status (struct imap4d_command *, imap4d_tokbuf_t); |
228 | extern int imap4d_store (struct imap4d_command *, char *); | 246 | extern int imap4d_store (struct imap4d_command *, imap4d_tokbuf_t); |
229 | extern int imap4d_store0 (char *, int, char *, size_t); | 247 | extern int imap4d_store0 (imap4d_tokbuf_t, int, char **); |
230 | extern int imap4d_subscribe (struct imap4d_command *, char *); | 248 | extern int imap4d_subscribe (struct imap4d_command *, imap4d_tokbuf_t); |
231 | extern int imap4d_uid (struct imap4d_command *, char *); | 249 | extern int imap4d_uid (struct imap4d_command *, imap4d_tokbuf_t); |
232 | extern int imap4d_unsubscribe (struct imap4d_command *, char *); | 250 | extern int imap4d_unsubscribe (struct imap4d_command *, imap4d_tokbuf_t); |
233 | extern int imap4d_namespace (struct imap4d_command *, char *); | 251 | extern int imap4d_namespace (struct imap4d_command *, imap4d_tokbuf_t); |
234 | extern int imap4d_version (struct imap4d_command *, char *); | 252 | extern int imap4d_version (struct imap4d_command *, imap4d_tokbuf_t); |
235 | extern int imap4d_idle (struct imap4d_command *, char *); | 253 | extern int imap4d_idle (struct imap4d_command *, imap4d_tokbuf_t); |
236 | 254 | ||
237 | extern int imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid); | 255 | extern int imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid); |
238 | 256 | ||
... | @@ -274,25 +292,17 @@ extern int util_start (char *); | ... | @@ -274,25 +292,17 @@ extern int util_start (char *); |
274 | extern int util_finish (struct imap4d_command *, int, const char *, ...) | 292 | extern int util_finish (struct imap4d_command *, int, const char *, ...) |
275 | MU_PRINTFLIKE(3,4); | 293 | MU_PRINTFLIKE(3,4); |
276 | extern int util_getstate (void); | 294 | extern int util_getstate (void); |
277 | extern int util_do_command (char *); | 295 | extern int util_do_command (imap4d_tokbuf_t); |
278 | extern char *imap4d_readline (void); | ||
279 | extern char *imap4d_readline_ex (void); | ||
280 | extern char *util_getword (char *, char **); | ||
281 | extern char *util_getitem (char *, const char *, char **); | ||
282 | extern int util_token (char *, size_t, char **); | ||
283 | extern void util_unquote (char **); | ||
284 | extern char *util_tilde_expansion (const char *, const char *); | 296 | extern char *util_tilde_expansion (const char *, const char *); |
285 | extern char *util_getfullpath (char *, const char *); | 297 | extern char *util_getfullpath (char *, const char *); |
286 | extern int util_msgset (char *, size_t **, int *, int); | 298 | extern int util_msgset (char *, size_t **, int *, int); |
287 | extern int util_upper (char *); | 299 | extern int util_upper (char *); |
288 | extern struct imap4d_command *util_getcommand (char *, | 300 | extern struct imap4d_command *util_getcommand (char *, |
289 | struct imap4d_command []); | 301 | struct imap4d_command []); |
290 | extern int util_parse_internal_date0 (char *date, time_t *timep, char **endp); | ||
291 | extern int util_parse_internal_date (char *date, time_t *timep); | 302 | extern int util_parse_internal_date (char *date, time_t *timep); |
292 | extern int util_parse_822_date (const char *date, time_t *timep); | 303 | extern int util_parse_822_date (const char *date, time_t *timep); |
293 | extern int util_parse_ctime_date (const char *date, time_t *timep); | 304 | extern int util_parse_ctime_date (const char *date, time_t *timep); |
294 | extern char *util_strcasestr (const char *haystack, const char *needle); | 305 | extern char *util_strcasestr (const char *haystack, const char *needle); |
295 | extern int util_parse_attributes (char *items, char **save, int *flags); | ||
296 | 306 | ||
297 | extern int util_base64_encode (const unsigned char *input, | 307 | extern int util_base64_encode (const unsigned char *input, |
298 | size_t input_len, | 308 | size_t input_len, |
... | @@ -330,6 +340,7 @@ void util_bye (void); | ... | @@ -330,6 +340,7 @@ void util_bye (void); |
330 | void util_atexit (void (*fp) (void)); | 340 | void util_atexit (void (*fp) (void)); |
331 | void util_chdir (const char *homedir); | 341 | void util_chdir (const char *homedir); |
332 | int is_atom (const char *s); | 342 | int is_atom (const char *s); |
343 | int util_isdelim (const char *str); | ||
333 | 344 | ||
334 | #ifdef WITH_TLS | 345 | #ifdef WITH_TLS |
335 | int imap4d_init_tls_server (void); | 346 | int imap4d_init_tls_server (void); | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002, 2005, 2006, | 2 | Copyright (C) 1999, 2001, 2002, 2005, 2006, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -106,6 +106,19 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) | ... | @@ -106,6 +106,19 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) |
106 | } | 106 | } |
107 | 107 | ||
108 | /* | 108 | /* |
109 | 6.3.8. LIST Command | ||
110 | |||
111 | Arguments: reference name | ||
112 | mailbox name with possible wildcards | ||
113 | |||
114 | Responses: untagged responses: LIST | ||
115 | |||
116 | Result: OK - list completed | ||
117 | NO - list failure: can't list that reference or name | ||
118 | BAD - command unknown or arguments invalid | ||
119 | */ | ||
120 | |||
121 | /* | ||
109 | 1- IMAP4 insists: the reference argument present in the | 122 | 1- IMAP4 insists: the reference argument present in the |
110 | interpreted form SHOULD prefix the interpreted form. It SHOULD | 123 | interpreted form SHOULD prefix the interpreted form. It SHOULD |
111 | also be in the same form as the reference name argument. This | 124 | also be in the same form as the reference name argument. This |
... | @@ -126,21 +139,17 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) | ... | @@ -126,21 +139,17 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data) |
126 | but it does not match the hierarchy delimiter. */ | 139 | but it does not match the hierarchy delimiter. */ |
127 | 140 | ||
128 | int | 141 | int |
129 | imap4d_list (struct imap4d_command *command, char *arg) | 142 | imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok) |
130 | { | 143 | { |
131 | char *sp = NULL; | ||
132 | char *ref; | 144 | char *ref; |
133 | char *wcard; | 145 | char *wcard; |
134 | const char *delim = "/"; | 146 | const char *delim = "/"; |
135 | 147 | ||
136 | ref = util_getword (arg, &sp); | 148 | if (imap4d_tokbuf_argc (tok) != 4) |
137 | wcard = util_getword (NULL, &sp); | 149 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
138 | if (!ref || !wcard) | 150 | |
139 | return util_finish (command, RESP_BAD, "Too few arguments"); | 151 | ref = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
140 | 152 | wcard = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2); | |
141 | /* Remove the double quotes. */ | ||
142 | util_unquote (&ref); | ||
143 | util_unquote (&wcard); | ||
144 | 153 | ||
145 | /* If wildcard is empty, it is a special case: we have to | 154 | /* If wildcard is empty, it is a special case: we have to |
146 | return the hierarchy. */ | 155 | return the hierarchy. */ | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002, 2006, | 2 | Copyright (C) 1999, 2001, 2002, 2006, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -19,26 +19,32 @@ | ... | @@ -19,26 +19,32 @@ |
19 | 19 | ||
20 | #include "imap4d.h" | 20 | #include "imap4d.h" |
21 | 21 | ||
22 | /* | ||
23 | 6.2.2. LOGIN Command | ||
24 | |||
25 | Arguments: user name | ||
26 | password | ||
27 | |||
28 | Responses: no specific responses for this command | ||
29 | |||
30 | Result: OK - login completed, now in authenticated state | ||
31 | NO - login failure: user name or password rejected | ||
32 | BAD - command unknown or arguments invalid | ||
33 | */ | ||
22 | int | 34 | int |
23 | imap4d_login (struct imap4d_command *command, char *arg) | 35 | imap4d_login (struct imap4d_command *command, imap4d_tokbuf_t tok) |
24 | { | 36 | { |
25 | char *sp = NULL, *username, *pass; | 37 | char *username, *pass; |
26 | int rc; | 38 | int rc; |
27 | 39 | ||
28 | if (login_disabled || tls_required) | 40 | if (login_disabled || tls_required) |
29 | return util_finish (command, RESP_NO, "Command disabled"); | 41 | return util_finish (command, RESP_NO, "Command disabled"); |
30 | 42 | ||
31 | username = util_getword (arg, &sp); | 43 | if (imap4d_tokbuf_argc (tok) != 4) |
32 | pass = util_getword (NULL, &sp); | 44 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
33 | 45 | ||
34 | /* Remove the double quotes. */ | 46 | username = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
35 | util_unquote (&username); | 47 | pass = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2); |
36 | util_unquote (&pass); | ||
37 | |||
38 | if (username == NULL || *username == '\0' || pass == NULL) | ||
39 | return util_finish (command, RESP_NO, "Too few args"); | ||
40 | else if (util_getword (NULL, &sp)) | ||
41 | return util_finish (command, RESP_NO, "Too many args"); | ||
42 | 48 | ||
43 | auth_data = mu_get_auth_by_name (username); | 49 | auth_data = mu_get_auth_by_name (username); |
44 | 50 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,15 +19,21 @@ | ... | @@ -19,15 +19,21 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * This needs to properly close the mailbox | 22 | 6.1.3. LOGOUT Command |
23 | */ | 23 | |
24 | Arguments: none | ||
25 | |||
26 | Responses: REQUIRED untagged response: BYE | ||
27 | |||
28 | Result: OK - logout completed | ||
29 | BAD - command unknown or arguments invalid | ||
30 | */ | ||
24 | 31 | ||
25 | int | 32 | int |
26 | imap4d_logout (struct imap4d_command *command, char *arg) | 33 | imap4d_logout (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 34 | { |
28 | char *sp = NULL; | 35 | if (imap4d_tokbuf_argc (tok) != 2) |
29 | if (util_getword (arg, &sp)) | 36 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
30 | return util_finish (command, RESP_BAD, "Too many args"); | ||
31 | imap4d_bye0 (OK, command); | 37 | imap4d_bye0 (OK, command); |
32 | return 0; | 38 | return 0; |
33 | } | 39 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,13 +19,20 @@ | ... | @@ -19,13 +19,20 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * | 22 | 6.3.9. LSUB Command |
23 | */ | ||
24 | 23 | ||
24 | Arguments: reference name | ||
25 | mailbox name with possible wildcards | ||
26 | |||
27 | Responses: untagged responses: LSUB | ||
28 | |||
29 | Result: OK - lsub completed | ||
30 | NO - lsub failure: can't list that reference or name | ||
31 | BAD - command unknown or arguments invalid | ||
32 | */ | ||
25 | int | 33 | int |
26 | imap4d_lsub (struct imap4d_command *command, char *arg) | 34 | imap4d_lsub (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 35 | { |
28 | char *sp; | ||
29 | char *ref; | 36 | char *ref; |
30 | char *wcard; | 37 | char *wcard; |
31 | char *file = NULL; | 38 | char *file = NULL; |
... | @@ -33,14 +40,11 @@ imap4d_lsub (struct imap4d_command *command, char *arg) | ... | @@ -33,14 +40,11 @@ imap4d_lsub (struct imap4d_command *command, char *arg) |
33 | const char *delim = "/"; | 40 | const char *delim = "/"; |
34 | FILE *fp; | 41 | FILE *fp; |
35 | 42 | ||
36 | ref = util_getword (arg, &sp); | 43 | if (imap4d_tokbuf_argc (tok) != 4) |
37 | wcard = util_getword (NULL, &sp); | 44 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
38 | if (!ref || !wcard) | 45 | |
39 | return util_finish (command, RESP_BAD, "Too few arguments"); | 46 | ref = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
40 | 47 | wcard = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2); | |
41 | /* Remove the double quotes. */ | ||
42 | util_unquote (&ref); | ||
43 | util_unquote (&wcard); | ||
44 | 48 | ||
45 | asprintf (&pattern, "%s%s", ref, wcard); | 49 | asprintf (&pattern, "%s%s", ref, wcard); |
46 | if (!pattern) | 50 | if (!pattern) | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -89,8 +89,9 @@ print_namespace (int n) | ... | @@ -89,8 +89,9 @@ print_namespace (int n) |
89 | util_send ("("); | 89 | util_send ("("); |
90 | for (i = 0; i < namespace[n].subdir_c; i++) | 90 | for (i = 0; i < namespace[n].subdir_c; i++) |
91 | { | 91 | { |
92 | util_send ("(\"%s\" \"/\")", | 92 | char *dir = printable_pathname (namespace[n].subdir_v[i]); |
93 | printable_pathname (namespace[n].subdir_v[i])); | 93 | char *suf = (dir[0] && dir[strlen (dir) - 1] != '/') ? "/" : ""; |
94 | util_send ("(\"%s%s\" \"/\")", dir, suf); | ||
94 | } | 95 | } |
95 | util_send (")"); | 96 | util_send (")"); |
96 | } | 97 | } |
... | @@ -114,11 +115,27 @@ namespace_enumerate_all (nsfp_t f, void *closure) | ... | @@ -114,11 +115,27 @@ namespace_enumerate_all (nsfp_t f, void *closure) |
114 | || namespace_enumerate (NS_SHARED, f, closure); | 115 | || namespace_enumerate (NS_SHARED, f, closure); |
115 | } | 116 | } |
116 | 117 | ||
118 | /* | ||
119 | 5. NAMESPACE Command | ||
120 | |||
121 | Arguments: none | ||
122 | |||
123 | Response: an untagged NAMESPACE response that contains the prefix | ||
124 | and hierarchy delimiter to the server's Personal | ||
125 | Namespace(s), Other Users' Namespace(s), and Shared | ||
126 | Namespace(s) that the server wishes to expose. The | ||
127 | response will contain a NIL for any namespace class | ||
128 | that is not available. Namespace_Response_Extensions | ||
129 | MAY be included in the response. | ||
130 | Namespace_Response_Extensions which are not on the IETF | ||
131 | standards track, MUST be prefixed with an "X-". | ||
132 | */ | ||
133 | |||
117 | int | 134 | int |
118 | imap4d_namespace (struct imap4d_command *command, char *arg) | 135 | imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok) |
119 | { | 136 | { |
120 | if (*arg) | 137 | if (imap4d_tokbuf_argc (tok) != 2) |
121 | return util_finish (command, RESP_BAD, "Too many arguments"); | 138 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
122 | 139 | ||
123 | util_send ("* NAMESPACE "); | 140 | util_send ("* NAMESPACE "); |
124 | 141 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,13 +19,10 @@ | ... | @@ -19,13 +19,10 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | int | 21 | int |
22 | imap4d_noop (struct imap4d_command *command, char *arg) | 22 | imap4d_noop (struct imap4d_command *command, imap4d_tokbuf_t tok) |
23 | { | 23 | { |
24 | char *sp = NULL; | 24 | if (imap4d_tokbuf_argc (tok) != 2) |
25 | 25 | return util_finish (command, RESP_BAD, "Invalid arguments"); | |
26 | if (util_getword (arg, &sp)) | ||
27 | return util_finish (command, RESP_BAD, "Too many args"); | ||
28 | |||
29 | imap4d_sync (); | 26 | imap4d_sync (); |
30 | return util_finish (command, RESP_OK, "Completed"); | 27 | return util_finish (command, RESP_OK, "Completed"); |
31 | } | 28 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,30 +19,37 @@ | ... | @@ -19,30 +19,37 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | 6.3.5. RENAME Command | ||
23 | |||
24 | Arguments: existing mailbox name | ||
25 | new mailbox name | ||
26 | |||
27 | Responses: no specific responses for this command | ||
28 | |||
29 | Result: OK - rename completed | ||
30 | NO - rename failure: can't rename mailbox with that name, | ||
31 | can't rename to mailbox with that name | ||
32 | BAD - command unknown or arguments invalid | ||
33 | */ | ||
34 | /* | ||
22 | FIXME: Renaming a mailbox we must change the UIDVALIDITY | 35 | FIXME: Renaming a mailbox we must change the UIDVALIDITY |
23 | of the mailbox. */ | 36 | of the mailbox. */ |
24 | 37 | ||
25 | int | 38 | int |
26 | imap4d_rename (struct imap4d_command *command, char *arg) | 39 | imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 40 | { |
28 | char *oldname; | 41 | char *oldname; |
29 | char *newname; | 42 | char *newname; |
30 | char *sp = NULL; | ||
31 | int rc = RESP_OK; | 43 | int rc = RESP_OK; |
32 | const char *msg = "Completed"; | 44 | const char *msg = "Completed"; |
33 | struct stat newst; | 45 | struct stat newst; |
34 | const char *delim = "/"; | 46 | const char *delim = "/"; |
35 | 47 | ||
36 | oldname = util_getword (arg, &sp); | 48 | if (imap4d_tokbuf_argc (tok) != 4) |
37 | newname = util_getword (NULL, &sp); | 49 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
38 | if (!newname || !oldname) | 50 | |
39 | return util_finish (command, RESP_BAD, "Too few arguments"); | 51 | oldname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
40 | 52 | newname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2); | |
41 | util_unquote (&newname); | ||
42 | util_unquote (&oldname); | ||
43 | |||
44 | if (*newname == '\0' || *oldname == '\0') | ||
45 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
46 | 53 | ||
47 | if (strcasecmp (newname, "INBOX") == 0) | 54 | if (strcasecmp (newname, "INBOX") == 0) |
48 | return util_finish (command, RESP_NO, "Name Inbox is reservered"); | 55 | return util_finish (command, RESP_NO, "Name Inbox is reservered"); | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2005, 2007, |
3 | 2008 Free Software Foundation, Inc. | ||
3 | 4 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -223,11 +224,9 @@ struct mem_chain | ... | @@ -223,11 +224,9 @@ struct mem_chain |
223 | /* Parse buffer structure */ | 224 | /* Parse buffer structure */ |
224 | struct parsebuf | 225 | struct parsebuf |
225 | { | 226 | { |
226 | char *token; /* Current token. Either points to tokbuf | 227 | imap4d_tokbuf_t tok; /* Token buffer */ |
227 | or is allocated within `alloc' chain */ | 228 | int arg; /* Argument number */ |
228 | char tokbuf[MAXTOKEN+1]; /* Token buffer for short tokens */ | 229 | char *token; /* Current token */ |
229 | |||
230 | char *arg; /* Rest of command line to be parsed */ | ||
231 | int isuid; /* UIDs instead of msgnos are required */ | 230 | int isuid; /* UIDs instead of msgnos are required */ |
232 | char *err_mesg; /* Error message if a parse error occured */ | 231 | char *err_mesg; /* Error message if a parse error occured */ |
233 | struct mem_chain *alloc; /* Chain of objects allocated during parsing */ | 232 | struct mem_chain *alloc; /* Chain of objects allocated during parsing */ |
... | @@ -249,30 +248,45 @@ static int parse_gettoken (struct parsebuf *pb, int req); | ... | @@ -249,30 +248,45 @@ static int parse_gettoken (struct parsebuf *pb, int req); |
249 | static int search_run (struct parsebuf *pb); | 248 | static int search_run (struct parsebuf *pb); |
250 | static void do_search (struct parsebuf *pb); | 249 | static void do_search (struct parsebuf *pb); |
251 | 250 | ||
251 | /* | ||
252 | 6.4.4. SEARCH Command | ||
253 | |||
254 | Arguments: OPTIONAL [CHARSET] specification | ||
255 | searching criteria (one or more) | ||
256 | |||
257 | Responses: REQUIRED untagged response: SEARCH | ||
258 | |||
259 | Result: OK - search completed | ||
260 | NO - search error: can't search that [CHARSET] or | ||
261 | criteria | ||
262 | BAD - command unknown or arguments invalid | ||
263 | */ | ||
264 | |||
252 | int | 265 | int |
253 | imap4d_search (struct imap4d_command *command, char *arg) | 266 | imap4d_search (struct imap4d_command *command, imap4d_tokbuf_t tok) |
254 | { | 267 | { |
255 | int rc; | 268 | int rc; |
256 | char buffer[64]; | 269 | char *err_text= ""; |
257 | 270 | ||
258 | rc = imap4d_search0 (arg, 0, buffer, sizeof buffer); | 271 | rc = imap4d_search0 (tok, 0, &err_text); |
259 | return util_finish (command, rc, "%s", buffer); | 272 | return util_finish (command, rc, "%s", err_text); |
260 | } | 273 | } |
261 | 274 | ||
262 | int | 275 | int |
263 | imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) | 276 | imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text) |
264 | { | 277 | { |
265 | struct parsebuf parsebuf; | 278 | struct parsebuf parsebuf; |
266 | 279 | ||
267 | memset (&parsebuf, 0, sizeof(parsebuf)); | 280 | memset (&parsebuf, 0, sizeof(parsebuf)); |
268 | parsebuf.arg = arg; | 281 | parsebuf.tok = tok; |
282 | parsebuf.arg = IMAP4_ARG_1 + !!isuid; | ||
269 | parsebuf.err_mesg = NULL; | 283 | parsebuf.err_mesg = NULL; |
270 | parsebuf.alloc = NULL; | 284 | parsebuf.alloc = NULL; |
271 | parsebuf.isuid = isuid; | 285 | parsebuf.isuid = isuid; |
272 | 286 | ||
273 | if (!parse_gettoken (&parsebuf, 0)) | 287 | if (!parse_gettoken (&parsebuf, 0)) |
274 | { | 288 | { |
275 | snprintf (replybuf, replysize, "Too few args"); | 289 | *err_text = "Too few args"; |
276 | return RESP_BAD; | 290 | return RESP_BAD; |
277 | } | 291 | } |
278 | 292 | ||
... | @@ -280,20 +294,20 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) | ... | @@ -280,20 +294,20 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) |
280 | { | 294 | { |
281 | if (!parse_gettoken (&parsebuf, 0)) | 295 | if (!parse_gettoken (&parsebuf, 0)) |
282 | { | 296 | { |
283 | snprintf (replybuf, replysize, "Too few args"); | 297 | *err_text = "Too few args"; |
284 | return RESP_BAD; | 298 | return RESP_BAD; |
285 | } | 299 | } |
286 | 300 | ||
287 | /* Currently only ASCII is supported */ | 301 | /* Currently only ASCII is supported */ |
288 | if (strcasecmp (parsebuf.token, "US-ASCII")) | 302 | if (strcasecmp (parsebuf.token, "US-ASCII")) |
289 | { | 303 | { |
290 | snprintf (replybuf, replysize, "Charset not supported"); | 304 | *err_text = "Charset not supported"; |
291 | return RESP_NO; | 305 | return RESP_NO; |
292 | } | 306 | } |
293 | 307 | ||
294 | if (!parse_gettoken (&parsebuf, 0)) | 308 | if (!parse_gettoken (&parsebuf, 0)) |
295 | { | 309 | { |
296 | snprintf (replybuf, replysize, "Too few args"); | 310 | *err_text = "Too few args"; |
297 | return RESP_BAD; | 311 | return RESP_BAD; |
298 | } | 312 | } |
299 | 313 | ||
... | @@ -304,16 +318,14 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) | ... | @@ -304,16 +318,14 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) |
304 | if (!parsebuf.tree) | 318 | if (!parsebuf.tree) |
305 | { | 319 | { |
306 | parse_free_mem (&parsebuf); | 320 | parse_free_mem (&parsebuf); |
307 | snprintf (replybuf, replysize, "%s (near %s)", | 321 | *err_text = "Parse error"; |
308 | parsebuf.err_mesg, | ||
309 | *parsebuf.arg ? parsebuf.arg : "end"); | ||
310 | return RESP_BAD; | 322 | return RESP_BAD; |
311 | } | 323 | } |
312 | 324 | ||
313 | if (parsebuf.token[0] != 0) | 325 | if (parsebuf.token) |
314 | { | 326 | { |
315 | parse_free_mem (&parsebuf); | 327 | parse_free_mem (&parsebuf); |
316 | snprintf (replybuf, replysize, "Junk at the end of statement"); | 328 | *err_text = "Junk at the end of statement"; |
317 | return RESP_BAD; | 329 | return RESP_BAD; |
318 | } | 330 | } |
319 | 331 | ||
... | @@ -322,7 +334,7 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) | ... | @@ -322,7 +334,7 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize) |
322 | 334 | ||
323 | parse_free_mem (&parsebuf); | 335 | parse_free_mem (&parsebuf); |
324 | 336 | ||
325 | snprintf (replybuf, replysize, "Completed"); | 337 | *err_text = "Completed"; |
326 | return RESP_OK; | 338 | return RESP_OK; |
327 | } | 339 | } |
328 | 340 | ||
... | @@ -359,41 +371,13 @@ do_search (struct parsebuf *pb) | ... | @@ -359,41 +371,13 @@ do_search (struct parsebuf *pb) |
359 | int | 371 | int |
360 | parse_gettoken (struct parsebuf *pb, int req) | 372 | parse_gettoken (struct parsebuf *pb, int req) |
361 | { | 373 | { |
362 | int rc; | 374 | if (req && pb->arg >= imap4d_tokbuf_argc (pb->tok)) |
363 | char *s; | ||
364 | |||
365 | pb->token = pb->tokbuf; | ||
366 | while (*pb->arg && *pb->arg == ' ') | ||
367 | pb->arg++; | ||
368 | switch (*pb->arg) | ||
369 | { | 375 | { |
370 | case '(': | 376 | pb->err_mesg = "Unexpected end of statement"; |
371 | case ')': | 377 | return 0; |
372 | pb->token[0] = *pb->arg++; | ||
373 | pb->token[1] = 0; | ||
374 | rc = 1; | ||
375 | break; | ||
376 | case '"': | ||
377 | s = ++pb->arg; | ||
378 | while (*pb->arg && *pb->arg != '"') | ||
379 | pb->arg++; | ||
380 | rc = pb->arg - s; | ||
381 | if (*pb->arg) | ||
382 | pb->arg++; | ||
383 | |||
384 | if (rc >= sizeof(pb->tokbuf)) | ||
385 | pb->token = parse_alloc (pb, rc+1); | ||
386 | memcpy (pb->token, s, rc); | ||
387 | pb->token[rc] = 0; | ||
388 | break; | ||
389 | |||
390 | default: | ||
391 | rc = util_token (pb->token, sizeof(pb->tokbuf), &pb->arg); | ||
392 | break; | ||
393 | } | 378 | } |
394 | if (req && rc == 0) | 379 | pb->token = imap4d_tokbuf_getarg (pb->tok, pb->arg++); |
395 | pb->err_mesg = "Unexpected end of statement"; | 380 | return 1; |
396 | return rc; | ||
397 | } | 381 | } |
398 | 382 | ||
399 | /* Memory handling */ | 383 | /* Memory handling */ |
... | @@ -468,7 +452,7 @@ parse_search_key_list (struct parsebuf *pb) | ... | @@ -468,7 +452,7 @@ parse_search_key_list (struct parsebuf *pb) |
468 | { | 452 | { |
469 | struct search_node *leftarg = NULL; | 453 | struct search_node *leftarg = NULL; |
470 | 454 | ||
471 | while (pb->token[0] && pb->token[0] != ')') | 455 | while (pb->token && pb->token[0] != ')') |
472 | { | 456 | { |
473 | struct search_node *rightarg = parse_search_key (pb); | 457 | struct search_node *rightarg = parse_search_key (pb); |
474 | if (!rightarg) | 458 | if (!rightarg) |
... | @@ -563,8 +547,8 @@ parse_equiv_key (struct parsebuf *pb) | ... | @@ -563,8 +547,8 @@ parse_equiv_key (struct parsebuf *pb) |
563 | { | 547 | { |
564 | struct search_node *node; | 548 | struct search_node *node; |
565 | struct cond_equiv *condp; | 549 | struct cond_equiv *condp; |
566 | char *arg; | 550 | int save_arg; |
567 | char *save_arg; | 551 | imap4d_tokbuf_t save_tok; |
568 | 552 | ||
569 | for (condp = equiv_list; condp->name && strcasecmp (condp->name, pb->token); | 553 | for (condp = equiv_list; condp->name && strcasecmp (condp->name, pb->token); |
570 | condp++) | 554 | condp++) |
... | @@ -574,8 +558,9 @@ parse_equiv_key (struct parsebuf *pb) | ... | @@ -574,8 +558,9 @@ parse_equiv_key (struct parsebuf *pb) |
574 | return parse_simple_key (pb); | 558 | return parse_simple_key (pb); |
575 | 559 | ||
576 | save_arg = pb->arg; | 560 | save_arg = pb->arg; |
577 | arg = parse_strdup (pb, condp->equiv); | 561 | save_tok = pb->tok; |
578 | pb->arg = arg; | 562 | pb->tok = imap4d_tokbuf_from_string (condp->equiv); |
563 | pb->arg = 0; | ||
579 | 564 | ||
580 | parse_gettoken (pb, 0); | 565 | parse_gettoken (pb, 0); |
581 | 566 | ||
... | @@ -584,11 +569,13 @@ parse_equiv_key (struct parsebuf *pb) | ... | @@ -584,11 +569,13 @@ parse_equiv_key (struct parsebuf *pb) |
584 | { | 569 | { |
585 | /* shouldn't happen? */ | 570 | /* shouldn't happen? */ |
586 | mu_diag_output (MU_DIAG_CRIT, _("%s:%d: INTERNAL ERROR (please report)"), | 571 | mu_diag_output (MU_DIAG_CRIT, _("%s:%d: INTERNAL ERROR (please report)"), |
587 | __FILE__, __LINE__); | 572 | __FILE__, __LINE__); |
588 | abort (); | 573 | abort (); |
589 | } | 574 | } |
575 | imap4d_tokbuf_destroy (&pb->tok); | ||
590 | 576 | ||
591 | pb->arg = save_arg; | 577 | pb->arg = save_arg; |
578 | pb->tok = save_tok; | ||
592 | parse_gettoken (pb, 0); | 579 | parse_gettoken (pb, 0); |
593 | return node; | 580 | return node; |
594 | } | 581 | } |
... | @@ -658,7 +645,7 @@ parse_simple_key (struct parsebuf *pb) | ... | @@ -658,7 +645,7 @@ parse_simple_key (struct parsebuf *pb) |
658 | return NULL; | 645 | return NULL; |
659 | } | 646 | } |
660 | 647 | ||
661 | if (!pb->token[0]) | 648 | if (!pb->token) |
662 | { | 649 | { |
663 | pb->err_mesg = "Not enough arguments for criterion"; | 650 | pb->err_mesg = "Not enough arguments for criterion"; |
664 | return NULL; | 651 | return NULL; | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2003, 2005, 2006, | 2 | Copyright (C) 1999, 2001, 2003, 2005, 2006, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -24,25 +24,22 @@ static int select_flags; | ... | @@ -24,25 +24,22 @@ static int select_flags; |
24 | /* select ::= "SELECT" SPACE mailbox */ | 24 | /* select ::= "SELECT" SPACE mailbox */ |
25 | 25 | ||
26 | int | 26 | int |
27 | imap4d_select (struct imap4d_command *command, char *arg) | 27 | imap4d_select (struct imap4d_command *command, imap4d_tokbuf_t tok) |
28 | { | 28 | { |
29 | return imap4d_select0 (command, arg, MU_STREAM_RDWR); | 29 | if (imap4d_tokbuf_argc (tok) != 3) |
30 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
31 | return imap4d_select0 (command, imap4d_tokbuf_getarg (tok, IMAP4_ARG_1), | ||
32 | MU_STREAM_RDWR); | ||
30 | } | 33 | } |
31 | 34 | ||
32 | /* This code is share with EXAMINE. */ | 35 | /* This code is share with EXAMINE. */ |
33 | int | 36 | int |
34 | imap4d_select0 (struct imap4d_command *command, char *arg, int flags) | 37 | imap4d_select0 (struct imap4d_command *command, char *mailbox_name, int flags) |
35 | { | 38 | { |
36 | char *mailbox_name, *sp = NULL; | ||
37 | int status; | 39 | int status; |
38 | 40 | ||
39 | /* FIXME: Check state. */ | 41 | /* FIXME: Check state. */ |
40 | 42 | ||
41 | mailbox_name = util_getword (arg, &sp); | ||
42 | util_unquote (&mailbox_name); | ||
43 | if (mailbox_name == NULL || *mailbox_name == '\0') | ||
44 | return util_finish (command, RESP_BAD, "Too few arguments"); | ||
45 | |||
46 | /* Even if a mailbox is selected, a SELECT EXAMINE or LOGOUT | 43 | /* Even if a mailbox is selected, a SELECT EXAMINE or LOGOUT |
47 | command MAY be issued without previously issuing a CLOSE command. | 44 | command MAY be issued without previously issuing a CLOSE command. |
48 | The SELECT, EXAMINE, and LOGUT commands implictly close the | 45 | The SELECT, EXAMINE, and LOGUT commands implictly close the | ... | ... |
... | @@ -23,17 +23,26 @@ | ... | @@ -23,17 +23,26 @@ |
23 | static int tls_available; | 23 | static int tls_available; |
24 | static int tls_done; | 24 | static int tls_done; |
25 | 25 | ||
26 | /* | ||
27 | 6.2.1. STARTTLS Command | ||
28 | |||
29 | Arguments: none | ||
30 | |||
31 | Responses: no specific response for this command | ||
32 | |||
33 | Result: OK - starttls completed, begin TLS negotiation | ||
34 | BAD - command unknown or arguments invalid | ||
35 | */ | ||
26 | int | 36 | int |
27 | imap4d_starttls (struct imap4d_command *command, char *arg) | 37 | imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok) |
28 | { | 38 | { |
29 | int status; | 39 | int status; |
30 | char *sp = NULL; | ||
31 | 40 | ||
32 | if (!tls_available || tls_done) | 41 | if (!tls_available || tls_done) |
33 | return util_finish (command, RESP_BAD, "Invalid command"); | 42 | return util_finish (command, RESP_BAD, "Invalid command"); |
34 | 43 | ||
35 | if (util_getword (arg, &sp)) | 44 | if (imap4d_tokbuf_argc (tok) != 2) |
36 | return util_finish (command, RESP_BAD, "Too many args"); | 45 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
37 | 46 | ||
38 | util_atexit (mu_deinit_tls_libs); | 47 | util_atexit (mu_deinit_tls_libs); |
39 | 48 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -52,11 +52,22 @@ status_get_handler (const char *name) | ... | @@ -52,11 +52,22 @@ status_get_handler (const char *name) |
52 | return p->fun; | 52 | return p->fun; |
53 | return NULL; | 53 | return NULL; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | ||
57 | 6.3.10. STATUS Command | ||
58 | |||
59 | Arguments: mailbox name | ||
60 | status data item names | ||
61 | |||
62 | Responses: untagged responses: STATUS | ||
63 | |||
64 | Result: OK - status completed | ||
65 | NO - status failure: no status for that name | ||
66 | BAD - command unknown or arguments invalid | ||
67 | */ | ||
56 | int | 68 | int |
57 | imap4d_status (struct imap4d_command *command, char *arg) | 69 | imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok) |
58 | { | 70 | { |
59 | char *sp = NULL; | ||
60 | char *name; | 71 | char *name; |
61 | char *mailbox_name; | 72 | char *mailbox_name; |
62 | const char *delim = "/"; | 73 | const char *delim = "/"; |
... | @@ -64,11 +75,12 @@ imap4d_status (struct imap4d_command *command, char *arg) | ... | @@ -64,11 +75,12 @@ imap4d_status (struct imap4d_command *command, char *arg) |
64 | int status; | 75 | int status; |
65 | int count = 0; | 76 | int count = 0; |
66 | char *err_msg = NULL; | 77 | char *err_msg = NULL; |
78 | int argc = imap4d_tokbuf_argc (tok); | ||
79 | |||
80 | if (argc < 4) | ||
81 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
67 | 82 | ||
68 | name = util_getword (arg, &sp); | 83 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
69 | util_unquote (&name); | ||
70 | if (!name || *name == '\0' || !sp || *sp == '\0') | ||
71 | return util_finish (command, RESP_BAD, "Too few args"); | ||
72 | 84 | ||
73 | mailbox_name = namespace_getfullpath (name, delim); | 85 | mailbox_name = namespace_getfullpath (name, delim); |
74 | 86 | ||
... | @@ -85,20 +97,22 @@ imap4d_status (struct imap4d_command *command, char *arg) | ... | @@ -85,20 +97,22 @@ imap4d_status (struct imap4d_command *command, char *arg) |
85 | status = mu_mailbox_open (smbox, MU_STREAM_READ); | 97 | status = mu_mailbox_open (smbox, MU_STREAM_READ); |
86 | if (status == 0) | 98 | if (status == 0) |
87 | { | 99 | { |
88 | char item[32]; | 100 | int i = IMAP4_ARG_2; |
89 | item[0] = '\0'; | 101 | char *item = imap4d_tokbuf_getarg (tok, i); |
90 | |||
91 | if (*sp == '(') | ||
92 | sp++; | ||
93 | else | ||
94 | *sp = 0; | ||
95 | 102 | ||
96 | /* Get the status item names. */ | 103 | if (item[0] == '(') |
97 | while (*sp && *sp != ')') | 104 | { |
105 | if (imap4d_tokbuf_getarg (tok, argc - 1)[0] != ')') | ||
106 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
107 | argc--; | ||
108 | i++; | ||
109 | } | ||
110 | |||
111 | for (; i < argc; i++) | ||
98 | { | 112 | { |
99 | status_funcp fun; | 113 | status_funcp fun; |
100 | 114 | ||
101 | util_token (item, sizeof (item), &sp); | 115 | item = imap4d_tokbuf_getarg (tok, i); |
102 | fun = status_get_handler (item); | 116 | fun = status_get_handler (item); |
103 | if (!fun) | 117 | if (!fun) |
104 | { | 118 | { |
... | @@ -112,6 +126,8 @@ imap4d_status (struct imap4d_command *command, char *arg) | ... | @@ -112,6 +126,8 @@ imap4d_status (struct imap4d_command *command, char *arg) |
112 | if (!fun (smbox)) | 126 | if (!fun (smbox)) |
113 | util_send (" "); | 127 | util_send (" "); |
114 | } | 128 | } |
129 | |||
130 | |||
115 | if (count > 0) | 131 | if (count > 0) |
116 | util_send (")\r\n"); | 132 | util_send (")\r\n"); |
117 | mu_mailbox_close (smbox); | 133 | mu_mailbox_close (smbox); |
... | @@ -193,5 +209,4 @@ status_unseen (mu_mailbox_t smbox) | ... | @@ -193,5 +209,4 @@ status_unseen (mu_mailbox_t smbox) |
193 | } | 209 | } |
194 | util_send ("UNSEEN %d", unseen); | 210 | util_send ("UNSEEN %d", unseen); |
195 | return 0; | 211 | return 0; |
196 | |||
197 | } | 212 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -23,134 +23,155 @@ | ... | @@ -23,134 +23,155 @@ |
23 | */ | 23 | */ |
24 | 24 | ||
25 | int | 25 | int |
26 | imap4d_store (struct imap4d_command *command, char *arg) | 26 | imap4d_store (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 27 | { |
28 | int rc; | 28 | int rc; |
29 | char buffer[64]; | 29 | char *err_text; |
30 | |||
31 | rc = imap4d_store0 (tok, 0, &err_text); | ||
32 | return util_finish (command, rc, "%s", err_text); | ||
33 | } | ||
34 | |||
35 | struct parsebuf | ||
36 | { | ||
37 | char *token; | ||
38 | imap4d_tokbuf_t tok; | ||
39 | int arg; | ||
40 | jmp_buf errjmp; | ||
41 | char *err_text; | ||
42 | }; | ||
43 | |||
44 | static void | ||
45 | parsebuf_exit (struct parsebuf *p, char *text) | ||
46 | { | ||
47 | p->err_text = text; | ||
48 | longjmp (p->errjmp, 1); | ||
49 | } | ||
30 | 50 | ||
31 | rc = imap4d_store0 (arg, 0, buffer, sizeof buffer); | 51 | static char * |
32 | return util_finish (command, rc, "%s", buffer); | 52 | parsebuf_next (struct parsebuf *p, int req) |
53 | { | ||
54 | p->token = imap4d_tokbuf_getarg (p->tok, p->arg++); | ||
55 | if (!p->token && req) | ||
56 | parsebuf_exit (p, "Too few arguments"); | ||
57 | return p->token; | ||
33 | } | 58 | } |
34 | 59 | ||
35 | int | 60 | int |
36 | imap4d_store0 (char *arg, int isuid, char *resp, size_t resplen) | 61 | imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext) |
37 | { | 62 | { |
38 | char *msgset; | 63 | char *msgset; |
39 | char *data; | ||
40 | char *sp = NULL; | ||
41 | int status; | 64 | int status; |
42 | int ack = 0; | 65 | int ack = 1; |
43 | size_t i; | 66 | size_t i; |
44 | int n = 0; | 67 | int n = 0; |
45 | size_t *set = NULL; | 68 | size_t *set = NULL; |
46 | enum value_type { STORE_SET, STORE_ADD, STORE_UNSET } how; | 69 | enum value_type { STORE_SET, STORE_ADD, STORE_UNSET } how; |
47 | 70 | struct parsebuf pb; | |
48 | msgset = util_getword (arg, &sp); | 71 | char *data; |
49 | data = util_getword (NULL, &sp); | 72 | int type = 0; |
50 | 73 | ||
51 | if (!msgset || !data || !sp || *sp == '\0') | 74 | pb.tok = tok; |
75 | pb.arg = IMAP4_ARG_1; | ||
76 | pb.err_text = NULL; | ||
77 | if (setjmp (pb.errjmp)) | ||
52 | { | 78 | { |
53 | snprintf (resp, resplen, "Too few args"); | 79 | *ptext = pb.err_text; |
80 | free (set); | ||
54 | return RESP_BAD; | 81 | return RESP_BAD; |
55 | } | 82 | } |
83 | |||
84 | msgset = parsebuf_next (&pb, 1); | ||
85 | data = parsebuf_next (&pb, 1); | ||
56 | 86 | ||
57 | /* The parsing of the data-item is a little slugish. */ | 87 | if (*data == '+') |
58 | if (strcasecmp (data, "FLAGS") == 0) | ||
59 | { | ||
60 | ack = 1; | ||
61 | how = STORE_SET; | ||
62 | } | ||
63 | else if (strcasecmp (data, "+FLAGS") == 0) | ||
64 | { | 88 | { |
65 | ack = 1; | ||
66 | how = STORE_ADD; | 89 | how = STORE_ADD; |
90 | data++; | ||
67 | } | 91 | } |
68 | else if (strcasecmp (data, "-FLAGS") == 0) | 92 | else if (*data == '-') |
69 | { | 93 | { |
70 | ack = 1; | ||
71 | how = STORE_UNSET; | ||
72 | } | ||
73 | else if (strcasecmp (data, "FLAGS.SILENT") == 0) | ||
74 | { | ||
75 | ack = 0; | ||
76 | how = STORE_SET; | ||
77 | } | ||
78 | else if (strcasecmp (data, "+FLAGS.SILENT") == 0) | ||
79 | { | ||
80 | ack = 0; | ||
81 | how = STORE_ADD; | ||
82 | } | ||
83 | else if (strcasecmp (data, "-FLAGS.SILENT") == 0) | ||
84 | { | ||
85 | ack = 0; | ||
86 | how = STORE_UNSET; | 94 | how = STORE_UNSET; |
95 | data++; | ||
87 | } | 96 | } |
88 | else | 97 | else |
98 | how = STORE_SET; | ||
99 | |||
100 | if (strcasecmp (data, "FLAGS")) | ||
101 | parsebuf_exit (&pb, "Bogus data item"); | ||
102 | data = parsebuf_next (&pb, 1); | ||
103 | |||
104 | if (*data == '.') | ||
89 | { | 105 | { |
90 | snprintf (resp, resplen, "Bogus data item"); | 106 | data = parsebuf_next (&pb, 1); |
91 | return RESP_BAD; | 107 | if (strcasecmp (data, "SILENT") == 0) |
108 | { | ||
109 | ack = 0; | ||
110 | parsebuf_next (&pb, 1); | ||
111 | } | ||
112 | else | ||
113 | parsebuf_exit (&pb, "Bogus data suffix"); | ||
92 | } | 114 | } |
93 | 115 | ||
94 | /* Get the message numbers in set[]. */ | 116 | /* Get the message numbers in set[]. */ |
95 | status = util_msgset (msgset, &set, &n, isuid); | 117 | status = util_msgset (msgset, &set, &n, isuid); |
96 | if (status != 0) | 118 | if (status != 0) |
119 | parsebuf_exit (&pb, "Bogus number set"); | ||
120 | |||
121 | if (pb.token[0] != '(') | ||
122 | parsebuf_exit (&pb, "Syntax error"); | ||
123 | parsebuf_next (&pb, 1); | ||
124 | |||
125 | do | ||
97 | { | 126 | { |
98 | snprintf (resp, resplen, "Bogus number set"); | 127 | int t; |
99 | return RESP_BAD; | 128 | if (!util_attribute_to_type (pb.token, &t)) |
129 | type |= t; | ||
100 | } | 130 | } |
131 | while (parsebuf_next (&pb, 1) && pb.token[0] != ')'); | ||
101 | 132 | ||
102 | for (i = 0; i < n; i++) | 133 | for (i = 0; i < n; i++) |
103 | { | 134 | { |
104 | mu_message_t msg = NULL; | 135 | mu_message_t msg = NULL; |
105 | mu_attribute_t attr = NULL; | 136 | mu_attribute_t attr = NULL; |
106 | char *items = strdup (sp); /* Don't use the orignal list. */ | 137 | size_t msgno = isuid ? uid_to_msgno (set[i]) : set[i]; |
107 | int first = 1; | 138 | |
108 | size_t msgno; | ||
109 | char *p = items; | ||
110 | |||
111 | msgno = (isuid) ? uid_to_msgno (set[i]) : set[i]; | ||
112 | if (msgno) | 139 | if (msgno) |
113 | { | 140 | { |
114 | mu_mailbox_get_message (mbox, msgno, &msg); | 141 | mu_mailbox_get_message (mbox, msgno, &msg); |
115 | mu_message_get_attribute (msg, &attr); | 142 | mu_message_get_attribute (msg, &attr); |
116 | 143 | ||
117 | /* Get the fetch command names. */ | 144 | switch (how) |
118 | while (*items && *items != ')') | ||
119 | { | 145 | { |
120 | int type = 0; | 146 | case STORE_ADD: |
121 | char item[64] = ""; | 147 | mu_attribute_set_flags (attr, type); |
122 | util_token (item, sizeof (item), &items); | 148 | break; |
123 | if (!util_attribute_to_type (item, &type)) | 149 | |
124 | { | 150 | case STORE_UNSET: |
125 | if (how == STORE_ADD ) | 151 | mu_attribute_unset_flags (attr, type); |
126 | mu_attribute_set_flags (attr, type); | 152 | break; |
127 | else if (how == STORE_UNSET ) | 153 | |
128 | mu_attribute_unset_flags (attr, type); | 154 | case STORE_SET: |
129 | else if (how == STORE_SET ) | 155 | mu_attribute_unset_flags (attr, 0xffffffff); /* FIXME */ |
130 | { | 156 | mu_attribute_set_flags (attr, type); |
131 | if (first) | ||
132 | { | ||
133 | mu_attribute_set_flags (attr, 0); | ||
134 | first = 0; | ||
135 | } | ||
136 | mu_attribute_set_flags (attr, type); | ||
137 | } | ||
138 | mu_attribute_set_flags (attr, MU_ATTRIBUTE_MODIFIED); | ||
139 | } | ||
140 | } | 157 | } |
141 | } | 158 | } |
159 | |||
142 | if (ack) | 160 | if (ack) |
143 | { | 161 | { |
144 | util_send ("* %d FETCH (", msgno); | 162 | util_send ("* %d FETCH (", msgno); |
145 | fetch_flags0 ("FLAGS", msg, isuid); | 163 | |
146 | util_send (")\r\n"); | 164 | if (isuid) |
165 | util_send ("UID %lu ", (unsigned long) msgno); | ||
166 | util_send ("FLAGS ("); | ||
167 | util_print_flags (attr); | ||
168 | util_send ("))\r\n"); | ||
147 | } | 169 | } |
148 | free (p); | ||
149 | /* Update the flags of uid table. */ | 170 | /* Update the flags of uid table. */ |
150 | imap4d_sync_flags (set[i]); | 171 | imap4d_sync_flags (set[i]); |
151 | } | 172 | } |
152 | free (set); | 173 | free (set); |
153 | snprintf (resp, resplen, "Completed"); | 174 | *ptext = "Completed"; |
154 | return RESP_OK; | 175 | return RESP_OK; |
155 | } | 176 | } |
156 | 177 | ... | ... |
... | @@ -19,21 +19,27 @@ | ... | @@ -19,21 +19,27 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | /* | 21 | /* |
22 | FIXME: We need to lock the file to prevent simultaneous access. | 22 | 6.3.6. SUBSCRIBE Command |
23 | */ | ||
24 | 23 | ||
24 | Arguments: mailbox | ||
25 | |||
26 | Responses: no specific responses for this command | ||
27 | |||
28 | Result: OK - subscribe completed | ||
29 | NO - subscribe failure: can't subscribe to that name | ||
30 | BAD - command unknown or arguments invalid | ||
31 | */ | ||
25 | int | 32 | int |
26 | imap4d_subscribe (struct imap4d_command *command, char *arg) | 33 | imap4d_subscribe (struct imap4d_command *command, imap4d_tokbuf_t tok) |
27 | { | 34 | { |
28 | char *sp = NULL; | ||
29 | char *name; | 35 | char *name; |
30 | char *file; | 36 | char *file; |
31 | FILE *fp; | 37 | FILE *fp; |
32 | 38 | ||
33 | name = util_getword (arg, &sp); | 39 | if (imap4d_tokbuf_argc (tok) != 3) |
34 | util_unquote (&name); | 40 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
35 | if (!name || *name == '\0') | 41 | |
36 | return util_finish (command, RESP_BAD, "Too few arguments"); | 42 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
37 | 43 | ||
38 | asprintf (&file, "%s/.mailboxlist", homedir); | 44 | asprintf (&file, "%s/.mailboxlist", homedir); |
39 | fp = fopen (file, "a"); | 45 | fp = fopen (file, "a"); | ... | ... |
1 | # -*- tcl -*- | 1 | # -*- tcl -*- |
2 | # This file is part of Mailutils testsuite. | 2 | # This file is part of Mailutils testsuite. |
3 | # Copyright (C) 2002, 2007 Free Software Foundation | 3 | # Copyright (C) 2002, 2007, 2008 Free Software Foundation |
4 | # | 4 | # |
5 | # This program is free software; you can redistribute it and/or modify | 5 | # This program is free software; you can redistribute it and/or modify |
6 | # it under the terms of the GNU General Public License as published by | 6 | # it under the terms of the GNU General Public License as published by |
... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
20 | imap4d_start | 20 | imap4d_start |
21 | 21 | ||
22 | imap4d_test "CAPABILITY" \ | 22 | imap4d_test "CAPABILITY" \ |
23 | "CAPABILITY IMAP4rev1 NAMESPACE IDLE X-VERSION" \ | 23 | "CAPABILITY IMAP4rev1 NAMESPACE IDLE LITERAL+ X-VERSION" \ |
24 | "OK" | 24 | "OK" |
25 | imap4d_test "NOOP" | 25 | imap4d_test "NOOP" |
26 | 26 | ... | ... |
... | @@ -48,7 +48,7 @@ Hello Joe, do you think we can meet at 3:30 tomorrow? | ... | @@ -48,7 +48,7 @@ Hello Joe, do you think we can meet at 3:30 tomorrow? |
48 | 48 | ||
49 | " | 49 | " |
50 | 50 | ||
51 | imap4d_test -long "APPEND mbox 25-Aug-2002 18:00:00 +0200"\ | 51 | imap4d_test -long "APPEND mbox \"25-Aug-2002 18:00:00 +0200\""\ |
52 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) | 52 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) |
53 | From: Fred Foobar <foobar@Blurdybloop.COM> | 53 | From: Fred Foobar <foobar@Blurdybloop.COM> |
54 | Subject: afternoon meeting again | 54 | Subject: afternoon meeting again |
... | @@ -72,7 +72,7 @@ imap4d_test "SELECT mbox"\ | ... | @@ -72,7 +72,7 @@ imap4d_test "SELECT mbox"\ |
72 | "OK" | 72 | "OK" |
73 | 73 | ||
74 | imap4d_test "FETCH 2:3 BODY\[\]"\ | 74 | imap4d_test "FETCH 2:3 BODY\[\]"\ |
75 | "2 FETCH (FLAGS (\\Seen) BODY\[\] {310}"\ | 75 | "2 FETCH (FLAGS (\\Seen) BODY\[\] {312}"\ |
76 | -literal\ | 76 | -literal\ |
77 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\ | 77 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\ |
78 | "From: Fred Foobar <foobar@Blurdybloop.COM>"\ | 78 | "From: Fred Foobar <foobar@Blurdybloop.COM>"\ |
... | @@ -83,9 +83,10 @@ imap4d_test "FETCH 2:3 BODY\[\]"\ | ... | @@ -83,9 +83,10 @@ imap4d_test "FETCH 2:3 BODY\[\]"\ |
83 | "Content-Type: TEXT/PLAIN; CHARSET=US-ASCII"\ | 83 | "Content-Type: TEXT/PLAIN; CHARSET=US-ASCII"\ |
84 | ""\ | 84 | ""\ |
85 | "Hello Joe, do you think we can meet at 3:30 tomorrow?"\ | 85 | "Hello Joe, do you think we can meet at 3:30 tomorrow?"\ |
86 | ""\ | ||
86 | ")"\ | 87 | ")"\ |
87 | -noliteral\ | 88 | -noliteral\ |
88 | "3 FETCH (FLAGS (\\Seen) BODY\[\] {283}"\ | 89 | "3 FETCH (FLAGS (\\Seen) BODY\[\] {285}"\ |
89 | -literal\ | 90 | -literal\ |
90 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\ | 91 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\ |
91 | "From: Fred Foobar <foobar@Blurdybloop.COM>"\ | 92 | "From: Fred Foobar <foobar@Blurdybloop.COM>"\ | ... | ... |
... | @@ -37,7 +37,7 @@ imap4d_test "CREATE flat" | ... | @@ -37,7 +37,7 @@ imap4d_test "CREATE flat" |
37 | 37 | ||
38 | imap4d_test "CREATE en/to/tre" | 38 | imap4d_test "CREATE en/to/tre" |
39 | 39 | ||
40 | imap4d_test -long "APPEND en/to/tre 25-Aug-2002 18:00:00 +0200"\ | 40 | imap4d_test -long "APPEND en/to/tre \"25-Aug-2002 18:00:00 +0200\""\ |
41 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) | 41 | "Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) |
42 | From: Fred Foobar <foobar@Blurdybloop.COM> | 42 | From: Fred Foobar <foobar@Blurdybloop.COM> |
43 | Subject: afternoon meeting again | 43 | Subject: afternoon meeting again |
... | @@ -65,7 +65,7 @@ imap4d_test "SELECT en/to/tre"\ | ... | @@ -65,7 +65,7 @@ imap4d_test "SELECT en/to/tre"\ |
65 | "OK \[READ-WRITE\] SELECT Completed" | 65 | "OK \[READ-WRITE\] SELECT Completed" |
66 | 66 | ||
67 | imap4d_test "FETCH 1 ALL"\ | 67 | imap4d_test "FETCH 1 ALL"\ |
68 | "1 FETCH (FLAGS (\\Recent) INTERNALDATE \"25-Aug-2002 16:00:00 +0000\" RFC822.SIZE 283 ENVELOPE (\"Mon, 7 Feb 1994 21:52:25 -0800 (PST)\" \"afternoon meeting again\" ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((NIL NIL \"mooch\" \"owatagu.siam.edu\")) NIL NIL NIL \"<B27397-0200000@Blurdybloop.COM>\"))"\ | 68 | "1 FETCH (FLAGS (\\Recent) INTERNALDATE \"25-Aug-2002 16:00:00 +0000\" RFC822.SIZE 285 ENVELOPE (\"Mon, 7 Feb 1994 21:52:25 -0800 (PST)\" \"afternoon meeting again\" ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((NIL NIL \"mooch\" \"owatagu.siam.edu\")) NIL NIL NIL \"<B27397-0200000@Blurdybloop.COM>\"))"\ |
69 | "OK" | 69 | "OK" |
70 | 70 | ||
71 | 71 | ... | ... |
... | @@ -165,7 +165,7 @@ imap4d_test "FETCH 1 BODY\[HEADER\]"\ | ... | @@ -165,7 +165,7 @@ imap4d_test "FETCH 1 BODY\[HEADER\]"\ |
165 | # The subset returned by HEADER.FIELDS contains only those header fields | 165 | # The subset returned by HEADER.FIELDS contains only those header fields |
166 | # with a field-name that matches one of the names in the list; | 166 | # with a field-name that matches one of the names in the list; |
167 | 167 | ||
168 | imap4d_test "FETCH 1 BODY\[HEADER.FIELDS FROM TO SUBJECT\]"\ | 168 | imap4d_test "FETCH 1 BODY\[HEADER.FIELDS (FROM TO SUBJECT)\]"\ |
169 | "1 FETCH (BODY\[HEADER.FIELDS (\"FROM\" \"TO\" \"SUBJECT\")\] {94}"\ | 169 | "1 FETCH (BODY\[HEADER.FIELDS (\"FROM\" \"TO\" \"SUBJECT\")\] {94}"\ |
170 | -literal\ | 170 | -literal\ |
171 | "FROM: Foo Bar <foobar@nonexistent.net>"\ | 171 | "FROM: Foo Bar <foobar@nonexistent.net>"\ |
... | @@ -178,7 +178,7 @@ imap4d_test "FETCH 1 BODY\[HEADER.FIELDS FROM TO SUBJECT\]"\ | ... | @@ -178,7 +178,7 @@ imap4d_test "FETCH 1 BODY\[HEADER.FIELDS FROM TO SUBJECT\]"\ |
178 | # similarly, the subset returned by HEADER.FIELDS.NOT contains only | 178 | # similarly, the subset returned by HEADER.FIELDS.NOT contains only |
179 | # the header fields with a non-matching field-name. | 179 | # the header fields with a non-matching field-name. |
180 | 180 | ||
181 | imap4d_test "FETCH 1 BODY\[HEADER.FIELDS.NOT FROM TO SUBJECT\]"\ | 181 | imap4d_test "FETCH 1 BODY\[HEADER.FIELDS.NOT (FROM TO SUBJECT)\]"\ |
182 | "1 FETCH (BODY\[HEADER.FIELDS.NOT (\"FROM\" \"TO\" \"SUBJECT\")\] {235}"\ | 182 | "1 FETCH (BODY\[HEADER.FIELDS.NOT (\"FROM\" \"TO\" \"SUBJECT\")\] {235}"\ |
183 | -literal\ | 183 | -literal\ |
184 | "Received: (from foobar@nonexistent.net) "\ | 184 | "Received: (from foobar@nonexistent.net) "\ |
... | @@ -330,8 +330,13 @@ imap4d_test "FETCH 3 BODY\[1.MIME\]"\ | ... | @@ -330,8 +330,13 @@ imap4d_test "FETCH 3 BODY\[1.MIME\]"\ |
330 | "OK" | 330 | "OK" |
331 | 331 | ||
332 | imap4d_test "FETCH 4 BODY\[2.2.1\]"\ | 332 | imap4d_test "FETCH 4 BODY\[2.2.1\]"\ |
333 | "4 FETCH (FLAGS (\\Seen) BODY\[2.2.1\] {490}"\ | 333 | "4 FETCH (FLAGS (\\Seen) BODY\[2.2.1\] {680}"\ |
334 | -literal\ | 334 | -literal\ |
335 | "Content-Type: application/octet-stream; name=\"msg.23\""\ | ||
336 | "Content-ID: <5122.1026510654.6@Mirddin.farlep.net>"\ | ||
337 | "Content-Description: Father William Part III"\ | ||
338 | "Content-Transfer-Encoding: base64"\ | ||
339 | ""\ | ||
335 | "YFlvdSBhcmUgb2xkLCcgc2FpZCB0aGUgeW91dGgsIGBhbmQgeW91ciBqYXdzIGFyZSB0b28gd2Vh"\ | 340 | "YFlvdSBhcmUgb2xkLCcgc2FpZCB0aGUgeW91dGgsIGBhbmQgeW91ciBqYXdzIGFyZSB0b28gd2Vh"\ |
336 | "awpGb3IgYW55dGhpbmcgdG91Z2hlciB0aGFuIHN1ZXQ7CllldCB5b3UgZmluaXNoZWQgdGhlIGdv"\ | 341 | "awpGb3IgYW55dGhpbmcgdG91Z2hlciB0aGFuIHN1ZXQ7CllldCB5b3UgZmluaXNoZWQgdGhlIGdv"\ |
337 | "b3NlLCB3aXRoIHRoZSBib25lcyBhbmQgdGhlIGJlYWstLQpQcmF5IGhvdyBkaWQgeW91IG1hbmFn"\ | 342 | "b3NlLCB3aXRoIHRoZSBib25lcyBhbmQgdGhlIGJlYWstLQpQcmF5IGhvdyBkaWQgeW91IG1hbmFn"\ | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -24,36 +24,29 @@ | ... | @@ -24,36 +24,29 @@ |
24 | */ | 24 | */ |
25 | 25 | ||
26 | int | 26 | int |
27 | imap4d_uid (struct imap4d_command *command, char *arg) | 27 | imap4d_uid (struct imap4d_command *command, imap4d_tokbuf_t tok) |
28 | { | 28 | { |
29 | char *cmd; | 29 | char *cmd; |
30 | char *sp = NULL; | ||
31 | int rc = RESP_NO; | 30 | int rc = RESP_NO; |
32 | char buffer[64]; | 31 | char *err_text = "Completed"; |
33 | 32 | ||
34 | cmd = util_getword (arg, &sp); | 33 | if (imap4d_tokbuf_argc (tok) < 3) |
35 | if (!cmd) | 34 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
36 | util_finish (command, RESP_BAD, "Too few args"); | 35 | |
36 | cmd = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); | ||
37 | |||
37 | if (strcasecmp (cmd, "FETCH") == 0) | 38 | if (strcasecmp (cmd, "FETCH") == 0) |
38 | { | 39 | rc = imap4d_fetch0 (tok, 1, &err_text); |
39 | rc = imap4d_fetch0 (sp, 1, buffer, sizeof buffer); | ||
40 | } | ||
41 | else if (strcasecmp (cmd, "COPY") == 0) | 40 | else if (strcasecmp (cmd, "COPY") == 0) |
42 | { | 41 | rc = imap4d_copy0 (tok, 1, &err_text); |
43 | rc = imap4d_copy0 (sp, 1, buffer, sizeof buffer); | ||
44 | } | ||
45 | else if (strcasecmp (cmd, "STORE") == 0) | 42 | else if (strcasecmp (cmd, "STORE") == 0) |
46 | { | 43 | rc = imap4d_store0 (tok, 1, &err_text); |
47 | rc = imap4d_store0 (sp, 1, buffer, sizeof buffer); | ||
48 | } | ||
49 | else if (strcasecmp (cmd, "SEARCH") == 0) | 44 | else if (strcasecmp (cmd, "SEARCH") == 0) |
50 | { | 45 | rc = imap4d_search0 (tok, 1, &err_text); |
51 | rc = imap4d_search0 (sp, 1, buffer, sizeof buffer); | ||
52 | } | ||
53 | else | 46 | else |
54 | { | 47 | { |
55 | snprintf (buffer, sizeof buffer, "Error uknown uid command"); | 48 | err_text = "Uknown uid command"; |
56 | rc = RESP_BAD; | 49 | rc = RESP_BAD; |
57 | } | 50 | } |
58 | return util_finish (command, rc, "%s %s", cmd, buffer); | 51 | return util_finish (command, rc, "%s %s", cmd, err_text); |
59 | } | 52 | } | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -71,19 +71,34 @@ unsubscribe (struct scan_data *data, char *name) | ... | @@ -71,19 +71,34 @@ unsubscribe (struct scan_data *data, char *name) |
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | /* | ||
75 | 6.3.7. UNSUBSCRIBE Command | ||
76 | |||
77 | Arguments: mailbox name | ||
78 | |||
79 | Responses: no specific responses for this command | ||
80 | |||
81 | Result: OK - unsubscribe completed | ||
82 | NO - unsubscribe failure: can't unsubscribe that name | ||
83 | BAD - command unknown or arguments invalid | ||
84 | |||
85 | The UNSUBSCRIBE command removes the specified mailbox name from | ||
86 | the server's set of "active" or "subscribed" mailboxes as returned | ||
87 | by the LSUB command. This command returns a tagged OK response | ||
88 | only if the unsubscription is successful. | ||
89 | */ | ||
74 | int | 90 | int |
75 | imap4d_unsubscribe (struct imap4d_command *command, char *arg) | 91 | imap4d_unsubscribe (struct imap4d_command *command, imap4d_tokbuf_t tok) |
76 | { | 92 | { |
77 | char *sp = NULL; | ||
78 | char *name; | 93 | char *name; |
79 | char *file; | 94 | char *file; |
80 | struct scan_data sd; | 95 | struct scan_data sd; |
81 | int rc; | 96 | int rc; |
82 | 97 | ||
83 | name = util_getword (arg, &sp); | 98 | if (imap4d_tokbuf_argc (tok) != 3) |
84 | util_unquote (&name); | 99 | return util_finish (command, RESP_BAD, "Invalid arguments"); |
85 | if (!name || *name == '\0') | 100 | |
86 | return util_finish (command, RESP_BAD, "Too few arguments"); | 101 | name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1); |
87 | 102 | ||
88 | asprintf (&file, "%s/.mailboxlist", homedir); | 103 | asprintf (&file, "%s/.mailboxlist", homedir); |
89 | sd.result = 0; | 104 | sd.result = 0; | ... | ... |
This diff is collapsed.
Click to expand it.
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -19,8 +19,10 @@ | ... | @@ -19,8 +19,10 @@ |
19 | #include "imap4d.h" | 19 | #include "imap4d.h" |
20 | 20 | ||
21 | int | 21 | int |
22 | imap4d_version (struct imap4d_command *command, char *arg) | 22 | imap4d_version (struct imap4d_command *command, imap4d_tokbuf_t tok) |
23 | { | 23 | { |
24 | if (imap4d_tokbuf_argc (tok) != 2) | ||
25 | return util_finish (command, RESP_BAD, "Invalid arguments"); | ||
24 | util_send ("* %s GNU %s\r\n", command->name, program_version); | 26 | util_send ("* %s GNU %s\r\n", command->name, program_version); |
25 | return util_finish (command, RESP_OK, "Completed"); | 27 | return util_finish (command, RESP_OK, "Completed"); |
26 | } | 28 | } | ... | ... |
... | @@ -145,7 +145,7 @@ mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox) | ... | @@ -145,7 +145,7 @@ mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox) |
145 | } | 145 | } |
146 | 146 | ||
147 | mu_stream_flush (mtmp->stream); | 147 | mu_stream_flush (mtmp->stream); |
148 | if ((status = mu_mailbox_create (mbox, "/dev/null")) | 148 | if ((status = mu_mailbox_create (mbox, "mbox:/dev/null")) |
149 | || (status = mu_mailbox_open (*mbox, MU_STREAM_READ)) | 149 | || (status = mu_mailbox_open (*mbox, MU_STREAM_READ)) |
150 | || (status = mu_mailbox_set_stream (*mbox, mtmp->stream))) | 150 | || (status = mu_mailbox_set_stream (*mbox, mtmp->stream))) |
151 | { | 151 | { | ... | ... |
... | @@ -51,7 +51,7 @@ _memory_destroy (mu_stream_t stream) | ... | @@ -51,7 +51,7 @@ _memory_destroy (mu_stream_t stream) |
51 | struct _memory_stream *mfs = mu_stream_get_owner (stream); | 51 | struct _memory_stream *mfs = mu_stream_get_owner (stream); |
52 | if (mfs && mfs->ptr != NULL) | 52 | if (mfs && mfs->ptr != NULL) |
53 | free (mfs->ptr); | 53 | free (mfs->ptr); |
54 | if(mfs->filename) | 54 | if (mfs->filename) |
55 | free (mfs->filename); | 55 | free (mfs->filename); |
56 | free (mfs); | 56 | free (mfs); |
57 | } | 57 | } | ... | ... |
-
Please register or sign in to post a comment