예제 #1
0
static void cmd_mailbox_mutf7(int argc, char *argv[])
{
	string_t *str;
	bool from_utf8;
	unsigned int i;
	int c;

	from_utf8 = TRUE;
	while ((c = getopt(argc, argv, "78")) > 0) {
		switch (c) {
		case '7':
			from_utf8 = FALSE;
			break;
		case '8':
			from_utf8 = TRUE;
			break;
		default:
			help(&doveadm_cmd_mailbox_mutf7);
		}
	}
	argv += optind;

	if (argv[0] == NULL)
		help(&doveadm_cmd_mailbox_mutf7);

	str = t_str_new(128);
	for (i = 0; argv[i] != NULL; i++) {
		str_truncate(str, 0);
		if (from_utf8) {
			if (imap_utf8_to_utf7(argv[i], str) < 0) {
				i_error("Mailbox name not valid UTF-8: %s",
					argv[i]);
				doveadm_exit_code = EX_DATAERR;
			}
		} else {
			if (imap_utf7_to_utf8(argv[i], str) < 0) {
				i_error("Mailbox name not valid mUTF-7: %s",
					argv[i]);
				doveadm_exit_code = EX_DATAERR;
			}
		}
		printf("%s\n", str_c(str));
	}
}
static void list_namespaces(struct mail_namespace *ns,
			    enum mail_namespace_type type, string_t *str)
{
	string_t *mutf7_prefix = t_str_new(64);
	char ns_sep;
	bool found = FALSE;

	while (ns != NULL) {
		if (ns->type == type &&
		    (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) {
			if (!found) {
				str_append_c(str, '(');
				found = TRUE;
			}
			ns_sep = mail_namespace_get_sep(ns);
			str_append_c(str, '(');

			str_truncate(mutf7_prefix, 0);
			if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) {
				i_panic("LIST: Namespace prefix not UTF-8: %s",
					ns->prefix);
			}

			imap_append_string(str, str_c(mutf7_prefix));
			str_append(str, " \"");
			if (ns_sep == '\\')
				str_append_c(str, '\\');
			str_append_c(str, ns_sep);
			str_append(str, "\")");
		}

		ns = ns->next;
	}

	if (found)
		str_append_c(str, ')');
	else
		str_append(str, "NIL");
}
예제 #3
0
static int
maildir_fill_readdir_entry(struct maildir_list_iterate_context *ctx,
			   struct imap_match_glob *glob, const struct dirent *d,
			   bool update_only)
{
	struct mailbox_list *list = ctx->ctx.list;
	const char *fname, *storage_name, *vname;
	enum mailbox_info_flags flags;
	enum imap_match_result match;
	struct mailbox_node *node;
	bool created;
	int ret;

	fname = d->d_name;
	if (fname[0] == ctx->prefix_char)
		storage_name = fname + 1;
	else {
		if (ctx->prefix_char != '\0' || fname[0] == '.')
			return 0;
		storage_name = fname;
	}

	/* skip . and .. */
	if (fname[0] == '.' &&
	    (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')))
		return 0;

	vname = mailbox_list_get_vname(list, storage_name);
	if (!uni_utf8_str_is_valid(vname)) {
		/* the storage_name is completely invalid, rename it to
		   something more sensible. we could do this for all names that
		   aren't valid mUTF-7, but that might lead to accidents in
		   future when UTF-8 storage names are used */
		const char *src = t_strdup_printf("%s/%s", ctx->dir, fname);
		string_t *destvname = t_str_new(128);
		string_t *dest = t_str_new(128);

		(void)uni_utf8_get_valid_data((const void *)fname,
					      strlen(fname), destvname);

		str_append(dest, ctx->dir);
		str_append_c(dest, '/');
		(void)imap_utf8_to_utf7(str_c(destvname), dest);

		if (rename(src, str_c(dest)) < 0 && errno != ENOENT)
			i_error("rename(%s, %s) failed: %m", src, str_c(dest));
		/* just skip this in this iteration, we'll see it on the
		   next list */
		return 0;
	}

	/* make sure the pattern matches */
	match = imap_match(glob, vname);
	if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) == 0)
		return 0;

	/* check if this is an actual mailbox */
	if (maildir_delete_trash_dir(ctx, fname))
		return 0;

	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
		ret = mailbox_list_dirent_is_alias_symlink(list, ctx->dir, d);
		if (ret != 0)
			return ret < 0 ? -1 : 0;
	}
	T_BEGIN {
		ret = list->v.get_mailbox_flags(list, ctx->dir, fname,
				mailbox_list_get_file_type(d), &flags);
	} T_END;
	if (ret <= 0)
		return ret;

	/* we know the children flags ourself, so ignore if any of
	   them were set. */
	flags &= ~(MAILBOX_NOINFERIORS | MAILBOX_CHILDREN | MAILBOX_NOCHILDREN);

	if ((match & IMAP_MATCH_PARENT) != 0)
		maildir_fill_parents(ctx, glob, update_only, vname);
	else {
		created = FALSE;
		node = update_only ?
			mailbox_tree_lookup(ctx->tree_ctx, vname) :
			mailbox_tree_get(ctx->tree_ctx, vname, &created);

		if (node != NULL) {
			if (created)
				node->flags = MAILBOX_NOCHILDREN;
			else
				node->flags &= ~MAILBOX_NONEXISTENT;
			if (!update_only)
				node->flags |= MAILBOX_MATCHED;
			node->flags |= flags;
			node_fix_parents(node);
		} else {
			i_assert(update_only);
			maildir_set_children(ctx, vname);
		}
	}
	return 0;
}