we don't keep rewriting the name just in case some backend switches
between separators when accessed different ways. */
- /* Get the current mailbox name with \0 separators. */
- char sep = mailbox_list_get_hierarchy_sep(box->list);
- char *box_zerosep_name = t_strdup_noconst(box->name);
- size_t box_name_len = strlen(box_zerosep_name);
- for (size_t i = 0; i < box_name_len; i++) {
- if (box_zerosep_name[i] == sep)
- box_zerosep_name[i] = '\0';
- }
+ /* Get the current mailbox name with \0 separators and unesacped. */
+ size_t box_name_len;
+ const unsigned char *box_zerosep_name =
+ mailbox_name_hdr_encode(box->list, box->name, &box_name_len);
/* Does it match what's in the header now? */
mail_index_get_header_ext(box->view, box->box_name_hdr_ext_id,
(void)mail_index_transaction_commit(&trans);
} else if (name_hdr_size > 0) {
/* Mailbox name is corrupted. Rename it to the previous name. */
- char sep = mailbox_list_get_hierarchy_sep(box->list);
- char *newname = t_malloc0(name_hdr_size + 1);
- memcpy(newname, name_hdr, name_hdr_size);
- for (size_t i = 0; i < name_hdr_size; i++) {
- if (newname[i] == '\0')
- newname[i] = sep;
- }
-
+ const char *newname =
+ mailbox_name_hdr_decode_storage_name(
+ box->list, name_hdr, name_hdr_size);
index_list_rename_corrupted(box, newname);
}
return 0;
return 0;
}
+const unsigned char *
+mailbox_name_hdr_encode(struct mailbox_list *list, const char *storage_name,
+ size_t *name_len_r)
+{
+ const char sep[] = {
+ mailbox_list_get_hierarchy_sep(list),
+ '\0'
+ };
+ const char **name_parts =
+ (const char **)p_strsplit(unsafe_data_stack_pool, storage_name, sep);
+ if (list->set.storage_name_escape_char != '\0') {
+ for (unsigned int i = 0; name_parts[i] != NULL; i++) {
+ mailbox_list_name_unescape(&name_parts[i],
+ list->set.storage_name_escape_char);
+ }
+ }
+
+ string_t *str = t_str_new(64);
+ str_append(str, name_parts[0]);
+ for (unsigned int i = 1; name_parts[i] != NULL; i++) {
+ str_append_c(str, '\0');
+ str_append(str, name_parts[i]);
+ }
+ *name_len_r = str_len(str);
+ return str_data(str);
+}
+
+const char *
+mailbox_name_hdr_decode_storage_name(struct mailbox_list *list,
+ const unsigned char *name_hdr,
+ size_t name_hdr_size)
+{
+ const char list_sep = mailbox_list_get_hierarchy_sep(list);
+ const char escape_char = list->set.storage_name_escape_char;
+ string_t *storage_name = t_str_new(name_hdr_size);
+ while (name_hdr_size > 0) {
+ const unsigned char *p = memchr(name_hdr, '\0', name_hdr_size);
+ size_t name_part_len;
+ if (p == NULL) {
+ name_part_len = name_hdr_size;
+ name_hdr_size = 0;
+ } else {
+ name_part_len = p - name_hdr;
+ i_assert(name_hdr_size > name_part_len);
+ name_hdr_size -= name_part_len + 1;
+ }
+
+ if (escape_char == '\0')
+ str_append_data(storage_name, name_hdr, name_part_len);
+ else {
+ const char *name_part =
+ t_strndup(name_hdr, name_part_len);
+ str_append(storage_name,
+ mailbox_list_escape_name_params(name_part,
+ "", '\0', list_sep, escape_char,
+ list->set.maildir_name));
+ }
+
+ if (p != NULL)
+ name_hdr += name_part_len + 1;
+ }
+ return str_c(storage_name);
+}
+
bool mailbox_list_index_need_refresh(struct mailbox_list_index *ilist,
struct mail_index_view *view)
{
void mailbox_list_index_node_unlink(struct mailbox_list_index *ilist,
struct mailbox_list_index_node *node);
+/* Return mailbox name encoded into box-name header. */
+const unsigned char *
+mailbox_name_hdr_encode(struct mailbox_list *list, const char *storage_name,
+ size_t *name_len_r);
+/* Return mailbox name decoded from box-name header. */
+const char *
+mailbox_name_hdr_decode_storage_name(struct mailbox_list *list,
+ const unsigned char *name_hdr,
+ size_t name_hdr_size);
+
int mailbox_list_index_index_open(struct mailbox_list *list);
bool mailbox_list_index_need_refresh(struct mailbox_list_index *ilist,
struct mail_index_view *view);