imap client: implement login and id commands.
* libproto/imap/id.c: New file. * libproto/imap/login.c: New file. * libproto/imap/Makefile.am: Add new files. * libproto/imap/capability.c (mu_imap_capability): Clear MU_IMAP_RESP before reading response. Add MU_WRDSF_QUOTE to mu_wordsplit flags. * libproto/imap/err.c (_mu_imap_seterrstr): Bugfix: initialize imap->errstr. * libproto/imap/logout.c (mu_imap_logout): Clear MU_IMAP_RESP before reading response. * libproto/imap/response.c (_mu_imap_response): Set error string. * mu/imap.c (com_login, com_id): New functions. (imap_comtab) <login, id>: New keywords.
Showing
11 changed files
with
394 additions
and
9 deletions
... | @@ -49,8 +49,11 @@ int mu_imap_disconnect (mu_imap_t imap); | ... | @@ -49,8 +49,11 @@ int mu_imap_disconnect (mu_imap_t imap); |
49 | int mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter); | 49 | int mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter); |
50 | int mu_imap_capability_test (mu_imap_t imap, const char *name, | 50 | int mu_imap_capability_test (mu_imap_t imap, const char *name, |
51 | const char **pret); | 51 | const char **pret); |
52 | 52 | ||
53 | int mu_imap_login (mu_imap_t imap, const char *user, const char *pass); | ||
53 | int mu_imap_logout (mu_imap_t imap); | 54 | int mu_imap_logout (mu_imap_t imap); |
55 | |||
56 | int mu_imap_id (mu_imap_t imap, char **idenv, mu_list_t *plist); | ||
54 | 57 | ||
55 | int mu_imap_set_carrier (mu_imap_t imap, mu_stream_t carrier); | 58 | int mu_imap_set_carrier (mu_imap_t imap, mu_stream_t carrier); |
56 | int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier); | 59 | int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier); | ... | ... |
... | @@ -40,7 +40,9 @@ enum mu_imap_client_state | ... | @@ -40,7 +40,9 @@ enum mu_imap_client_state |
40 | MU_IMAP_GREETINGS, | 40 | MU_IMAP_GREETINGS, |
41 | MU_IMAP_CONNECTED, | 41 | MU_IMAP_CONNECTED, |
42 | MU_IMAP_CAPABILITY_RX, | 42 | MU_IMAP_CAPABILITY_RX, |
43 | MU_IMAP_LOGIN_RX, | ||
43 | MU_IMAP_LOGOUT_RX, | 44 | MU_IMAP_LOGOUT_RX, |
45 | MU_IMAP_ID_RX, | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | enum mu_imap_response | 48 | enum mu_imap_response | ... | ... |
... | @@ -33,6 +33,7 @@ struct mu_kwd bool_keytab[] = { | ... | @@ -33,6 +33,7 @@ struct mu_kwd bool_keytab[] = { |
33 | /*{ "reuse", MU_WRDSF_REUSE },*/ | 33 | /*{ "reuse", MU_WRDSF_REUSE },*/ |
34 | { "undef", MU_WRDSF_UNDEF }, | 34 | { "undef", MU_WRDSF_UNDEF }, |
35 | { "novar", MU_WRDSF_NOVAR }, | 35 | { "novar", MU_WRDSF_NOVAR }, |
36 | { "nocmd", MU_WRDSF_NOCMD }, | ||
36 | { "ws", MU_WRDSF_WS }, | 37 | { "ws", MU_WRDSF_WS }, |
37 | { "quote", MU_WRDSF_QUOTE }, | 38 | { "quote", MU_WRDSF_QUOTE }, |
38 | { "squeeze_delims", MU_WRDSF_SQUEEZE_DELIMS }, | 39 | { "squeeze_delims", MU_WRDSF_SQUEEZE_DELIMS }, |
... | @@ -205,7 +206,7 @@ main (int argc, char **argv) | ... | @@ -205,7 +206,7 @@ main (int argc, char **argv) |
205 | plaintext_option = !negate; | 206 | plaintext_option = !negate; |
206 | continue; | 207 | continue; |
207 | } | 208 | } |
208 | 209 | ||
209 | if (mu_kwd_xlat_name (bool_keytab, opt, &flag) == 0) | 210 | if (mu_kwd_xlat_name (bool_keytab, opt, &flag) == 0) |
210 | { | 211 | { |
211 | if (negate) | 212 | if (negate) | ... | ... |
... | @@ -81,6 +81,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter) | ... | @@ -81,6 +81,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter) |
81 | status = mu_stream_printf (imap->carrier, "%s CAPABILITY\r\n", | 81 | status = mu_stream_printf (imap->carrier, "%s CAPABILITY\r\n", |
82 | imap->tag_str); | 82 | imap->tag_str); |
83 | MU_IMAP_CHECK_EAGAIN (imap, status); | 83 | MU_IMAP_CHECK_EAGAIN (imap, status); |
84 | MU_IMAP_FCLR (imap, MU_IMAP_RESP); | ||
84 | imap->state = MU_IMAP_CAPABILITY_RX; | 85 | imap->state = MU_IMAP_CAPABILITY_RX; |
85 | 86 | ||
86 | case MU_IMAP_CAPABILITY_RX: | 87 | case MU_IMAP_CAPABILITY_RX: |
... | @@ -103,7 +104,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter) | ... | @@ -103,7 +104,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter) |
103 | 104 | ||
104 | if (mu_wordsplit (str, &ws, | 105 | if (mu_wordsplit (str, &ws, |
105 | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | | 106 | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | |
106 | MU_WRDSF_SQUEEZE_DELIMS)) | 107 | MU_WRDSF_QUOTE | MU_WRDSF_SQUEEZE_DELIMS)) |
107 | { | 108 | { |
108 | int ec = errno; | 109 | int ec = errno; |
109 | mu_error ("mu_imap_capability: cannot split line: %s", | 110 | mu_error ("mu_imap_capability: cannot split line: %s", | ... | ... |
... | @@ -32,6 +32,7 @@ _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) | ... | @@ -32,6 +32,7 @@ _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len) |
32 | if (!p) | 32 | if (!p) |
33 | return ENOMEM; | 33 | return ENOMEM; |
34 | imap->errsize = len + 1; | 34 | imap->errsize = len + 1; |
35 | imap->errstr = p; | ||
35 | } | 36 | } |
36 | memcpy (imap->errstr, str, len); | 37 | memcpy (imap->errstr, str, len); |
37 | imap->errstr[len] = 0; | 38 | imap->errstr[len] = 0; | ... | ... |
libproto/imap/id.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include <mailutils/cstr.h> | ||
26 | #include <mailutils/wordsplit.h> | ||
27 | #include <mailutils/stream.h> | ||
28 | #include <mailutils/sys/imap.h> | ||
29 | |||
30 | static int | ||
31 | id_comp (const void *item, const void *value) | ||
32 | { | ||
33 | const char *id = item; | ||
34 | const char *needle = value; | ||
35 | return mu_c_strcasecmp (id, needle); | ||
36 | } | ||
37 | |||
38 | static int | ||
39 | parse_id_reply (mu_imap_t imap, mu_list_t *plist) | ||
40 | { | ||
41 | mu_list_t list; | ||
42 | int rc; | ||
43 | const char *response; | ||
44 | struct mu_wordsplit ws; | ||
45 | size_t i; | ||
46 | |||
47 | rc = mu_list_create (&list); | ||
48 | if (rc) | ||
49 | return rc; | ||
50 | mu_list_set_comparator (list, id_comp); | ||
51 | mu_list_set_destroy_item (list, mu_list_free_item); | ||
52 | |||
53 | rc = mu_list_get (imap->untagged_resp, 0, (void*) &response); | ||
54 | if (rc == MU_ERR_NOENT) | ||
55 | { | ||
56 | *plist = list; | ||
57 | return 0; | ||
58 | } | ||
59 | else if (rc) | ||
60 | { | ||
61 | mu_list_destroy (&list); | ||
62 | return rc; | ||
63 | } | ||
64 | |||
65 | ws.ws_delim = "() \t"; | ||
66 | if (mu_wordsplit (response, &ws, | ||
67 | MU_WRDSF_NOVAR | MU_WRDSF_NOCMD | | ||
68 | MU_WRDSF_QUOTE | MU_WRDSF_DELIM | | ||
69 | MU_WRDSF_SQUEEZE_DELIMS | | ||
70 | MU_WRDSF_WS)) | ||
71 | { | ||
72 | int ec = errno; | ||
73 | mu_error ("mu_imap_id: cannot split line: %s", | ||
74 | mu_wordsplit_strerror (&ws)); | ||
75 | mu_list_destroy (&list); | ||
76 | return ec; | ||
77 | } | ||
78 | |||
79 | for (i = 1; i < ws.ws_wordc; i += 2) | ||
80 | { | ||
81 | size_t len, l1, l2; | ||
82 | char *elt; | ||
83 | |||
84 | if (i + 1 == ws.ws_wordc) | ||
85 | break; | ||
86 | l1 = strlen (ws.ws_wordv[i]); | ||
87 | l2 = strlen (ws.ws_wordv[i+1]); | ||
88 | len = l1 + l2 + 1; | ||
89 | elt = malloc (len + 1); | ||
90 | if (!elt) | ||
91 | break; | ||
92 | |||
93 | memcpy (elt, ws.ws_wordv[i], l1); | ||
94 | elt[l1] = 0; | ||
95 | memcpy (elt + l1 + 1, ws.ws_wordv[i+1], l2); | ||
96 | elt[len] = 0; | ||
97 | mu_list_append (list, elt); | ||
98 | } | ||
99 | mu_wordsplit_free (&ws); | ||
100 | *plist = list; | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | int | ||
105 | mu_imap_id (mu_imap_t imap, char **idenv, mu_list_t *plist) | ||
106 | { | ||
107 | int status; | ||
108 | |||
109 | if (imap == NULL) | ||
110 | return EINVAL; | ||
111 | if (!imap->carrier) | ||
112 | return MU_ERR_NO_TRANSPORT; | ||
113 | if (imap->state != MU_IMAP_CONNECTED) | ||
114 | return MU_ERR_SEQ; | ||
115 | |||
116 | switch (imap->state) | ||
117 | { | ||
118 | case MU_IMAP_CONNECTED: | ||
119 | status = _mu_imap_tag_next (imap); | ||
120 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
121 | status = mu_stream_printf (imap->carrier, "%s ID ", | ||
122 | imap->tag_str); | ||
123 | MU_IMAP_CHECK_ERROR (imap, status); | ||
124 | if (!idenv) | ||
125 | status = mu_stream_printf (imap->carrier, "NIL"); | ||
126 | else | ||
127 | { | ||
128 | if (idenv[0]) | ||
129 | { | ||
130 | int i; | ||
131 | char *delim = "("; | ||
132 | for (i = 0; idenv[i]; i++) | ||
133 | { | ||
134 | status = mu_stream_printf (imap->carrier, "%s\"%s\"", | ||
135 | delim, idenv[i]); | ||
136 | MU_IMAP_CHECK_ERROR (imap, status); | ||
137 | |||
138 | delim = " "; | ||
139 | if (status) | ||
140 | break; | ||
141 | } | ||
142 | status = mu_stream_printf (imap->carrier, ")"); | ||
143 | } | ||
144 | else | ||
145 | status = mu_stream_printf (imap->carrier, "()"); | ||
146 | } | ||
147 | MU_IMAP_CHECK_ERROR (imap, status); | ||
148 | status = mu_stream_printf (imap->carrier, "\r\n"); | ||
149 | MU_IMAP_CHECK_ERROR (imap, status); | ||
150 | MU_IMAP_FCLR (imap, MU_IMAP_RESP); | ||
151 | imap->state = MU_IMAP_ID_RX; | ||
152 | |||
153 | case MU_IMAP_ID_RX: | ||
154 | status = _mu_imap_response (imap); | ||
155 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
156 | switch (imap->resp_code) | ||
157 | { | ||
158 | case MU_IMAP_OK: | ||
159 | imap->imap_state = MU_IMAP_STATE_AUTH; | ||
160 | if (plist) | ||
161 | status = parse_id_reply (imap, plist); | ||
162 | break; | ||
163 | |||
164 | case MU_IMAP_NO: | ||
165 | status = EACCES; | ||
166 | break; | ||
167 | |||
168 | case MU_IMAP_BAD: | ||
169 | status = MU_ERR_BADREPLY; | ||
170 | break; | ||
171 | } | ||
172 | imap->state = MU_IMAP_CONNECTED; | ||
173 | break; | ||
174 | |||
175 | default: | ||
176 | status = EINPROGRESS; | ||
177 | } | ||
178 | return status; | ||
179 | } | ||
180 |
libproto/imap/login.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU Lesser General Public | ||
6 | License as published by the Free Software Foundation; either | ||
7 | version 3 of the License, or (at your option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General | ||
15 | Public License along with this library. If not, see | ||
16 | <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #include <mailutils/errno.h> | ||
23 | #include <mailutils/stream.h> | ||
24 | #include <mailutils/sys/imap.h> | ||
25 | |||
26 | int | ||
27 | mu_imap_login (mu_imap_t imap, const char *user, const char *pass) | ||
28 | { | ||
29 | int status; | ||
30 | |||
31 | if (imap == NULL) | ||
32 | return EINVAL; | ||
33 | if (!imap->carrier) | ||
34 | return MU_ERR_NO_TRANSPORT; | ||
35 | if (imap->state != MU_IMAP_CONNECTED) | ||
36 | return MU_ERR_SEQ; | ||
37 | if (imap->imap_state != MU_IMAP_STATE_NONAUTH) | ||
38 | return MU_ERR_SEQ; | ||
39 | |||
40 | switch (imap->state) | ||
41 | { | ||
42 | case MU_IMAP_CONNECTED: | ||
43 | if (mu_imap_trace_mask (imap, MU_IMAP_TRACE_QRY, MU_XSCRIPT_SECURE)) | ||
44 | _mu_imap_xscript_level (imap, MU_XSCRIPT_SECURE); | ||
45 | status = _mu_imap_tag_next (imap); | ||
46 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
47 | status = mu_stream_printf (imap->carrier, "%s LOGIN \"%s\" \"%s\"\r\n", | ||
48 | imap->tag_str, user, pass); | ||
49 | _mu_imap_xscript_level (imap, MU_XSCRIPT_NORMAL); | ||
50 | /* FIXME: how to obscure the passwd in the stream buffer? */ | ||
51 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
52 | MU_IMAP_FCLR (imap, MU_IMAP_RESP); | ||
53 | imap->state = MU_IMAP_LOGIN_RX; | ||
54 | |||
55 | case MU_IMAP_LOGIN_RX: | ||
56 | status = _mu_imap_response (imap); | ||
57 | MU_IMAP_CHECK_EAGAIN (imap, status); | ||
58 | switch (imap->resp_code) | ||
59 | { | ||
60 | case MU_IMAP_OK: | ||
61 | imap->imap_state = MU_IMAP_STATE_AUTH; | ||
62 | break; | ||
63 | |||
64 | case MU_IMAP_NO: | ||
65 | status = EACCES; | ||
66 | break; | ||
67 | |||
68 | case MU_IMAP_BAD: | ||
69 | status = MU_ERR_BADREPLY; | ||
70 | break; | ||
71 | } | ||
72 | imap->state = MU_IMAP_CONNECTED; | ||
73 | break; | ||
74 | |||
75 | default: | ||
76 | status = EINPROGRESS; | ||
77 | } | ||
78 | return status; | ||
79 | } | ||
80 |
... | @@ -43,6 +43,7 @@ mu_imap_logout (mu_imap_t imap) | ... | @@ -43,6 +43,7 @@ mu_imap_logout (mu_imap_t imap) |
43 | status = mu_stream_printf (imap->carrier, "%s LOGOUT\r\n", | 43 | status = mu_stream_printf (imap->carrier, "%s LOGOUT\r\n", |
44 | imap->tag_str); | 44 | imap->tag_str); |
45 | MU_IMAP_CHECK_EAGAIN (imap, status); | 45 | MU_IMAP_CHECK_EAGAIN (imap, status); |
46 | MU_IMAP_FCLR (imap, MU_IMAP_RESP); | ||
46 | imap->state = MU_IMAP_LOGOUT_RX; | 47 | imap->state = MU_IMAP_LOGOUT_RX; |
47 | 48 | ||
48 | case MU_IMAP_LOGOUT_RX: | 49 | case MU_IMAP_LOGOUT_RX: | ... | ... |
... | @@ -85,12 +85,24 @@ _mu_imap_response (mu_imap_t imap) | ... | @@ -85,12 +85,24 @@ _mu_imap_response (mu_imap_t imap) |
85 | imap->tagbuf = np; | 85 | imap->tagbuf = np; |
86 | } | 86 | } |
87 | strcpy (imap->tagbuf, p); | 87 | strcpy (imap->tagbuf, p); |
88 | if (IS_PREFIX(p, len, "OK")) | 88 | if (IS_PREFIX (p, len, "OK")) |
89 | imap->resp_code = MU_IMAP_OK; | 89 | { |
90 | else if (IS_PREFIX(p, len, "NO")) | 90 | imap->resp_code = MU_IMAP_OK; |
91 | imap->resp_code = MU_IMAP_NO; | 91 | p = mu_str_skip_cset (p + 2, " "); |
92 | else if (IS_PREFIX(p, len, "BAD")) | 92 | _mu_imap_seterrstr (imap, p, strlen (p)); |
93 | imap->resp_code = MU_IMAP_BAD; | 93 | } |
94 | else if (IS_PREFIX (p, len, "NO")) | ||
95 | { | ||
96 | imap->resp_code = MU_IMAP_NO; | ||
97 | p = mu_str_skip_cset (p + 2, " "); | ||
98 | _mu_imap_seterrstr (imap, p, strlen (p)); | ||
99 | } | ||
100 | else if (IS_PREFIX (p, len, "BAD")) | ||
101 | { | ||
102 | imap->resp_code = MU_IMAP_BAD; | ||
103 | p = mu_str_skip_cset (p + 2, " "); | ||
104 | _mu_imap_seterrstr (imap, p, strlen (p)); | ||
105 | } | ||
94 | else | 106 | else |
95 | status = MU_ERR_BADREPLY; | 107 | status = MU_ERR_BADREPLY; |
96 | MU_IMAP_FSET (imap, MU_IMAP_RESP); | 108 | MU_IMAP_FSET (imap, MU_IMAP_RESP); | ... | ... |
... | @@ -358,6 +358,102 @@ com_capability (int argc, char **argv) | ... | @@ -358,6 +358,102 @@ com_capability (int argc, char **argv) |
358 | return status; | 358 | return status; |
359 | } | 359 | } |
360 | 360 | ||
361 | static int | ||
362 | com_login (int argc, char **argv) | ||
363 | { | ||
364 | int status; | ||
365 | char *pwd, *passbuf = NULL; | ||
366 | |||
367 | if (argc == 2) | ||
368 | { | ||
369 | if (!mutool_shell_interactive) | ||
370 | { | ||
371 | mu_error (_("login: password required")); | ||
372 | return 1; | ||
373 | } | ||
374 | status = mu_getpass (mustrin, mustrout, "Password:", &passbuf); | ||
375 | if (status) | ||
376 | return status; | ||
377 | pwd = passbuf; | ||
378 | } | ||
379 | else | ||
380 | pwd = argv[2]; | ||
381 | |||
382 | status = mu_imap_login (imap, argv[1], pwd); | ||
383 | memset (pwd, 0, strlen (pwd)); | ||
384 | free (passbuf); | ||
385 | if (status == 0) | ||
386 | imap_prompt_env (); | ||
387 | else | ||
388 | { | ||
389 | const char *str; | ||
390 | |||
391 | mu_error ("authentication failed: %s", mu_strerror (status)); | ||
392 | if (mu_imap_strerror (imap, &str) == 0) | ||
393 | mu_error ("server reply: %s", str); | ||
394 | } | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | |||
399 | static int | ||
400 | _print_id (void *item, void *data) | ||
401 | { | ||
402 | const char *id = item; | ||
403 | mu_stream_printf (mustrout, "ID: %s %s\n", id, id + strlen (id) + 1); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int | ||
408 | com_id (int argc, char **argv) | ||
409 | { | ||
410 | mu_list_t list; | ||
411 | char *test = NULL; | ||
412 | int status; | ||
413 | |||
414 | argv++; | ||
415 | if (argv[0] && strcmp (argv[0], "-test") == 0) | ||
416 | { | ||
417 | argv++; | ||
418 | if (argv[0] == NULL) | ||
419 | { | ||
420 | mu_error ("id -test requires an argument"); | ||
421 | return 0; | ||
422 | } | ||
423 | test = argv[0]; | ||
424 | argv++; | ||
425 | } | ||
426 | |||
427 | status = mu_imap_id (imap, argv + 1, &list); | ||
428 | if (status == 0) | ||
429 | { | ||
430 | if (test) | ||
431 | { | ||
432 | const char *res; | ||
433 | int rc = mu_list_locate (list, test, (void*)&res); | ||
434 | |||
435 | switch (rc) | ||
436 | { | ||
437 | case 0: | ||
438 | mu_stream_printf (mustrout, "%s: %s\n", test, | ||
439 | res + strlen (res) + 1); | ||
440 | break; | ||
441 | |||
442 | case MU_ERR_NOENT: | ||
443 | mu_stream_printf (mustrout, "%s is not set\n", test); | ||
444 | break; | ||
445 | |||
446 | default: | ||
447 | return rc; | ||
448 | } | ||
449 | } | ||
450 | else | ||
451 | mu_list_do (list, _print_id, NULL); | ||
452 | mu_list_destroy (&list); | ||
453 | } | ||
454 | return status; | ||
455 | } | ||
456 | |||
361 | 457 | ||
362 | struct mutool_command imap_comtab[] = { | 458 | struct mutool_command imap_comtab[] = { |
363 | { "capability", 1, -1, com_capability, | 459 | { "capability", 1, -1, com_capability, |
... | @@ -375,9 +471,15 @@ struct mutool_command imap_comtab[] = { | ... | @@ -375,9 +471,15 @@ struct mutool_command imap_comtab[] = { |
375 | com_disconnect, | 471 | com_disconnect, |
376 | NULL, | 472 | NULL, |
377 | N_("close connection") }, | 473 | N_("close connection") }, |
474 | { "login", 2, 3, com_login, | ||
475 | N_("USER [PASS]"), | ||
476 | N_("login to the server") }, | ||
378 | { "logout", 1, 1, com_logout, | 477 | { "logout", 1, 1, com_logout, |
379 | NULL, | 478 | NULL, |
380 | N_("quit imap session") }, | 479 | N_("quit imap session") }, |
480 | { "id", 1, -1, com_id, | ||
481 | N_("[-test KW] [ARG [ARG...]]"), | ||
482 | N_("send ID command") }, | ||
381 | { "quit", 1, 1, com_logout, | 483 | { "quit", 1, 1, com_logout, |
382 | NULL, | 484 | NULL, |
383 | N_("same as `logout'") }, | 485 | N_("same as `logout'") }, | ... | ... |
-
Please register or sign in to post a comment