Commit 31459010 31459010ef8c1bf790b769260788982c714624d7 by Sergey Poznyakoff

Imap client: quote command arguments as necessary.

* include/mailutils/imapio.h (mu_imapio_send_command)
(mu_imapio_send_command_e,mu_imapio_send_command_v)
(mu_imapio_last_error,mu_imapio_clearerr): New protos.
* include/mailutils/sys/imap.h (imap_command)<uid>: Remove.
<extra>: New member.
* libmailutils/imapio/Makefile.am (libimapio_la_SOURCES): Add new files.
* libmailutils/imapio/qstring.c (mu_imapio_send_qstring_unfold): Improve
functionality.
* libmailutils/imapio/sendcmd.c: New file.
* libmailutils/imapio/sendcmde.c: New file.
* libmailutils/imapio/sendcmdv.c: New file.
* libmailutils/imapio/errstate.c: New file.

* libproto/imap/gencom.c (mu_imap_gencom): Use mu_imapio_send_command_v
* libproto/imap/appstrsiz.c: Quote command arguments as necessary.
* libproto/imap/capability.c: Likewise.
* libproto/imap/check.c: Likewise.
* libproto/imap/close.c: Likewise.
* libproto/imap/copy.c: Likewise.
* libproto/imap/delete.c: Likewise.
* libproto/imap/expunge.c: Likewise.
* libproto/imap/fetch.c: Likewise.
* libproto/imap/list.c: Likewise.
* libproto/imap/login.c: Likewise.
* libproto/imap/mbcreate.c: Likewise.
* libproto/imap/noop.c: Likewise.
* libproto/imap/rename.c: Likewise.
* libproto/imap/select.c: Likewise.
* libproto/imap/store.c: Likewise.
* libproto/imap/unselect.c: Likewise.
1 parent 7e78c6af
...@@ -45,6 +45,13 @@ int mu_imapio_send_qstring (struct _mu_imapio *io, const char *buffer); ...@@ -45,6 +45,13 @@ int mu_imapio_send_qstring (struct _mu_imapio *io, const char *buffer);
45 int mu_imapio_send_qstring_unfold (struct _mu_imapio *io, const char *buffer, 45 int mu_imapio_send_qstring_unfold (struct _mu_imapio *io, const char *buffer,
46 int unfold); 46 int unfold);
47 47
48 int mu_imapio_send_command_v (struct _mu_imapio *io, const char *tag,
49 int argc, char const **argv, const char *extra);
50 int mu_imapio_send_command (struct _mu_imapio *io, const char *tag,
51 char const *cmd, ...);
52 int mu_imapio_send_command_e (struct _mu_imapio *io, const char *tag,
53 char const *cmd, ...);
54
48 int mu_imapio_send_flags (struct _mu_imapio *io, int flags); 55 int mu_imapio_send_flags (struct _mu_imapio *io, int flags);
49 int mu_imapio_send_time (struct _mu_imapio *io, struct tm *tm, 56 int mu_imapio_send_time (struct _mu_imapio *io, struct tm *tm,
50 struct mu_timezone *tz); 57 struct mu_timezone *tz);
...@@ -59,6 +66,9 @@ int mu_imapio_getbuf (mu_imapio_t io, char **pptr, size_t *psize); ...@@ -59,6 +66,9 @@ int mu_imapio_getbuf (mu_imapio_t io, char **pptr, size_t *psize);
59 66
60 int mu_imapio_reply_string (struct _mu_imapio *io, size_t start, char **pbuf); 67 int mu_imapio_reply_string (struct _mu_imapio *io, size_t start, char **pbuf);
61 68
69 int mu_imapio_last_error (struct _mu_imapio *io);
70 void mu_imapio_clearerr (struct _mu_imapio *io);
71
62 int mu_imap_flag_to_attribute (const char *item, int *attr); 72 int mu_imap_flag_to_attribute (const char *item, int *attr);
63 int mu_imap_format_flags (mu_stream_t str, int flags); 73 int mu_imap_format_flags (mu_stream_t str, int flags);
64 74
......
...@@ -144,9 +144,9 @@ struct imap_command ...@@ -144,9 +144,9 @@ struct imap_command
144 int session_state; 144 int session_state;
145 char *capa; 145 char *capa;
146 int rx_state; 146 int rx_state;
147 int uid;
148 int argc; 147 int argc;
149 char const **argv; 148 char const **argv;
149 char const *extra;
150 void (*tagged_handler) (mu_imap_t); 150 void (*tagged_handler) (mu_imap_t);
151 mu_imap_response_action_t untagged_handler; 151 mu_imap_response_action_t untagged_handler;
152 void *untagged_handler_data; 152 void *untagged_handler_data;
......
...@@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libimapio.la ...@@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libimapio.la
19 19
20 libimapio_la_SOURCES = \ 20 libimapio_la_SOURCES = \
21 create.c\ 21 create.c\
22 errstate.c\
22 flags.c\ 23 flags.c\
23 getline.c\ 24 getline.c\
24 litstream.c\ 25 litstream.c\
...@@ -27,6 +28,9 @@ libimapio_la_SOURCES = \ ...@@ -27,6 +28,9 @@ libimapio_la_SOURCES = \
27 qstring.c\ 28 qstring.c\
28 replstr.c\ 29 replstr.c\
29 send.c\ 30 send.c\
31 sendcmd.c\
32 sendcmdv.c\
33 sendcmde.c\
30 time.c\ 34 time.c\
31 trace.c\ 35 trace.c\
32 words.c\ 36 words.c\
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
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
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <mailutils/stream.h>
19 #include <mailutils/sys/imapio.h>
20
21 int
22 mu_imapio_last_error (struct _mu_imapio *io)
23 {
24 return mu_stream_last_error (io->_imap_stream);
25 }
26
27 void
28 mu_imapio_clearerr (struct _mu_imapio *io)
29 {
30 mu_stream_clearerr (io->_imap_stream);
31 }
32
33
...@@ -19,50 +19,80 @@ ...@@ -19,50 +19,80 @@
19 #include <mailutils/types.h> 19 #include <mailutils/types.h>
20 #include <mailutils/imapio.h> 20 #include <mailutils/imapio.h>
21 #include <mailutils/stream.h> 21 #include <mailutils/stream.h>
22 #include <mailutils/cstr.h>
23 #include <mailutils/cctype.h>
22 #include <mailutils/sys/imapio.h> 24 #include <mailutils/sys/imapio.h>
23 25
24 /* Send NIL if empty string, change the quoted string to a literal if the 26 /* If string is NULL, send NIL.
25 string contains: double quotes, CR, LF, or \. */ 27 If it contains \r\n, send it as a literal, replacing
28 contiguous sequences of \r\n by a single space, if UNFOLD is set.
29 If string contains " or \, quote it,
30 Otherwise send it as is. */
26 31
27 int 32 int
28 mu_imapio_send_qstring_unfold (struct _mu_imapio *io, const char *buffer, 33 mu_imapio_send_qstring_unfold (struct _mu_imapio *io, const char *buffer,
29 int unfold) 34 int unfold)
30 { 35 {
31 if (buffer == NULL || *buffer == '\0') 36 int len;
37
38 if (buffer == NULL)
32 return mu_imapio_printf (io, "NIL"); 39 return mu_imapio_printf (io, "NIL");
33 if (strchr (buffer, '"') || 40
34 strchr (buffer, '\r') || 41 if (buffer[len = strcspn (buffer, "\r\n")])
35 strchr (buffer, '\n') ||
36 strchr (buffer, '\\'))
37 { 42 {
38 if (unfold) 43 if (unfold)
39 { 44 {
40 int rc; 45 int rc;
41 size_t len = strlen (buffer); 46 size_t size = strlen (buffer);
42 47
43 rc = mu_stream_printf (io->_imap_stream, 48 rc = mu_stream_printf (io->_imap_stream,
44 "{%lu}\n", (unsigned long) strlen (buffer)); 49 "{%lu}\n", (unsigned long) size);
45 if (rc) 50 if (rc)
46 return rc; 51 return rc;
47 for (;;) 52 while (1)
48 { 53 {
49 size_t s = strcspn (buffer, "\r\n"); 54 mu_stream_write (io->_imap_stream, buffer, len, NULL);
50 rc = mu_stream_write (io->_imap_stream, buffer, s, NULL); 55 buffer += len;
51 if (rc) 56 if (*buffer)
52 return rc; 57 {
53 len -= s; 58 mu_stream_write (io->_imap_stream, " ", 1, NULL);
54 if (len == 0) 59 buffer = mu_str_skip_class (buffer, MU_CTYPE_ENDLN);
60 len = strcspn (buffer, "\r\n");
61 }
62 else
55 break; 63 break;
56 buffer += s;
57 rc = mu_stream_write (io->_imap_stream, " ", 1, NULL);
58 if (rc)
59 return rc;
60 } 64 }
61 } 65 }
62 else 66 else
63 return mu_imapio_send_literal_string (io, buffer); 67 mu_imapio_send_literal_string (io, buffer);
64 } 68 }
65 return mu_imapio_printf (io, "\"%s\"", buffer); 69 else if (buffer[len = strcspn (buffer, io->_imap_ws.ws_escape)])
70 {
71 int rc;
72
73 rc = mu_stream_write (io->_imap_stream, "\"", 1, NULL);
74 while (1)
75 {
76 mu_stream_write (io->_imap_stream, buffer, len, NULL);
77 buffer += len;
78 if (*buffer)
79 {
80 mu_stream_write (io->_imap_stream, "\\", 1, NULL);
81 mu_stream_write (io->_imap_stream, buffer, 1, NULL);
82 buffer++;
83 len = strcspn (buffer, io->_imap_ws.ws_escape);
84 }
85 else
86 break;
87 }
88 mu_stream_write (io->_imap_stream, "\"", 1, NULL);
89 }
90 else if (buffer[0] == 0 || buffer[strcspn (buffer, io->_imap_ws.ws_delim)])
91 mu_stream_printf (io->_imap_stream, "\"%s\"", buffer);
92 else
93 mu_stream_write (io->_imap_stream, buffer, len, NULL);
94
95 return mu_stream_last_error (io->_imap_stream);
66 } 96 }
67 97
68 int 98 int
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
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
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <mailutils/imapio.h>
21 #include <mailutils/stream.h>
22 #include <mailutils/sys/imapio.h>
23
24 /* Send a IMAP command to the server, quoting its arguments as necessary.
25 TAG is the command tag, CMD is the command verb. Command arguments are
26 given in variadic list terminated with NULL. */
27 int
28 mu_imapio_send_command (struct _mu_imapio *io, const char *tag,
29 char const *cmd, ...)
30 {
31 va_list ap;
32
33 va_start (ap, cmd);
34 mu_imapio_printf (io, "%s %s", tag, cmd);
35 while ((cmd = va_arg (ap, char *)))
36 {
37 mu_imapio_send (io, " ", 1);
38 mu_imapio_send_qstring (io, cmd);
39 }
40 va_end (ap);
41 mu_imapio_send (io, "\r\n", 2);
42 return mu_stream_last_error (io->_imap_stream);
43 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
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
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <mailutils/imapio.h>
21 #include <mailutils/stream.h>
22 #include <mailutils/sys/imapio.h>
23
24 /* Send a IMAP command to the server, quoting its arguments as necessary.
25 TAG is the command tag, CMD is the command verb. Command arguments are
26 given in variadic list terminated with NULL. The last argument is sent
27 over the wire as is, without quoting. */
28 int
29 mu_imapio_send_command_e (struct _mu_imapio *io, const char *tag,
30 char const *cmd, ...)
31 {
32 va_list ap;
33
34 va_start (ap, cmd);
35 mu_imapio_printf (io, "%s %s", tag, cmd);
36 cmd = va_arg (ap, char *);
37 while (cmd)
38 {
39 char const *next = va_arg (ap, char *);
40
41 mu_imapio_send (io, " ", 1);
42 if (next)
43 mu_imapio_send_qstring (io, cmd);
44 else
45 mu_imapio_send (io, cmd, strlen (cmd));
46 cmd = next;
47 }
48 va_end (ap);
49 mu_imapio_send (io, "\r\n", 2);
50 return mu_stream_last_error (io->_imap_stream);
51 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2011 Free Software Foundation, Inc.
3
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
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <string.h>
19 #include <mailutils/imapio.h>
20 #include <mailutils/stream.h>
21 #include <mailutils/sys/imapio.h>
22
23 /* Send a IMAP command to the server, quoting its arguments as necessary.
24 TAG is the command tag, ARGV contains ARGC elements and supplies the
25 command (in ARGV[0]) and its arguments. EXTRA (if not NULL) supplies
26 additional arguments that will be sent as is. */
27 int
28 mu_imapio_send_command_v (struct _mu_imapio *io, const char *tag,
29 int argc, char const **argv, const char *extra)
30 {
31 int i;
32
33 mu_imapio_printf (io, "%s %s", tag, argv[0]);
34 for (i = 1; i < argc; i++)
35 {
36 mu_imapio_send (io, " ", 1);
37 mu_imapio_send_qstring (io, argv[i]);
38 }
39 if (extra)
40 {
41 mu_imapio_send (io, " ", 1);
42 mu_imapio_send (io, extra, strlen (extra));
43 }
44 mu_imapio_send (io, "\r\n", 2);
45 return mu_stream_last_error (io->_imap_stream);
46 }
...@@ -80,8 +80,9 @@ mu_imap_append_stream_size (mu_imap_t imap, const char *mailbox, int flags, ...@@ -80,8 +80,9 @@ mu_imap_append_stream_size (mu_imap_t imap, const char *mailbox, int flags,
80 80
81 status = _mu_imap_tag_next (imap); 81 status = _mu_imap_tag_next (imap);
82 MU_IMAP_CHECK_EAGAIN (imap, status); 82 MU_IMAP_CHECK_EAGAIN (imap, status);
83 status = mu_imapio_printf (imap->io, "%s APPEND %s", 83 status = mu_imapio_printf (imap->io, "%s APPEND ", imap->tag_str);
84 imap->tag_str, mailbox); 84 MU_IMAP_CHECK_ERROR (imap, status);
85 status = mu_imapio_send_qstring (imap->io, mailbox);
85 MU_IMAP_CHECK_ERROR (imap, status); 86 MU_IMAP_CHECK_ERROR (imap, status);
86 if (flags) 87 if (flags)
87 { 88 {
......
...@@ -109,8 +109,8 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter) ...@@ -109,8 +109,8 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
109 case MU_IMAP_CLIENT_READY: 109 case MU_IMAP_CLIENT_READY:
110 status = _mu_imap_tag_next (imap); 110 status = _mu_imap_tag_next (imap);
111 MU_IMAP_CHECK_EAGAIN (imap, status); 111 MU_IMAP_CHECK_EAGAIN (imap, status);
112 status = mu_imapio_printf (imap->io, "%s CAPABILITY\r\n", 112 status = mu_imapio_send_command (imap->io, imap->tag_str,
113 imap->tag_str); 113 "CAPABILITY", NULL);
114 MU_IMAP_CHECK_EAGAIN (imap, status); 114 MU_IMAP_CHECK_EAGAIN (imap, status);
115 MU_IMAP_FCLR (imap, MU_IMAP_RESP); 115 MU_IMAP_FCLR (imap, MU_IMAP_RESP);
116 imap->client_state = MU_IMAP_CLIENT_CAPABILITY_RX; 116 imap->client_state = MU_IMAP_CLIENT_CAPABILITY_RX;
......
...@@ -30,7 +30,6 @@ mu_imap_check (mu_imap_t imap) ...@@ -30,7 +30,6 @@ mu_imap_check (mu_imap_t imap)
30 MU_IMAP_SESSION_SELECTED, 30 MU_IMAP_SESSION_SELECTED,
31 NULL, 31 NULL,
32 MU_IMAP_CLIENT_CHECK_RX, 32 MU_IMAP_CLIENT_CHECK_RX,
33 0,
34 1, 33 1,
35 &command, 34 &command,
36 NULL 35 NULL
......
...@@ -37,9 +37,9 @@ mu_imap_close (mu_imap_t imap) ...@@ -37,9 +37,9 @@ mu_imap_close (mu_imap_t imap)
37 MU_IMAP_SESSION_SELECTED, 37 MU_IMAP_SESSION_SELECTED,
38 NULL, 38 NULL,
39 MU_IMAP_CLIENT_CLOSE_RX, 39 MU_IMAP_CLIENT_CLOSE_RX,
40 0,
41 1, 40 1,
42 &command, 41 &command,
42 NULL,
43 _mu_close_handler 43 _mu_close_handler
44 }; 44 };
45 return mu_imap_gencom (imap, &com); 45 return mu_imap_gencom (imap, &com);
......
...@@ -26,19 +26,23 @@ ...@@ -26,19 +26,23 @@
26 int 26 int
27 mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox) 27 mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox)
28 { 28 {
29 char const *argv[3]; 29 char const *argv[4];
30 int i;
30 static struct imap_command com; 31 static struct imap_command com;
31 32
32 argv[0] = "COPY"; 33 i = 0;
33 argv[1] = msgset; 34 if (uid)
34 argv[2] = mailbox; 35 argv[i++] = "UID";
36 argv[i++] = "COPY";
37 argv[i++] = msgset;
38 argv[i++] = mailbox;
35 39
36 com.session_state = MU_IMAP_SESSION_SELECTED; 40 com.session_state = MU_IMAP_SESSION_SELECTED;
37 com.capa = NULL; 41 com.capa = NULL;
38 com.rx_state = MU_IMAP_CLIENT_COPY_RX; 42 com.rx_state = MU_IMAP_CLIENT_COPY_RX;
39 com.uid = 0; 43 com.argc = i;
40 com.argc = 3;
41 com.argv = argv; 44 com.argv = argv;
45 com.extra = NULL;
42 com.tagged_handler = NULL; 46 com.tagged_handler = NULL;
43 com.untagged_handler = NULL; 47 com.untagged_handler = NULL;
44 48
......
...@@ -37,9 +37,9 @@ mu_imap_delete (mu_imap_t imap, const char *mailbox) ...@@ -37,9 +37,9 @@ mu_imap_delete (mu_imap_t imap, const char *mailbox)
37 com.session_state = MU_IMAP_SESSION_AUTH; 37 com.session_state = MU_IMAP_SESSION_AUTH;
38 com.capa = NULL; 38 com.capa = NULL;
39 com.rx_state = MU_IMAP_CLIENT_DELETE_RX; 39 com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
40 com.uid = 0;
41 com.argc = 2; 40 com.argc = 2;
42 com.argv = argv; 41 com.argv = argv;
42 com.extra = NULL;
43 com.tagged_handler = NULL; 43 com.tagged_handler = NULL;
44 com.untagged_handler = NULL; 44 com.untagged_handler = NULL;
45 45
......
...@@ -30,7 +30,6 @@ mu_imap_expunge (mu_imap_t imap) ...@@ -30,7 +30,6 @@ mu_imap_expunge (mu_imap_t imap)
30 MU_IMAP_SESSION_SELECTED, 30 MU_IMAP_SESSION_SELECTED,
31 NULL, 31 NULL,
32 MU_IMAP_CLIENT_EXPUNGE_RX, 32 MU_IMAP_CLIENT_EXPUNGE_RX,
33 0,
34 1, 33 1,
35 &command, 34 &command,
36 NULL 35 NULL
......
...@@ -32,18 +32,21 @@ int ...@@ -32,18 +32,21 @@ int
32 mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items) 32 mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items)
33 { 33 {
34 char const *argv[3]; 34 char const *argv[3];
35 int i;
35 static struct imap_command com; 36 static struct imap_command com;
36 37
37 argv[0] = "FETCH"; 38 i = 0;
38 argv[1] = msgset; 39 if (uid)
39 argv[2] = items; 40 argv[i++] = "UID";
41 argv[i++] = "FETCH";
42 argv[i++] = msgset;
40 43
41 com.session_state = MU_IMAP_SESSION_SELECTED; 44 com.session_state = MU_IMAP_SESSION_SELECTED;
42 com.capa = NULL; 45 com.capa = NULL;
43 com.rx_state = MU_IMAP_CLIENT_FETCH_RX; 46 com.rx_state = MU_IMAP_CLIENT_FETCH_RX;
44 com.uid = uid; 47 com.argc = i;
45 com.argc = 3;
46 com.argv = argv; 48 com.argv = argv;
49 com.extra = items;
47 com.tagged_handler = NULL; 50 com.tagged_handler = NULL;
48 com.untagged_handler = NULL; 51 com.untagged_handler = NULL;
49 52
......
...@@ -28,7 +28,6 @@ int ...@@ -28,7 +28,6 @@ int
28 mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd) 28 mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
29 { 29 {
30 int status; 30 int status;
31 int i;
32 31
33 if (imap == NULL || !cmd || cmd->argc < 1) 32 if (imap == NULL || !cmd || cmd->argc < 1)
34 return EINVAL; 33 return EINVAL;
...@@ -57,16 +56,8 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd) ...@@ -57,16 +56,8 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
57 { 56 {
58 status = _mu_imap_tag_next (imap); 57 status = _mu_imap_tag_next (imap);
59 MU_IMAP_CHECK_EAGAIN (imap, status); 58 MU_IMAP_CHECK_EAGAIN (imap, status);
60 status = mu_imapio_printf (imap->io, "%s", imap->tag_str); 59 status = mu_imapio_send_command_v (imap->io, imap->tag_str,
61 if (status == 0 && cmd->uid) 60 cmd->argc, cmd->argv, cmd->extra);
62 status = mu_imapio_printf (imap->io, " UID");
63 MU_IMAP_CHECK_ERROR (imap, status);
64 for (i = 0; i < cmd->argc; i++)
65 {
66 status = mu_imapio_printf (imap->io, " %s", cmd->argv[i]);
67 MU_IMAP_CHECK_ERROR (imap, status);
68 }
69 status = mu_imapio_send (imap->io, "\r\n", 2);
70 MU_IMAP_CHECK_ERROR (imap, status); 61 MU_IMAP_CHECK_ERROR (imap, status);
71 MU_IMAP_FCLR (imap, MU_IMAP_RESP); 62 MU_IMAP_FCLR (imap, MU_IMAP_RESP);
72 imap->client_state = cmd->rx_state; 63 imap->client_state = cmd->rx_state;
......
...@@ -139,9 +139,9 @@ mu_imap_list (mu_imap_t imap, const char *refname, const char *mboxname, ...@@ -139,9 +139,9 @@ mu_imap_list (mu_imap_t imap, const char *refname, const char *mboxname,
139 com.session_state = MU_IMAP_SESSION_AUTH; 139 com.session_state = MU_IMAP_SESSION_AUTH;
140 com.capa = NULL; 140 com.capa = NULL;
141 com.rx_state = MU_IMAP_CLIENT_LIST_RX; 141 com.rx_state = MU_IMAP_CLIENT_LIST_RX;
142 com.uid = 0;
143 com.argc = 3; 142 com.argc = 3;
144 com.argv = argv; 143 com.argv = argv;
144 com.extra = NULL;
145 com.tagged_handler = NULL; 145 com.tagged_handler = NULL;
146 com.untagged_handler = list_untagged_handler; 146 com.untagged_handler = list_untagged_handler;
147 com.untagged_handler_data = &clos; 147 com.untagged_handler_data = &clos;
......
...@@ -43,8 +43,8 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass) ...@@ -43,8 +43,8 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass)
43 _mu_imap_xscript_level (imap, MU_XSCRIPT_SECURE); 43 _mu_imap_xscript_level (imap, MU_XSCRIPT_SECURE);
44 status = _mu_imap_tag_next (imap); 44 status = _mu_imap_tag_next (imap);
45 MU_IMAP_CHECK_EAGAIN (imap, status); 45 MU_IMAP_CHECK_EAGAIN (imap, status);
46 status = mu_imapio_printf (imap->io, "%s LOGIN \"%s\" \"%s\"\r\n", 46 status = mu_imapio_send_command (imap->io, imap->tag_str,
47 imap->tag_str, user, pass); 47 "LOGIN", user, pass, NULL);
48 _mu_imap_xscript_level (imap, MU_XSCRIPT_NORMAL); 48 _mu_imap_xscript_level (imap, MU_XSCRIPT_NORMAL);
49 /* FIXME: how to obscure the passwd in the stream buffer? */ 49 /* FIXME: how to obscure the passwd in the stream buffer? */
50 MU_IMAP_CHECK_EAGAIN (imap, status); 50 MU_IMAP_CHECK_EAGAIN (imap, status);
......
...@@ -37,9 +37,9 @@ mu_imap_mailbox_create (mu_imap_t imap, const char *mailbox) ...@@ -37,9 +37,9 @@ mu_imap_mailbox_create (mu_imap_t imap, const char *mailbox)
37 com.session_state = MU_IMAP_SESSION_AUTH; 37 com.session_state = MU_IMAP_SESSION_AUTH;
38 com.capa = NULL; 38 com.capa = NULL;
39 com.rx_state = MU_IMAP_CLIENT_DELETE_RX; 39 com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
40 com.uid = 0;
41 com.argc = 2; 40 com.argc = 2;
42 com.argv = argv; 41 com.argv = argv;
42 com.extra = 0;
43 com.tagged_handler = NULL; 43 com.tagged_handler = NULL;
44 com.untagged_handler = NULL; 44 com.untagged_handler = NULL;
45 45
......
...@@ -30,7 +30,6 @@ mu_imap_noop (mu_imap_t imap) ...@@ -30,7 +30,6 @@ mu_imap_noop (mu_imap_t imap)
30 MU_IMAP_SESSION_INIT, 30 MU_IMAP_SESSION_INIT,
31 NULL, 31 NULL,
32 MU_IMAP_CLIENT_NOOP_RX, 32 MU_IMAP_CLIENT_NOOP_RX,
33 0,
34 1, 33 1,
35 &command, 34 &command,
36 NULL 35 NULL
......
...@@ -36,9 +36,9 @@ mu_imap_rename (mu_imap_t imap, const char *mailbox, const char *new_mailbox) ...@@ -36,9 +36,9 @@ mu_imap_rename (mu_imap_t imap, const char *mailbox, const char *new_mailbox)
36 com.session_state = MU_IMAP_SESSION_AUTH; 36 com.session_state = MU_IMAP_SESSION_AUTH;
37 com.capa = NULL; 37 com.capa = NULL;
38 com.rx_state = MU_IMAP_CLIENT_DELETE_RX; 38 com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
39 com.uid = 0;
40 com.argc = 3; 39 com.argc = 3;
41 com.argv = argv; 40 com.argv = argv;
41 com.extra = NULL;
42 com.tagged_handler = NULL; 42 com.tagged_handler = NULL;
43 com.untagged_handler = NULL; 43 com.untagged_handler = NULL;
44 44
......
...@@ -101,10 +101,9 @@ mu_imap_select (mu_imap_t imap, const char *mbox, int writable, ...@@ -101,10 +101,9 @@ mu_imap_select (mu_imap_t imap, const char *mbox, int writable,
101 case MU_IMAP_CLIENT_READY: 101 case MU_IMAP_CLIENT_READY:
102 status = _mu_imap_tag_next (imap); 102 status = _mu_imap_tag_next (imap);
103 MU_IMAP_CHECK_EAGAIN (imap, status); 103 MU_IMAP_CHECK_EAGAIN (imap, status);
104 status = mu_imapio_printf (imap->io, "%s %s %s\r\n", 104 status = mu_imapio_send_command (imap->io, imap->tag_str,
105 imap->tag_str,
106 writable ? "SELECT" : "EXAMINE", 105 writable ? "SELECT" : "EXAMINE",
107 mbox); 106 mbox, NULL);
108 MU_IMAP_CHECK_ERROR (imap, status); 107 MU_IMAP_CHECK_ERROR (imap, status);
109 MU_IMAP_FCLR (imap, MU_IMAP_RESP); 108 MU_IMAP_FCLR (imap, MU_IMAP_RESP);
110 imap->client_state = MU_IMAP_CLIENT_SELECT_RX; 109 imap->client_state = MU_IMAP_CLIENT_SELECT_RX;
......
...@@ -29,18 +29,21 @@ int ...@@ -29,18 +29,21 @@ int
29 mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items) 29 mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items)
30 { 30 {
31 char const *argv[3]; 31 char const *argv[3];
32 int i;
32 static struct imap_command com; 33 static struct imap_command com;
33 34
34 argv[0] = "STORE"; 35 i = 0;
35 argv[1] = msgset; 36 if (uid)
36 argv[2] = items; 37 argv[i++] = "UID";
38 argv[i++] = "STORE";
39 argv[i++] = msgset;
37 40
38 com.session_state = MU_IMAP_SESSION_SELECTED; 41 com.session_state = MU_IMAP_SESSION_SELECTED;
39 com.capa = NULL; 42 com.capa = NULL;
40 com.rx_state = MU_IMAP_CLIENT_STORE_RX; 43 com.rx_state = MU_IMAP_CLIENT_STORE_RX;
41 com.uid = uid; 44 com.argc = i;
42 com.argc = 3;
43 com.argv = argv; 45 com.argv = argv;
46 com.extra = items;
44 com.tagged_handler = NULL; 47 com.tagged_handler = NULL;
45 com.untagged_handler = NULL; 48 com.untagged_handler = NULL;
46 49
......
...@@ -30,9 +30,9 @@ mu_imap_unselect (mu_imap_t imap) ...@@ -30,9 +30,9 @@ mu_imap_unselect (mu_imap_t imap)
30 MU_IMAP_SESSION_SELECTED, 30 MU_IMAP_SESSION_SELECTED,
31 NULL, 31 NULL,
32 MU_IMAP_CLIENT_UNSELECT_RX, 32 MU_IMAP_CLIENT_UNSELECT_RX,
33 0,
34 1, 33 1,
35 &command, 34 &command,
35 NULL,
36 _mu_close_handler 36 _mu_close_handler
37 }; 37 };
38 return mu_imap_gencom (imap, &com); 38 return mu_imap_gencom (imap, &com);
......