9
9
#include "maildir-storage.h"
10
10
#include "maildir-uidlist.h"
11
11
#include "maildir-keywords.h"
12
#include "maildir-filename.h"
12
#include "maildir-filename-flags.h"
13
13
#include "maildir-sync.h"
24
24
static const char *
25
25
maildir_filename_guess(struct maildir_mailbox *mbox, uint32_t uid,
26
const char *fname, bool *have_flags_r)
27
enum maildir_uidlist_rec_flag *uidlist_flags,
29
31
struct mail_index_view *view = mbox->flags_view;
30
32
struct maildir_keywords_sync_ctx *kw_ctx;
31
33
enum mail_flags flags;
32
34
ARRAY_TYPE(keyword_indexes) keywords;
35
38
if (view == NULL || !mail_index_lookup_seq(view, uid, &seq)) {
41
44
mail_index_lookup_view_flags(view, seq, &flags, &keywords);
42
45
if (array_count(&keywords) == 0) {
43
46
*have_flags_r = (flags & MAIL_FLAGS_NONRECENT) != 0;
44
fname = maildir_filename_set_flags(NULL, fname, flags, NULL);
47
fname = maildir_filename_flags_set(NULL, fname, flags, NULL);
46
49
*have_flags_r = TRUE;
47
50
kw_ctx = maildir_keywords_sync_init_readonly(mbox->keywords,
49
fname = maildir_filename_set_flags(kw_ctx, fname,
52
fname = maildir_filename_flags_set(kw_ctx, fname,
51
54
maildir_keywords_sync_deinit(&kw_ctx);
58
/* don't even bother looking into new/ dir */
59
*uidlist_flags &= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
60
} else if ((*uidlist_flags & MAILDIR_UIDLIST_REC_FLAG_MOVED) == 0 &&
61
((*uidlist_flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0 ||
62
index_mailbox_is_recent(&mbox->box, uid))) {
63
/* probably in new/ dir, drop ":2," from fname */
64
*uidlist_flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
65
p = strrchr(fname, MAILDIR_INFO_SEP);
67
fname = t_strdup_until(fname, p);
64
ret = maildir_uidlist_lookup(mbox->uidlist, uid, &flags, &fname);
81
ret = maildir_sync_lookup(mbox, uid, &flags, &fname);
66
83
return ret == 0 ? -2 : -1;
68
85
if ((flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
69
86
/* let's see if we can guess the filename based on index */
70
fname = maildir_filename_guess(mbox, uid, fname, &have_flags);
72
/* don't even bother looking into new/ dir */
73
flags &= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
87
fname = maildir_filename_guess(mbox, uid, fname,
77
92
if ((flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0) {
78
93
/* probably in new/ dir */
79
path = t_strconcat(mbox->box.path, "/new/", fname, NULL);
80
ret = callback(mbox, path, context);
85
path = t_strconcat(mbox->box.path, "/cur/", fname, NULL);
86
ret = callback(mbox, path, context);
94
path = t_strconcat(mailbox_get_path(&mbox->box),
95
"/new/", fname, NULL);
96
ret = callback(mbox, path, context);
99
path = t_strconcat(mailbox_get_path(&mbox->box), "/cur/",
101
ret = callback(mbox, path, context);
103
if (ret > 0 && (flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
104
/* file was found. make sure we remember its latest name. */
105
maildir_uidlist_update_fname(mbox->uidlist, fname);
106
} else if (ret == 0 &&
107
(flags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) == 0) {
108
/* file wasn't found. mark this message nonsynced, so we can
109
retry the lookup by guessing the flags */
110
maildir_uidlist_add_flags(mbox->uidlist, fname,
111
MAILDIR_UIDLIST_REC_FLAG_NONSYNCED);
114
140
ret = maildir_file_do_try(mbox, uid, callback, context);
142
if (ret == 0 && mbox->storage->set->maildir_very_dirty_syncs) T_BEGIN {
143
/* try guessing again with refreshed flags */
144
if (maildir_sync_refresh_flags_view(mbox) == 0)
145
ret = maildir_file_do_try(mbox, uid, callback, context);
116
147
for (i = 0; i < MAILDIR_RESYNC_RETRY_COUNT && ret == 0; i++) {
117
148
/* file is either renamed or deleted. sync the maildir and
118
149
see which one. if file appears to be renamed constantly,
135
166
static int maildir_create_path(struct mailbox *box, const char *path,
136
167
enum mailbox_list_path_type type, bool retry)
138
const char *p, *parent;
169
const struct mailbox_permissions *perm = mailbox_get_permissions(box);
170
const char *p, *parent, *error;
140
if (mkdir_chgrp(path, box->dir_create_mode, box->file_create_gid,
141
box->file_create_gid_origin) == 0)
172
if (mkdir_chgrp(path, perm->dir_create_mode, perm->file_create_gid,
173
perm->file_create_gid_origin) == 0)
155
187
/* create index/control root directory */
156
188
parent = t_strdup_until(path, p);
157
if (mailbox_list_mkdir(box->list, parent, type) == 0) {
189
if (mailbox_list_mkdir_root(box->list, parent, type, &error) == 0) {
158
190
/* should work now, try again */
159
191
return maildir_create_path(box, path, type, FALSE);
161
193
/* fall through */
194
mail_storage_set_critical(box->storage,
195
"Couldn't create %s: %s", parent, error);
164
198
mail_storage_set_critical(box->storage,
179
213
/* @UNSAFE: get a list of directories we want to create */
180
214
for (i = 0; i < N_ELEMENTS(subdirs); i++) {
181
215
types[i] = MAILBOX_LIST_PATH_TYPE_MAILBOX;
182
dirs[i] = t_strconcat(box->path, "/", subdirs[i], NULL);
216
dirs[i] = t_strconcat(mailbox_get_path(box),
217
"/", subdirs[i], NULL);
184
219
types[i] = MAILBOX_LIST_PATH_TYPE_CONTROL;
185
220
dirs[i++] = mailbox_list_get_path(box->list, box->name,
212
if (stat(box->path, &st) < 0) {
247
if (stat(mailbox_get_path(box), &st) < 0) {
213
248
if (errno == ENOENT)
214
249
mailbox_set_deleted(box);
216
251
mail_storage_set_critical(box->storage,
217
"stat(%s) failed: %m", box->path);
252
"stat(%s) failed: %m", mailbox_get_path(box));