1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "imap-common.h"
4 #include "mail-namespace.h"
5 #include "imap-commands.h"
6 
cmd_rename(struct client_command_context * cmd)7 bool cmd_rename(struct client_command_context *cmd)
8 {
9 	struct mail_namespace *old_ns, *new_ns;
10 	struct mailbox *old_box, *new_box;
11 	const char *oldname, *newname;
12 	size_t oldlen;
13 
14 	/* <old name> <new name> */
15 	if (!client_read_string_args(cmd, 2, &oldname, &newname))
16 		return FALSE;
17 
18 	old_ns = client_find_namespace(cmd, &oldname);
19 	if (old_ns == NULL)
20 		return TRUE;
21 	new_ns = client_find_namespace(cmd, &newname);
22 	if (new_ns == NULL)
23 		return TRUE;
24 
25 	if (old_ns == new_ns) {
26 		/* disallow box -> box/child, because it may break clients and
27 		   there's really no point in doing it anyway. */
28 		old_ns = mailbox_list_get_namespace(old_ns->list);
29 		oldlen = strlen(oldname);
30 		if (str_begins(newname, oldname) &&
31 		    newname[oldlen] == mail_namespace_get_sep(old_ns)) {
32 			client_send_tagline(cmd,
33 				"NO Can't rename mailbox under its own child.");
34 			return TRUE;
35 		}
36 	}
37 
38 	old_box = mailbox_alloc(old_ns->list, oldname, 0);
39 	new_box = mailbox_alloc(new_ns->list, newname, 0);
40 	mailbox_set_reason(old_box, "RENAME from");
41 	mailbox_set_reason(new_box, "RENAME to");
42 	event_add_str(cmd->event, "old_mailbox", mailbox_get_vname(old_box));
43 	event_add_str(cmd->event, "new_mailbox", mailbox_get_vname(new_box));
44 	if (mailbox_rename(old_box, new_box) < 0)
45 		client_send_box_error(cmd, old_box);
46 	else
47 		client_send_tagline(cmd, "OK Rename completed.");
48 	mailbox_free(&old_box);
49 	mailbox_free(&new_box);
50 	return TRUE;
51 }
52