Commit e6ae2852 e6ae2852edb142fcf84dc489715f8984843dfe0c by Sergey Poznyakoff

Implement a copy method in mailbox.

This method copies given messages (ificated by their sequence or UID
numbers) to the given mailbox. So far this is implemented only in
IMAP[S] folders.

The mh/inc utility uses this method to optionally move incorporated
messages to other folder (mailbox) instead of simply deleting them.

* include/mailutils/imap.h (mu_imap_response)
(mu_imap_response_code): New protos.
(MU_IMAP_CB_TAGGED_OK,MU_IMAP_CB_TAGGED_NO)
(MU_IMAP_CB_TAGGED_BAD): New callback codes.
* include/mailutils/mailbox.h (MU_MAILBOX_COPY_UID)
(MU_MAILBOX_COPY_CREAT): New constants.
(mu_mailbox_msgset_copy)
(mu_mailbox_message_copy): New protos.
* include/mailutils/sys/imap.h (resp_code): Rename to
response to avoid confusion. All uses updated.
(response_code): New member.
(_mu_imap_process_tagged_response): New proto.
* include/mailutils/sys/mailbox.h (_mu_mailbox) <_copy>: New member.
* libmailutils/mailbox/Makefile.am (libmailbox_la_SOURCES): Add copy.c
* libmailutils/mailbox/copy.c: New file.
* libproto/imap/err.c (mu_imap_response): New function.
(mu_imap_response_code): New function.
* libproto/imap/mbox.c (_imap_copy_to_mailbox)
(_mu_imap_mailbox_init): Implement _copy method.
* libproto/imap/resplist.c (IS_LBRACE,IS_RBRACE): Fix macros.
* libproto/imap/response.c (_mu_imap_response): Call
_mu_imap_process_tagged_response to process tagged responses.
* libproto/imap/resproc.c (parse_response_code): Bugfix: expected
']' was set off by one.
(resptab)<code>: New member.
(_mu_imap_process_tagged_response): New function.

* mh/inc.c (options, mh_option, opt_handler): New option --moveto.
(move_to_mailbox): New variable.
(main): If move_to_mailbox is set, move messages to that mailbox
instead of deleting them.
* mh/mh_getopt.h (mh_arg)<ARG_MOVETO>: New constant.

* NEWS: Update.

* include/mailutils/folder.h: Add a comment.
* libmailutils/mailbox/folder.c: Minor formatting change.
1 parent 1cf13b32
GNU mailutils NEWS -- history of user-visible changes. 2012-02-26
GNU mailutils NEWS -- history of user-visible changes. 2012-04-29
Copyright (C) 2002-2012 Free Software Foundation, Inc.
See the end of file for copying conditions.
......@@ -116,6 +116,16 @@ See <http://mailutils.org/wiki/Timestamp_(Sieve_test)>.
** MH: improved compatibility with other implementations
** MH inc: new option --moveto
This option instructs the utility to move incorporated messages into
another folder instead of deleting them. It is implemented only for
input folders of type IMAP or IMAPS. A sample usage is:
inc -truncate -moveto Read -file imaps://imap.gmail.com
Note the `-truncate' option.
** mailutils-config is deprecated.
Use `mu cflags' and `mu ldflags' instead. The mailutils-config is
......@@ -202,6 +212,13 @@ transaction.
** Support for Maildir and MH formats considerably improved.
** The mailbox object contains a `copy' method.
This method copies the requested set of messages into another
mailbox. It is accessed using the `mu_mailbox_msgset_copy' or
`mu_mailbox_message_copy' functions. So far it is implememented
only for IMAP and IMAPS mailboxes.
** MIME support improved.
** Debugging support considerably improved.
......
......@@ -61,7 +61,8 @@ extern int mu_folder_enumerate (mu_folder_t, const char *,
extern int mu_folder_lsub (mu_folder_t, const char *, const char *,
mu_list_t *);
/* Stream settings. */
/* Stream settings. Don't use these functions.
FIXME: To be removed. */
extern int mu_folder_get_stream (mu_folder_t, mu_stream_t *)
__attribute__ ((deprecated));
extern int mu_folder_get_streamref (mu_folder_t, mu_stream_t *);
......
......@@ -133,6 +133,9 @@ int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier);
int mu_imap_trace (mu_imap_t imap, int op);
int mu_imap_trace_mask (mu_imap_t imap, int op, int lev);
enum mu_imap_response mu_imap_response (mu_imap_t imap);
int mu_imap_response_code (mu_imap_t imap);
int mu_imap_strerror (mu_imap_t imap, const char **pstr);
int mu_imap_session_state (mu_imap_t imap);
......@@ -178,21 +181,27 @@ extern struct mu_kwd _mu_imap_status_name_table[];
#define MU_IMAP_CB_UIDNEXT 4
#define MU_IMAP_CB_UIDVALIDITY 5
/* The following callbacks correspond to server responses and take two
arguments: a response code (see MU_IMAP_RESPONSE, below) in SDAT, and
human-readable text string as returned by the server in PDAT. The
latter can be NULL. */
/* The following callbacks correspond to unsolicited server responses and
take two arguments: a response code (see MU_IMAP_RESPONSE, below) in
SDAT, and human-readable text string as returned by the server in PDAT.
The latter can be NULL. */
#define MU_IMAP_CB_OK 6
#define MU_IMAP_CB_NO 7
#define MU_IMAP_CB_BAD 8
#define MU_IMAP_CB_BYE 9
#define MU_IMAP_CB_PREAUTH 10
/* These corresponde to the tagged server responses. The calling convention
is the same as above. */
#define MU_IMAP_CB_TAGGED_OK 11
#define MU_IMAP_CB_TAGGED_NO 12
#define MU_IMAP_CB_TAGGED_BAD 13
/* FETCH callback. Arguments: SDAT - message sequence number, PDAT - a
list (mu_list_t) of union mu_imap_fetch_response (see below). */
#define MU_IMAP_CB_FETCH 11
#define MU_IMAP_CB_FETCH 14
#define _MU_IMAP_CB_MAX 12
#define _MU_IMAP_CB_MAX 15
typedef void (*mu_imap_callback_t) (void *, int code, size_t sdat, void *pdat);
......@@ -202,8 +211,6 @@ void mu_imap_register_callback_function (mu_imap_t imap, int code,
mu_imap_callback_t callback,
void *data);
#define MU_IMAP_RESPONSE_TAGGED 0x10
#define MU_IMAP_RESPONSE_UNKNOWN 0
#define MU_IMAP_RESPONSE_ALERT 1
#define MU_IMAP_RESPONSE_BADCHARSET 2
......
......@@ -120,6 +120,14 @@ extern int mu_mailbox_get_iterator (mu_mailbox_t mbx,
extern int mu_mailbox_translate (mu_mailbox_t, int, size_t, size_t *);
/* Copy message into a folder */
#define MU_MAILBOX_COPY_UID 0x01
#define MU_MAILBOX_COPY_CREAT 0x02
extern int mu_mailbox_msgset_copy (mu_mailbox_t, mu_msgset_t, const char *,
int);
extern int mu_mailbox_message_copy (mu_mailbox_t, size_t, const char *, int);
#ifdef __cplusplus
}
#endif
......
......@@ -85,8 +85,10 @@ struct _mu_imap
{
int flags;
/* Holds the recect response code */
enum mu_imap_response resp_code;
/* Holds the recent response */
enum mu_imap_response response;
/* The recent response code */
int response_code;
/* Error string (if any) */
char *errstr;
......@@ -210,6 +212,7 @@ int _mu_imap_untagged_response_to_list (mu_imap_t imap, mu_list_t *plist);
int _mu_imap_process_untagged_response (mu_imap_t imap, mu_list_t list,
mu_imap_response_action_t fun,
void *data);
int _mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp);
int _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
void *data);
......
......@@ -75,6 +75,7 @@ struct _mu_mailbox
int (*_get_uidls) (mu_mailbox_t, mu_list_t);
int (*_translate) (mu_mailbox_t, int cmd, size_t, size_t *);
int (*_copy) (mu_mailbox_t, mu_msgset_t, const char *, int);
};
# ifdef __cplusplus
......
......@@ -24,6 +24,7 @@ libmailbox_la_SOURCES = \
attribute.c\
body.c\
bodystruct.c\
copy.c\
envelope.c\
folder.c\
fsfolder.c\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2001, 2004-2005, 2007, 2009-2012 Free Software
Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <mailutils/types.h>
#include <mailutils/mailbox.h>
#include <mailutils/stream.h>
#include <mailutils/errno.h>
#include <mailutils/msgset.h>
#include <mailutils/sys/mailbox.h>
int
mu_mailbox_msgset_copy (mu_mailbox_t mbox, mu_msgset_t msgset,
const char *dest, int flags)
{
if (!mbox)
return EINVAL;
if (!mbox->_copy)
return ENOSYS;
return mbox->_copy (mbox, msgset, dest, flags);
}
int
mu_mailbox_message_copy (mu_mailbox_t mbox, size_t msgno,
const char *dest, int flags)
{
int rc;
mu_msgset_t msgset;
int mode;
if (!mbox)
return EINVAL;
if (!mbox->_copy)
return ENOSYS;
mode = flags & MU_MAILBOX_COPY_UID ? MU_MSGSET_UID : MU_MSGSET_NUM;
rc = mu_msgset_create (&msgset, mbox, mode);
if (rc)
return rc;
rc = mu_msgset_add_range (msgset, 1, 1, mode);
if (rc == 0)
rc = mbox->_copy (mbox, msgset, dest, flags);
mu_msgset_destroy (&msgset);
return rc;
}
......@@ -475,12 +475,13 @@ mu_folder_delete (mu_folder_t folder, const char *name)
mailbox and call mailbox delete (remove) method. This is necessary
because certain types of mailboxes share a common folder (e.g. mbox,
maildir and mh all use filesystem folder), but have a different
internal structure. Supplying mu_folder_t with a knowledge of mailbox
internals will harm separation of concerns. On the other hand,
removing something without looking into it may well yield undesired
results. For example, a MH mailbox can hold another mailboxes, i.e.
be a folder itself. Removing it blindly would result in removing
these mailboxes as well, which is clearly not indended.
internal structure. Supplying mu_folder_t with knowledge about
mailbox internals will harm separation of concerns. On the other
hand, removing something without looking into it may well yield
undesired results. For example, a MH mailbox can hold another
mailboxes, i.e. be a folder itself. Removing it blindly would
result in removing these mailboxes as well, which is clearly not
indended.
To solve this folder and mailbox delete methods are tightly paired,
but without looking into each-others internal mechanisms. */
......
......@@ -121,7 +121,7 @@ mu_imap_append_stream_size (mu_imap_t imap, const char *mailbox, int flags,
case MU_IMAP_CLIENT_APPEND_RX:
status = _mu_imap_response (imap, NULL, NULL);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
status = 0;
......
......@@ -113,7 +113,7 @@ mu_imap_capability (mu_imap_t imap, int reread, mu_iterator_t *piter)
NULL);
imap->client_state = MU_IMAP_CLIENT_READY;
MU_IMAP_CHECK_EAGAIN (imap, status);
if (imap->resp_code != MU_IMAP_OK)
if (imap->response != MU_IMAP_OK)
return MU_ERR_REPLY;
else
{
......
......@@ -25,7 +25,7 @@
void
_mu_close_handler (mu_imap_t imap)
{
if (imap->resp_code == MU_IMAP_OK)
if (imap->response == MU_IMAP_OK)
imap->session_state = MU_IMAP_SESSION_AUTH;
}
......
......@@ -71,3 +71,21 @@ mu_imap_strerror (mu_imap_t imap, const char **pstr)
*pstr = "(no recent reply)";
return MU_ERR_NOENT;
}
enum mu_imap_response
mu_imap_response (mu_imap_t imap)
{
if (!imap)
return MU_IMAP_BAD;
return imap->response;
}
int
mu_imap_response_code (mu_imap_t imap)
{
if (!imap)
return -1;
return imap->response_code;
}
......
......@@ -71,7 +71,7 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
MU_IMAP_CHECK_EAGAIN (imap, status);
if (cmd->tagged_handler)
cmd->tagged_handler (imap);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
status = 0;
......
......@@ -126,7 +126,7 @@ mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc)
case MU_IMAP_CLIENT_ID_RX:
status = _mu_imap_response (imap, parse_id_reply, passoc);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
status = 0;
......
......@@ -56,7 +56,7 @@ mu_imap_login (mu_imap_t imap, const char *user, const char *pass)
status = _mu_imap_response (imap, NULL, NULL);
imap->client_state = MU_IMAP_CLIENT_READY;
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
imap->session_state = MU_IMAP_SESSION_AUTH;
......
......@@ -1252,6 +1252,41 @@ _imap_mbx_is_updated (mu_mailbox_t mbox)
return imbx->flags & _MU_IMAP_MBX_UPTODATE;
}
static int
_imap_copy_to_mailbox (mu_mailbox_t mbox, mu_msgset_t msgset,
const char *mailbox, int flags)
{
struct _mu_imap_mailbox *imbx = mbox->data;
mu_folder_t folder = mbox->folder;
mu_imap_t imap = folder->data;
int rc;
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("copying messages to mailbox %s"), mailbox));
_imap_mbx_clrerr (imbx);
rc = mu_imap_copy (imap, flags & MU_MAILBOX_COPY_UID, msgset, mailbox);
if (rc)
{
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
(_("mu_imap_copy: %s"), mu_strerror (rc)));
if (rc)
{
if (mu_imap_response_code (imap) == MU_IMAP_RESPONSE_TRYCREATE)
{
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
(_("creating mailbox %s"), mailbox));
rc = mu_imap_mailbox_create (imap, mailbox);
if (rc == 0)
rc = mu_imap_copy (imap, flags & MU_MAILBOX_COPY_UID,
msgset, mailbox);
}
}
imbx->last_error = rc;
}
return rc;
}
int
_mu_imap_mailbox_init (mu_mailbox_t mailbox)
{
......@@ -1279,6 +1314,7 @@ _mu_imap_mailbox_init (mu_mailbox_t mailbox)
mailbox->_sync = _imap_mbx_sync;
mailbox->_append_message = _imap_mbx_append_message;
mailbox->_copy = _imap_copy_to_mailbox;
return 0;
}
......
......@@ -55,8 +55,8 @@ _mu_imap_response_list_create (mu_imap_t imap, mu_list_t *plist)
return 0;
}
#define IS_LBRACE(p) ((p)[0] == '(')
#define IS_RBRACE(p) ((p)[0] == ')')
#define IS_LBRACE(p) ((p)[0] == '(' && !(p)[1])
#define IS_RBRACE(p) ((p)[0] == ')' && !(p)[1])
#define IS_NIL(p) (strcmp (p, "NIL") == 0)
static struct imap_list_element *
......
......@@ -27,13 +27,6 @@
#include <mailutils/errno.h>
#include <mailutils/sys/imap.h>
static void
response_to_errstr (mu_imap_t imap, size_t argc, char **argv)
{
if (argc && strcmp (argv[argc-1], "]"))
_mu_imap_seterrstrz (imap, argv[argc-1]);
}
int
_mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
void *data)
......@@ -83,29 +76,17 @@ _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
/*imap->client_state = MU_IMAP_CLIENT_ERROR;*/
status = MU_ERR_BADREPLY;
}
else if (strcmp (wv[1], "OK") == 0)
else
{
imap->resp_code = MU_IMAP_OK;
response_to_errstr (imap, wc, wv);
}
else if (strcmp (wv[1], "NO") == 0)
mu_list_t list;
status = _mu_imap_untagged_response_to_list (imap, &list);
if (status == 0)
{
imap->resp_code = MU_IMAP_NO;
response_to_errstr (imap, wc, wv);
if (_mu_imap_process_tagged_response (imap, list))
status = MU_ERR_BADREPLY;
mu_list_destroy (&list);
}
else if (strcmp (wv[1], "BAD") == 0)
{
imap->resp_code = MU_IMAP_BAD;
response_to_errstr (imap, wc, wv);
/* This may be so important that CB_BAD callback is
* overloaded to handle this case as well.
*/
mu_imap_callback (imap, MU_IMAP_CB_BAD,
MU_IMAP_RESPONSE_TAGGED,
wc >= 1 ? wv[wc-1] : NULL);
}
else
status = MU_ERR_BADREPLY;
MU_IMAP_FSET (imap, MU_IMAP_RESP);
}
else
......
......@@ -72,7 +72,7 @@ parse_response_code (mu_imap_t imap, mu_list_t resp)
if (mu_kwd_xlat_name (mu_imap_response_codes, arg->v.string, &rcode))
return -1;
arg = _mu_imap_list_at (resp, 4);
arg = _mu_imap_list_at (resp, 3);
if (!arg || !_mu_imap_list_element_is_string (arg, "]"))
return -1;
}
......@@ -217,6 +217,7 @@ struct resptab
{
char *name;
mu_imap_response_action_t action;
int code;
};
static struct resptab resptab[] = {
......@@ -351,4 +352,74 @@ _mu_imap_process_untagged_response (mu_imap_t imap, mu_list_t list,
return 0;
}
static void
default_tagged_response (mu_imap_t imap, int code, mu_list_t resp, void *data)
{
struct imap_list_element *arg;
if (mu_list_tail (resp, (void*) &arg) == 0 &&
arg->type == imap_eltype_string)
_mu_imap_seterrstrz (imap, arg->v.string);
imap->response_code = parse_response_code (imap, resp);
mu_imap_callback (imap, code, imap->response_code,
arg ? arg->v.string : NULL);
}
static void
ok_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
{
default_tagged_response (imap, MU_IMAP_CB_TAGGED_OK, resp, data);
}
static void
no_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
{
default_tagged_response (imap, MU_IMAP_CB_TAGGED_NO, resp, data);
}
static void
bad_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
{
default_tagged_response (imap, MU_IMAP_CB_TAGGED_BAD, resp, data);
}
static struct resptab tagged_resptab[] = {
{ "OK", ok_tagged_response, MU_IMAP_OK },
{ "NO", no_tagged_response, MU_IMAP_NO },
{ "BAD", bad_tagged_response, MU_IMAP_BAD },
{ NULL }
};
static int
_std_tagged_response (mu_imap_t imap, size_t count, mu_list_t resp)
{
struct resptab *rp;
struct imap_list_element *arg = _mu_imap_list_at (resp, 0);
if (!arg)
return 1;
if (arg->type == imap_eltype_string)
for (rp = tagged_resptab; rp->name; rp++)
{
if (mu_c_strcasecmp (rp->name, arg->v.string) == 0)
{
imap->response = rp->code;
rp->action (imap, resp, NULL);
return 0;
}
}
return 1;
}
int
_mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp)
{
size_t count;
if (mu_list_count (resp, &count))
return 1;
return _std_tagged_response (imap, count, resp);
}
......
......@@ -113,7 +113,7 @@ mu_imap_select (mu_imap_t imap, const char *mbox, int writable,
memset (&imap->mbox_stat, 0, sizeof (imap->mbox_stat));
status = _mu_imap_response (imap, _select_response_action, NULL);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
imap->session_state = MU_IMAP_SESSION_SELECTED;
......
......@@ -60,7 +60,7 @@ mu_imap_starttls (mu_imap_t imap)
case MU_IMAP_CLIENT_STARTTLS_RX:
status = _mu_imap_response (imap, NULL, NULL);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
status = mu_imapio_get_streams (imap->io, streams);
......
......@@ -185,7 +185,7 @@ mu_imap_status (mu_imap_t imap, const char *mboxname, struct mu_imap_stat *ps)
status = _mu_imap_response (imap, _status_response_action, &sd);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
break;
......
......@@ -67,7 +67,7 @@ mu_imap_store_flags (mu_imap_t imap, int uid, mu_msgset_t msgset,
/* FIXME: Handle unsolicited responses */
status = _mu_imap_response (imap, NULL, NULL);
MU_IMAP_CHECK_EAGAIN (imap, status);
switch (imap->resp_code)
switch (imap->response)
{
case MU_IMAP_OK:
status = 0;
......
......@@ -42,6 +42,8 @@ static struct argp_option options[] = {
{"truncate", ARG_TRUNCATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("truncate source mailbox after incorporating (default)")},
{"notruncate", ARG_NOTRUNCATE, NULL, OPTION_HIDDEN, ""},
{"moveto", ARG_MOVETO, N_("MAILBOX"), 0,
N_("move incorporated messages to MAILBOX instead of deleting them") },
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("set output width")},
{"quiet", ARG_QUIET, 0, 0,
......@@ -58,6 +60,7 @@ struct mh_option mh_option[] = {
{ "form", MH_OPT_ARG, "format-file" },
{ "format", MH_OPT_ARG, "string" },
{ "truncate", MH_OPT_BOOL },
{ "moveto", MH_OPT_ARG, "folder" },
{ "width", MH_OPT_ARG, "number" },
{ "quiet" },
{ NULL }
......@@ -72,6 +75,7 @@ static int changecur = -1;
static int truncate_source = -1;
static int quiet = 0;
static const char *append_folder;
static const char *move_to_mailbox;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
......@@ -123,6 +127,10 @@ opt_handler (int key, char *arg, struct argp_state *state)
truncate_source = 0;
break;
case ARG_MOVETO:
move_to_mailbox = arg;
break;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
......@@ -143,7 +151,8 @@ opt_handler (int key, char *arg, struct argp_state *state)
}
void
list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno, size_t width)
list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno,
size_t width)
{
mu_message_t msg;
char *buf = NULL;
......@@ -275,6 +284,33 @@ main (int argc, char **argv)
}
}
if (truncate_source && move_to_mailbox)
{
mu_msgset_t msgset;
rc = mu_msgset_create (&msgset, input, MU_MSGSET_NUM);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
else
{
rc = mu_msgset_add_range (msgset, 1, total, MU_MSGSET_NUM);
if (rc)
mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc);
else
{
rc = mu_mailbox_msgset_copy (input, msgset, move_to_mailbox,
MU_MAILBOX_COPY_CREAT);
if (rc)
{
mu_error (_("failed to move messages to %s: %s"),
move_to_mailbox, mu_strerror (rc));
truncate_source = 0;
}
}
mu_msgset_destroy (&msgset);
}
}
if (!changecur)
{
mu_property_t prop = mh_mailbox_get_property (output);
......
......@@ -92,6 +92,7 @@ enum mh_arg {
ARG_LIST,
ARG_MIME,
ARG_MOREPROC,
ARG_MOVETO,
ARG_MSGID,
ARG_NOALIAS,
ARG_NOAUDIT,
......