Commit 0ff01881 0ff01881ca8dd159c2802751901644daef2bcc19 by Sergey Poznyakoff

Use mu_msgset_t in imap client for FETCH, STORE and COPY.

* include/mailutils/imap.h (mu_imap_fetch,mu_imap_store)
(mu_imap_store_flags,mu_imap_copy): Take mu_msgset_t as the
message set parameter.
* include/mailutils/imapio.h (mu_imapio_send_msgset): New proto.
(mu_imapio_send_command_v,mu_imapio_send_command)
(mu_imapio_send_command_e): Take additional mu_msgset_t parameter.
All uses changed.
* include/mailutils/msgset.h (mu_msgset_parse_imap): Input string
is const.
* include/mailutils/sys/imap.h (imap_command) <msgset>: New member.
* libmailutils/imapio/sendmsgset.c: New file.
* libmailutils/imapio/Makefile.am (libimapio_la_SOURCES): Add sendmsgset.c.
* libmailutils/imapio/sendcmd.c (mu_imapio_send_command): Take additional
mu_msgset_t parameter.
* libmailutils/imapio/sendcmde.c (mu_imapio_send_command_e): Likewise.
* libmailutils/imapio/sendcmdv.c (mu_imapio_send_command_v): Likewise.
* libmailutils/msgset/parse.c (mu_msgset_parse_imap): Input string
is const.
* libproto/imap/copy.c (mu_imap_copy): Take mu_msgset_t as the
message set parameter.
* libproto/imap/fetch.c (mu_imap_fetch): Likewise.
* libproto/imap/store.c (mu_imap_store): Likewise.
* libproto/imap/storeflg.c (mu_imap_store_flags): Likewise.
* libproto/imap/gencom.c (mu_imap_gencom): Send cmd->msgset.
1 parent 1c7d50a6
......@@ -66,9 +66,9 @@ int mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc);
int mu_imap_noop (mu_imap_t imap);
int mu_imap_check (mu_imap_t imap);
int mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset,
int mu_imap_fetch (mu_imap_t imap, int uid, mu_msgset_t msgset,
const char *items);
int mu_imap_store (mu_imap_t imap, int uid, const char *msgset,
int mu_imap_store (mu_imap_t imap, int uid, mu_msgset_t msgset,
const char *items);
#define MU_IMAP_STORE_SET 0
......@@ -78,13 +78,13 @@ int mu_imap_store (mu_imap_t imap, int uid, const char *msgset,
#define MU_IMAP_STORE_OPMASK 0xf
int mu_imap_store_flags (mu_imap_t imap, int uid, const char *msgset,
int mu_imap_store_flags (mu_imap_t imap, int uid, mu_msgset_t msgset,
int op, int flags);
int mu_imap_delete (mu_imap_t imap, const char *mailbox);
int mu_imap_rename (mu_imap_t imap, const char *mailbox,
const char *new_mailbox);
int mu_imap_copy (mu_imap_t imap, int uid, const char *msgset,
int mu_imap_copy (mu_imap_t imap, int uid, mu_msgset_t msgset,
const char *mailbox);
int mu_imap_close (mu_imap_t imap);
......
......@@ -44,13 +44,15 @@ int mu_imapio_send_literal_stream (mu_imapio_t io, mu_stream_t stream,
int mu_imapio_send_qstring (mu_imapio_t io, const char *buffer);
int mu_imapio_send_qstring_unfold (mu_imapio_t io, const char *buffer,
int unfold);
int mu_imapio_send_msgset (mu_imapio_t io, mu_msgset_t msgset);
int mu_imapio_send_command_v (mu_imapio_t io, const char *tag,
mu_msgset_t msgset,
int argc, char const **argv, const char *extra);
int mu_imapio_send_command (mu_imapio_t io, const char *tag,
char const *cmd, ...);
mu_msgset_t msgset, char const *cmd, ...);
int mu_imapio_send_command_e (mu_imapio_t io, const char *tag,
char const *cmd, ...);
mu_msgset_t msgset, char const *cmd, ...);
int mu_imapio_send_flags (mu_imapio_t io, int flags);
int mu_imapio_send_time (mu_imapio_t io, struct tm *tm,
......
......@@ -47,7 +47,7 @@ int mu_msgset_clear (mu_msgset_t set);
void mu_msgset_free (mu_msgset_t set);
void mu_msgset_destroy (mu_msgset_t *set);
int mu_msgset_parse_imap (mu_msgset_t set, char *s, char **end);
int mu_msgset_parse_imap (mu_msgset_t set, const char *s, char **end);
int mu_msgset_print (mu_stream_t str, mu_msgset_t msgset);
......
......@@ -151,6 +151,7 @@ struct imap_command
int argc;
char const **argv;
char const *extra;
mu_msgset_t msgset;
void (*tagged_handler) (mu_imap_t);
mu_imap_response_action_t untagged_handler;
void *untagged_handler_data;
......
......@@ -32,6 +32,7 @@ libimapio_la_SOURCES = \
sendcmdv.c\
sendcmde.c\
sendflg.c\
sendmsgset.c\
time.c\
trace.c\
transport.c\
......
......@@ -23,10 +23,14 @@
/* Send a IMAP command to the server, quoting its arguments as necessary.
TAG is the command tag, CMD is the command verb. Command arguments are
given in variadic list terminated with NULL. */
given in variadic list terminated with NULL.
If MSGSET is supplied, it is sent when the function encounters the
"\\" (single backslash) in ARGV.
*/
int
mu_imapio_send_command (struct _mu_imapio *io, const char *tag,
char const *cmd, ...)
mu_msgset_t msgset, char const *cmd, ...)
{
va_list ap;
......@@ -35,7 +39,10 @@ mu_imapio_send_command (struct _mu_imapio *io, const char *tag,
while ((cmd = va_arg (ap, char *)))
{
mu_imapio_send (io, " ", 1);
mu_imapio_send_qstring (io, cmd);
if (msgset && strcmp (cmd, "\\") == 0)
mu_imapio_send_msgset (io, msgset);
else
mu_imapio_send_qstring (io, cmd);
}
va_end (ap);
mu_imapio_send (io, "\r\n", 2);
......
......@@ -24,9 +24,12 @@
/* Send a IMAP command to the server, quoting its arguments as necessary.
TAG is the command tag, CMD is the command verb. Command arguments are
given in variadic list terminated with NULL. The last argument is sent
over the wire as is, without quoting. */
over the wire as is, without quoting. If MSGSET is supplied, it is sent
when the function encounters the "\\" (single backslash) in ARGV.
*/
int
mu_imapio_send_command_e (struct _mu_imapio *io, const char *tag,
mu_msgset_t msgset,
char const *cmd, ...)
{
va_list ap;
......@@ -40,7 +43,12 @@ mu_imapio_send_command_e (struct _mu_imapio *io, const char *tag,
mu_imapio_send (io, " ", 1);
if (next)
mu_imapio_send_qstring (io, cmd);
{
if (msgset && strcmp (cmd, "\\") == 0)
mu_imapio_send_msgset (io, msgset);
else
mu_imapio_send_qstring (io, cmd);
}
else
mu_imapio_send (io, cmd, strlen (cmd));
cmd = next;
......
......@@ -23,9 +23,14 @@
/* Send a IMAP command to the server, quoting its arguments as necessary.
TAG is the command tag, ARGV contains ARGC elements and supplies the
command (in ARGV[0]) and its arguments. EXTRA (if not NULL) supplies
additional arguments that will be sent as is. */
additional arguments that will be sent as is.
If MSGSET is supplied, it is sent when the function encounters the
"\\" (single backslash) in ARGV.
*/
int
mu_imapio_send_command_v (struct _mu_imapio *io, const char *tag,
mu_msgset_t msgset,
int argc, char const **argv, const char *extra)
{
int i;
......@@ -34,7 +39,10 @@ mu_imapio_send_command_v (struct _mu_imapio *io, const char *tag,
for (i = 1; i < argc; i++)
{
mu_imapio_send (io, " ", 1);
mu_imapio_send_qstring (io, argv[i]);
if (msgset && strcmp (argv[i], "\\") == 0)
mu_imapio_send_msgset (io, msgset);
else
mu_imapio_send_qstring (io, argv[i]);
}
if (extra)
{
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdarg.h>
#include <mailutils/types.h>
#include <mailutils/imapio.h>
#include <mailutils/msgset.h>
#include <mailutils/stream.h>
#include <mailutils/sys/imapio.h>
int
mu_imapio_send_msgset (mu_imapio_t io, mu_msgset_t msgset)
{
return mu_msgset_print (io->_imap_stream, msgset);
}
......@@ -29,7 +29,7 @@
/* This structure keeps parser state while parsing message set. */
struct parse_msgnum_env
{
char *s; /* Current position in string */
const char *s; /* Current position in string */
size_t minval; /* Min. sequence number or UID */
size_t maxval; /* Max. sequence number or UID */
mu_msgset_t msgset; /* Message set being built. */
......@@ -125,7 +125,7 @@ parse_msgrange (struct parse_msgnum_env *env)
On error, return error code and point END to the position in the input
string where parsing has failed. */
int
mu_msgset_parse_imap (mu_msgset_t mset, char *s, char **end)
mu_msgset_parse_imap (mu_msgset_t mset, const char *s, char **end)
{
int rc;
struct parse_msgnum_env env;
......@@ -141,7 +141,7 @@ mu_msgset_parse_imap (mu_msgset_t mset, char *s, char **end)
env.minval = 1;
if (end)
*end = s;
*end = (char*) s;
if (mset->mbox)
{
size_t lastmsgno; /* Max. sequence number. */
......@@ -174,6 +174,6 @@ mu_msgset_parse_imap (mu_msgset_t mset, char *s, char **end)
}
if (end)
*end = env.s;
*end = (char*) env.s;
return rc;
}
......
......@@ -102,7 +102,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
case MU_IMAP_CLIENT_READY:
status = _mu_imap_tag_next (imap);
MU_IMAP_CHECK_EAGAIN (imap, status);
status = mu_imapio_send_command (imap->io, imap->tag_str,
status = mu_imapio_send_command (imap->io, imap->tag_str, NULL,
"CAPABILITY", NULL);
MU_IMAP_CHECK_EAGAIN (imap, status);
MU_IMAP_FCLR (imap, MU_IMAP_RESP);
......
......@@ -40,6 +40,7 @@ mu_imap_close (mu_imap_t imap)
1,
&command,
NULL,
NULL,
_mu_close_handler
};
return mu_imap_gencom (imap, &com);
......
......@@ -24,7 +24,7 @@
#include <mailutils/sys/imap.h>
int
mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox)
mu_imap_copy (mu_imap_t imap, int uid, mu_msgset_t msgset, const char *mailbox)
{
char const *argv[4];
int i;
......@@ -34,7 +34,7 @@ mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox)
if (uid)
argv[i++] = "UID";
argv[i++] = "COPY";
argv[i++] = msgset;
argv[i++] = "\\";
argv[i++] = mailbox;
com.session_state = MU_IMAP_SESSION_SELECTED;
......@@ -43,6 +43,7 @@ mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox)
com.argc = i;
com.argv = argv;
com.extra = NULL;
com.msgset = msgset;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -43,6 +43,7 @@ mu_imap_delete (mu_imap_t imap, const char *mailbox)
com.argc = 2;
com.argv = argv;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -32,7 +32,7 @@
#include <mailutils/sys/imap.h>
int
mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items)
mu_imap_fetch (mu_imap_t imap, int uid, mu_msgset_t msgset, const char *items)
{
char const *argv[3];
int i;
......@@ -42,7 +42,7 @@ mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items)
if (uid)
argv[i++] = "UID";
argv[i++] = "FETCH";
argv[i++] = msgset;
argv[i++] = "\\";
com.session_state = MU_IMAP_SESSION_SELECTED;
com.capa = NULL;
......@@ -50,6 +50,7 @@ mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items)
com.argc = i;
com.argv = argv;
com.extra = items;
com.msgset = msgset;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -57,6 +57,7 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
status = _mu_imap_tag_next (imap);
MU_IMAP_CHECK_EAGAIN (imap, status);
status = mu_imapio_send_command_v (imap->io, imap->tag_str,
cmd->msgset,
cmd->argc, cmd->argv, cmd->extra);
MU_IMAP_CHECK_ERROR (imap, status);
MU_IMAP_FCLR (imap, MU_IMAP_RESP);
......
......@@ -150,6 +150,7 @@ mu_imap_genlist (mu_imap_t imap, int lsub,
com.argc = 3;
com.argv = argv;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = list_untagged_handler;
com.untagged_handler_data = &clos;
......
......@@ -44,7 +44,7 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass)
_mu_imap_xscript_level (imap, MU_XSCRIPT_SECURE);
status = _mu_imap_tag_next (imap);
MU_IMAP_CHECK_EAGAIN (imap, status);
status = mu_imapio_send_command (imap->io, imap->tag_str,
status = mu_imapio_send_command (imap->io, imap->tag_str, NULL,
"LOGIN", user, pass, NULL);
_mu_imap_xscript_level (imap, MU_XSCRIPT_NORMAL);
/* FIXME: how to obscure the passwd in the stream buffer? */
......
......@@ -39,7 +39,8 @@ mu_imap_mailbox_create (mu_imap_t imap, const char *mailbox)
com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
com.argc = 2;
com.argv = argv;
com.extra = 0;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -38,6 +38,7 @@
#include <mailutils/attribute.h>
#include <mailutils/header.h>
#include <mailutils/body.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/imap.h>
#define _imap_mbx_clrerr(imbx) ((imbx)->last_error = 0)
......@@ -58,7 +59,7 @@ _imap_msg_no (struct _mu_imap_message *imsg)
}
static int
_imap_fetch_with_callback (mu_imap_t imap, char *msgset, char *items,
_imap_fetch_with_callback (mu_imap_t imap, mu_msgset_t msgset, char *items,
mu_imap_callback_t cb, void *data)
{
int rc;
......@@ -156,7 +157,7 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
if (!(imsg->flags & _MU_IMAP_MSG_CACHED))
{
char *msgset;
mu_msgset_t msgset;
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("caching message %lu"), (unsigned long) msgno));
......@@ -174,16 +175,22 @@ __imap_msg_get_stream (struct _mu_imap_message *imsg, size_t msgno,
if (rc)
return rc;
rc = mu_asprintf (&msgset, "%lu", msgno);
rc = mu_msgset_create (&msgset, NULL, 0);
if (rc == 0)
{
struct save_closure clos;
clos.imsg = imsg;
clos.save_stream = imbx->cache;
_imap_mbx_clrerr (imbx);
rc = _imap_fetch_with_callback (imap, msgset, "BODY[]",
_save_message, &clos);
free (msgset);
rc = mu_msgset_add_range (msgset, msgno, msgno);
if (rc == 0)
{
_imap_mbx_clrerr (imbx);
rc = _imap_fetch_with_callback (imap, msgset, "BODY[]",
_save_message, &clos);
}
mu_msgset_free (msgset);
if (rc == 0 && !_imap_mbx_errno (imbx))
{
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
......@@ -359,46 +366,54 @@ _imap_hdr_fill (void *data, char **pbuf, size_t *plen)
struct _mu_imap_mailbox *imbx = imsg->imbx;
mu_imap_t imap = imbx->mbox->folder->data;
struct save_closure clos;
char *msgset;
mu_msgset_t msgset;
unsigned long msgno = _imap_msg_no (imsg);
int rc;
clos.imsg = imsg;
rc = mu_memory_stream_create (&clos.save_stream, MU_STREAM_RDWR);
_imap_mbx_clrerr (imbx);
rc = mu_asprintf (&msgset, "%lu", msgno);
rc = mu_msgset_create (&msgset, NULL, 0);
if (rc == 0)
{
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("message %lu: reading headers"),
(unsigned long) msgno));
rc = _imap_fetch_with_callback (imap, msgset, "BODY.PEEK[HEADER]",
_save_message, &clos);
free (msgset);
rc = mu_msgset_add_range (msgset, msgno, msgno);
if (rc == 0)
{
char *buf;
mu_off_t size;
mu_stream_size (clos.save_stream, &size);
buf = malloc (size + 1);
if (!buf)
rc = ENOMEM;
else
clos.imsg = imsg;
rc = mu_memory_stream_create (&clos.save_stream, MU_STREAM_RDWR);
if (rc == 0)
{
mu_stream_seek (clos.save_stream, 0, MU_SEEK_SET, NULL);
rc = mu_stream_read (clos.save_stream, buf, size, NULL);
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("message %lu: reading headers"),
(unsigned long) msgno));
_imap_mbx_clrerr (imbx);
rc = _imap_fetch_with_callback (imap, msgset,
"BODY.PEEK[HEADER]",
_save_message, &clos);
if (rc == 0)
{
*pbuf = buf;
*plen = size;
char *buf;
mu_off_t size;
mu_stream_size (clos.save_stream, &size);
buf = malloc (size + 1);
if (!buf)
rc = ENOMEM;
else
{
mu_stream_seek (clos.save_stream, 0, MU_SEEK_SET, NULL);
rc = mu_stream_read (clos.save_stream, buf, size, NULL);
if (rc == 0)
{
*pbuf = buf;
*plen = size;
}
else
free (buf);
}
}
else
free (buf);
mu_stream_destroy (&clos.save_stream);
}
}
mu_msgset_free (msgset);
}
mu_stream_destroy (&clos.save_stream);
return rc;
}
......@@ -602,15 +617,18 @@ _imap_msg_bodystructure (mu_message_t msg, struct mu_bodystructure **pbs)
struct _mu_imap_mailbox *imbx = imsg->imbx;
mu_imap_t imap = imbx->mbox->folder->data;
int rc;
char *msgset;
rc = mu_asprintf (&msgset, "%lu", _imap_msg_no (imsg));
if (rc)
return rc;
mu_msgset_t msgset;
rc = _imap_fetch_with_callback (imap, msgset, "BODYSTRUCTURE",
_imap_bodystructure_callback, pbs);
free (msgset);
rc = mu_msgset_create (&msgset, NULL, 0);
if (rc == 0)
{
size_t msgno = _imap_msg_no (imsg);
rc = mu_msgset_add_range (msgset, msgno, msgno);
if (rc == 0)
rc = _imap_fetch_with_callback (imap, msgset, "BODYSTRUCTURE",
_imap_bodystructure_callback, pbs);
mu_msgset_free (msgset);
}
return rc;
}
......@@ -919,36 +937,22 @@ aggregate_attributes (struct _mu_imap_mailbox *imbx,
}
static int
flush_attributes (mu_imap_t imap, mu_stream_t str, int attr_flags)
{
int rc;
mu_transport_t trans[2];
mu_stream_write (str, "", 1, NULL);
if (mu_stream_err (str))
return mu_stream_last_error (str);
rc = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans);
if (rc == 0)
rc = mu_imap_store_flags (imap, 0, (char*)trans[0],
MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
attr_flags);
return rc;
}
static int
_imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
{
struct _mu_imap_mailbox *imbx = mbox->data;
mu_folder_t folder = mbox->folder;
mu_imap_t imap = folder->data;
size_t i, j;
char *msgset;
mu_msgset_t msgset;
int rc;
int delflg = 0;
struct attr_tab *tab;
size_t count;
rc = mu_msgset_create (&msgset, NULL, 0);
if (rc)
return rc;
rc = aggregate_attributes (imbx, &tab, &count);
if (rc)
{
......@@ -957,14 +961,14 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
{
if (imbx->msgs[i].flags & _MU_IMAP_MSG_ATTRCHG)
{
rc = mu_asprintf (&msgset, "%lu", i + 1);
mu_msgset_clear (msgset);
mu_msgset_add_range (msgset, i + 1, i + 1);
if (rc)
break;
rc = mu_imap_store_flags (imap, 0, msgset,
MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
imbx->msgs[i].attr_flags);
delflg |= imbx->msgs[i].attr_flags & MU_ATTRIBUTE_DELETED;
free (msgset);
if (rc)
break;
}
......@@ -972,45 +976,45 @@ _imap_mbx_gensync (mu_mailbox_t mbox, int *pdel)
}
else
{
mu_stream_t str;
rc = mu_memory_stream_create (&str, MU_STREAM_RDWR);
if (rc == 0)
for (i = j = 0; i < count; i++)
{
for (i = j = 0; i < count; i++)
if (j < i)
{
if (j < i)
if (tab[j].attr_flags != tab[i].attr_flags)
{
if (tab[j].attr_flags != tab[i].attr_flags)
{
rc = flush_attributes (imap, str, tab[j].attr_flags);
delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
if (rc)
break;
mu_stream_truncate (str, 0);
j = i;
}
else
mu_stream_printf (str, ",");
rc = mu_imap_store_flags (imap, 0, msgset,
MU_IMAP_STORE_SET|
MU_IMAP_STORE_SILENT,
tab[j].attr_flags);
delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
if (rc)
break;
mu_msgset_clear (msgset);
j = i;
}
if (tab[i].end == tab[i].start)
mu_stream_printf (str, "%lu", (unsigned long)tab[i].start+1);
else
mu_stream_printf (str, "%lu:%lu",
(unsigned long)tab[i].start+1,
(unsigned long)tab[i].end+1);
}
if (tab[i].end == tab[i].start)
rc = mu_msgset_add_range (msgset, tab[i].start + 1,
tab[i].start + 1);
else
rc = mu_msgset_add_range (msgset,
tab[i].start + 1,
tab[i].end + 1);
if (rc)
break;
}
if (j < i)
{
rc = flush_attributes (imap, str, tab[j].attr_flags);
delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
}
mu_stream_unref (str);
if (rc == 0 && j < i)
{
rc = mu_imap_store_flags (imap, 0, msgset,
MU_IMAP_STORE_SET|MU_IMAP_STORE_SILENT,
tab[j].attr_flags);
delflg |= tab[j].attr_flags & MU_ATTRIBUTE_DELETED;
}
free (tab);
}
mu_msgset_free (msgset);
if (rc)
return rc;
......@@ -1182,20 +1186,26 @@ _imap_mbx_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
struct _mu_imap_mailbox *imbx = mbox->data;
mu_folder_t folder = mbox->folder;
mu_imap_t imap = folder->data;
char *msgset;
mu_msgset_t msgset;
int rc;
static char _imap_scan_items[] = "(UID FLAGS ENVELOPE RFC822.SIZE BODY)";
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("scanning mailbox %s"), mu_url_to_string (mbox->url)));
rc = mu_asprintf (&msgset, "%lu:*", (unsigned long) msgno);
rc = mu_msgset_create (&msgset, NULL, 0);
if (rc)
return rc;
rc = mu_msgset_add_range (msgset, msgno, MU_MSGNO_LAST);
if (rc)
{
mu_msgset_free (msgset);
return rc;
}
_imap_mbx_clrerr (imbx);
rc = _imap_fetch_with_callback (imap, msgset, _imap_scan_items,
_imap_fetch_callback, imbx);
free (msgset);
mu_msgset_free (msgset);
if (rc == 0)
rc = _imap_mbx_errno (imbx);
if (rc == 0)
......
......@@ -42,6 +42,7 @@ mu_imap_rename (mu_imap_t imap, const char *mailbox, const char *new_mailbox)
com.argc = 3;
com.argv = argv;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -102,7 +102,7 @@ mu_imap_select (mu_imap_t imap, const char *mbox, int writable,
case MU_IMAP_CLIENT_READY:
status = _mu_imap_tag_next (imap);
MU_IMAP_CHECK_EAGAIN (imap, status);
status = mu_imapio_send_command (imap->io, imap->tag_str,
status = mu_imapio_send_command (imap->io, imap->tag_str, NULL,
writable ? "SELECT" : "EXAMINE",
mbox, NULL);
MU_IMAP_CHECK_ERROR (imap, status);
......
......@@ -26,7 +26,7 @@
#include <mailutils/sys/imap.h>
int
mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items)
mu_imap_store (mu_imap_t imap, int uid, mu_msgset_t msgset, const char *items)
{
char const *argv[3];
int i;
......@@ -36,7 +36,7 @@ mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items)
if (uid)
argv[i++] = "UID";
argv[i++] = "STORE";
argv[i++] = msgset;
argv[i++] = "\\";
com.session_state = MU_IMAP_SESSION_SELECTED;
com.capa = NULL;
......@@ -44,6 +44,7 @@ mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items)
com.argc = i;
com.argv = argv;
com.extra = items;
com.msgset = msgset;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -29,7 +29,7 @@
#include <mailutils/sys/imap.h>
int
mu_imap_store_flags (mu_imap_t imap, int uid, const char *msgset,
mu_imap_store_flags (mu_imap_t imap, int uid, mu_msgset_t msgset,
int op, int flags)
{
int status;
......@@ -50,8 +50,9 @@ mu_imap_store_flags (mu_imap_t imap, int uid, const char *msgset,
mu_imapio_printf (imap->io, "%s ", imap->tag_str);
if (uid)
mu_imapio_printf (imap->io, "UID ");
mu_imapio_printf (imap->io, "STORE %s %s", msgset,
cmd[op & MU_IMAP_STORE_OPMASK]);
mu_imapio_printf (imap->io, "STORE ");
mu_imapio_send_msgset (imap->io, msgset);
mu_imapio_printf (imap->io, " %s", cmd[op & MU_IMAP_STORE_OPMASK]);
if (op & MU_IMAP_STORE_SILENT)
mu_imapio_printf (imap->io, ".SILENT");
mu_imapio_printf (imap->io, " ");
......
......@@ -41,6 +41,7 @@ mu_imap_subscribe (mu_imap_t imap, const char *mailbox)
com.argc = 2;
com.argv = argv;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -33,6 +33,7 @@ mu_imap_unselect (mu_imap_t imap)
1,
&command,
NULL,
NULL,
_mu_close_handler
};
return mu_imap_gencom (imap, &com);
......
......@@ -41,6 +41,7 @@ mu_imap_unsubscribe (mu_imap_t imap, const char *mailbox)
com.argc = 2;
com.argv = argv;
com.extra = NULL;
com.msgset = NULL;
com.tagged_handler = NULL;
com.untagged_handler = NULL;
......
......@@ -27,6 +27,7 @@
#include <mailutils/imap.h>
#include <mailutils/imapio.h>
#include <mailutils/imaputil.h>
#include <mailutils/msgset.h>
#include "mu.h"
#include "argp.h"
#include "xalloc.h"
......@@ -110,6 +111,29 @@ com_verbose (int argc, char **argv)
}
static mu_msgset_t
parse_msgset (const char *arg)
{
int status;
mu_msgset_t msgset;
char *p;
status = mu_msgset_create (&msgset, NULL, 0);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, status);
return NULL;
}
status = mu_msgset_parse_imap (msgset, arg, &p);
if (status)
{
mu_error (_("failed to parse message set near \"%s\": %s"),
p, mu_strerror (status));
mu_msgset_destroy (&msgset);
}
return msgset;
}
static void
report_failure (const char *what, int status)
{
......@@ -898,28 +922,39 @@ com_check (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
static int
com_fetch (int argc, char **argv)
{
int status;
mu_stream_t out = mutool_open_pager ();
mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
imap_fetch_callback,
out);
status = mu_imap_fetch (imap, uid_mode, argv[1], argv[2]);
mu_stream_destroy (&out);
mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
imap_fetch_callback,
mu_strout);
if (status)
report_failure ("fetch", status);
mu_msgset_t msgset = parse_msgset (argv[1]);
if (msgset)
{
int status;
mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
imap_fetch_callback,
out);
status = mu_imap_fetch (imap, uid_mode, msgset, argv[2]);
mu_stream_destroy (&out);
mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
imap_fetch_callback,
mu_strout);
mu_msgset_free (msgset);
if (status)
report_failure ("fetch", status);
}
return 0;
}
static int
com_store (int argc, char **argv)
{
int status = mu_imap_store (imap, uid_mode, argv[1], argv[2]);
if (status)
report_failure ("store", status);
mu_msgset_t msgset = parse_msgset (argv[1]);
if (msgset)
{
int status = mu_imap_store (imap, uid_mode, msgset, argv[2]);
if (status)
report_failure ("store", status);
}
return 0;
}
......@@ -1076,9 +1111,14 @@ com_append (int argc, char **argv)
static int
com_copy (int argc, char **argv)
{
int status = mu_imap_copy (imap, uid_mode, argv[1], argv[2]);
if (status)
report_failure ("copy", status);
mu_msgset_t msgset = parse_msgset (argv[1]);
if (msgset)
{
int status = mu_imap_copy (imap, uid_mode, msgset, argv[2]);
mu_msgset_free (msgset);
if (status)
report_failure ("copy", status);
}
return 0;
}
......