Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-storage/index/mbox/mbox-storage.c @ 160:ff05b320482c HEAD
Bigger changes.. full_virtual_size was removed from index record and
MessagePart caching is now forced. Also added per-message flags, including
binary flags which can be used to check if CRs need to be inserted into
message data.
Added mbox-rewrite support which can be used to write out mbox file with
updated flags. This still has the problem of being able to read changed
custom flags, that'll require another bigger change.
There's also several other mostly mbox related fixes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 06 Sep 2002 16:43:58 +0300 |
parents | 899ea73710fc |
children | 73bf05a1d862 |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
4 #include "unlink-directory.h" | |
5 #include "subscription-file/subscription-file.h" | |
6 #include "mbox-index.h" | |
7 #include "mbox-storage.h" | |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <unistd.h> | |
12 #include <fcntl.h> | |
13 #include <sys/stat.h> | |
14 | |
15 #define CREATE_MODE 0770 /* umask() should limit it more */ | |
16 | |
17 extern MailStorage mbox_storage; | |
18 static Mailbox mbox_mailbox; | |
19 | |
20 static int mbox_autodetect(const char *data) | |
21 { | |
22 const char *path; | |
23 struct stat st; | |
24 | |
25 path = t_strconcat(data, "/.imap", NULL); | |
26 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode) && | |
27 access(path, R_OK|W_OK|X_OK) == 0) | |
28 return TRUE; | |
29 | |
30 path = t_strconcat(data, "/inbox", NULL); | |
31 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) && | |
32 access(path, R_OK|W_OK) == 0) | |
33 return TRUE; | |
34 | |
35 path = t_strconcat(data, "/mbox", NULL); | |
36 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) && | |
37 access(path, R_OK|W_OK) == 0) | |
38 return TRUE; | |
39 | |
40 return FALSE; | |
41 } | |
42 | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
13
diff
changeset
|
43 static MailStorage *mbox_create(const char *data, const char *user) |
0 | 44 { |
45 MailStorage *storage; | |
46 const char *home, *path; | |
47 | |
48 if (data == NULL || *data == '\0') { | |
49 /* we'll need to figure out the mail location ourself. | |
50 it's root dir if we've already chroot()ed, otherwise | |
51 either $HOME/mail or $HOME/Mail */ | |
52 if (mbox_autodetect("")) | |
53 data = "/"; | |
54 else { | |
55 home = getenv("HOME"); | |
56 if (home != NULL) { | |
57 path = t_strconcat(home, "/mail", NULL); | |
58 if (access(path, R_OK|W_OK|X_OK) == 0) | |
59 data = path; | |
60 else { | |
61 path = t_strconcat(home, "/Mail", NULL); | |
62 if (access(path, R_OK|W_OK|X_OK) == 0) | |
63 data = path; | |
64 } | |
65 } | |
66 } | |
67 } | |
68 | |
69 if (data == NULL) | |
70 return NULL; | |
71 | |
72 storage = i_new(MailStorage, 1); | |
73 memcpy(storage, &mbox_storage, sizeof(MailStorage)); | |
74 | |
75 storage->dir = i_strdup(data); | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
13
diff
changeset
|
76 storage->user = i_strdup(user); |
0 | 77 return storage; |
78 } | |
79 | |
80 static void mbox_free(MailStorage *storage) | |
81 { | |
82 i_free(storage->dir); | |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
13
diff
changeset
|
83 i_free(storage->user); |
0 | 84 i_free(storage); |
85 } | |
86 | |
87 static int mbox_is_valid_name(MailStorage *storage, const char *name) | |
88 { | |
24
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
89 const char *p; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
90 int newdir; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
91 |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
92 if (name[0] == '\0' || name[0] == storage->hierarchy_sep) |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
93 return FALSE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
94 |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
95 /* make sure there's no "../" or "..\" stuff */ |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
96 newdir = TRUE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
97 for (p = name; *p != '\0'; p++) { |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
98 if (newdir && p[0] == '.' && p[1] == '.' && |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
99 (p[2] == '/' || p[2] == '\\')) |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
100 return FALSE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
101 newdir = p[0] == '/' || p[0] == '\\'; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
102 } |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
103 |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
104 return TRUE; |
0 | 105 } |
106 | |
107 static const char *mbox_get_index_dir(const char *mbox_path) | |
108 { | |
109 const char *p, *rootpath; | |
110 | |
111 p = strrchr(mbox_path, '/'); | |
112 if (p == NULL) | |
113 return t_strconcat(".imap/", mbox_path); | |
114 else { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
115 rootpath = t_strdup_until(mbox_path, p); |
0 | 116 return t_strconcat(rootpath, "/.imap/", p+1, NULL); |
117 } | |
118 } | |
119 | |
120 static int create_mbox_index_dirs(const char *mbox_path, int verify) | |
121 { | |
122 const char *index_dir, *imap_dir; | |
123 | |
124 index_dir = mbox_get_index_dir(mbox_path); | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
125 imap_dir = t_strdup_until(index_dir, strstr(index_dir, ".imap/") + 5); |
0 | 126 |
127 if (mkdir(imap_dir, CREATE_MODE) == -1 && errno != EEXIST) | |
128 return FALSE; | |
129 if (mkdir(index_dir, CREATE_MODE) == -1 && (errno != EEXIST || !verify)) | |
130 return FALSE; | |
131 | |
132 return TRUE; | |
133 } | |
134 | |
135 static void verify_inbox(MailStorage *storage) | |
136 { | |
137 char path[1024]; | |
138 int fd; | |
139 | |
140 i_snprintf(path, sizeof(path), "%s/inbox", storage->dir); | |
141 | |
142 /* make sure inbox file itself exists */ | |
143 fd = open(path, O_RDWR | O_CREAT | O_EXCL); | |
144 if (fd != -1) | |
145 (void)close(fd); | |
146 | |
147 /* make sure the index directories exist */ | |
148 (void)create_mbox_index_dirs(path, TRUE); | |
149 } | |
150 | |
151 static Mailbox *mbox_open(MailStorage *storage, const char *name, int readonly) | |
152 { | |
153 IndexMailbox *ibox; | |
154 const char *path, *index_dir; | |
155 | |
156 /* name = "foo/bar" | |
157 mbox_path = "/mail/foo/bar" | |
158 index_dir = "/mail/foo/.imap/bar" */ | |
159 path = t_strconcat(storage->dir, "/", name, NULL); | |
160 index_dir = mbox_get_index_dir(path); | |
161 | |
162 ibox = index_storage_init(storage, &mbox_mailbox, | |
163 mbox_index_alloc(index_dir, path), | |
164 name, readonly); | |
165 if (ibox != NULL) | |
166 ibox->expunge_locked = mbox_expunge_locked; | |
167 return (Mailbox *) ibox; | |
168 } | |
169 | |
170 static Mailbox *mbox_open_mailbox(MailStorage *storage, const char *name, | |
171 int readonly) | |
172 { | |
173 struct stat st; | |
174 char path[1024]; | |
175 | |
176 mail_storage_clear_error(storage); | |
177 | |
178 /* INBOX is always case-insensitive */ | |
179 if (strcasecmp(name, "INBOX") == 0) { | |
180 /* make sure inbox exists */ | |
181 verify_inbox(storage); | |
182 return mbox_open(storage, "inbox", readonly); | |
183 } | |
184 | |
24
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
185 if (!mbox_is_valid_name(storage, name)) { |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
186 mail_storage_set_error(storage, "Invalid mailbox name"); |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
187 return FALSE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
188 } |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
189 |
0 | 190 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name); |
191 if (stat(path, &st) == 0) { | |
192 /* exists - make sure the required directories are also there */ | |
193 (void)create_mbox_index_dirs(path, TRUE); | |
194 | |
195 return mbox_open(storage, name, readonly); | |
196 } else if (errno == ENOENT) { | |
136
899ea73710fc
"Mailbox doesn't exist" error now gives the name of the mailbox that was
Timo Sirainen <tss@iki.fi>
parents:
24
diff
changeset
|
197 mail_storage_set_error(storage, "Mailbox doesn't exist: %s", |
899ea73710fc
"Mailbox doesn't exist" error now gives the name of the mailbox that was
Timo Sirainen <tss@iki.fi>
parents:
24
diff
changeset
|
198 name); |
0 | 199 return NULL; |
200 } else { | |
201 mail_storage_set_critical(storage, "Can't open mailbox %s: %m", | |
202 name); | |
203 return NULL; | |
204 } | |
205 } | |
206 | |
207 static int mbox_create_mailbox(MailStorage *storage, const char *name) | |
208 { | |
209 struct stat st; | |
210 char path[1024]; | |
211 int fd; | |
212 | |
213 mail_storage_clear_error(storage); | |
214 | |
215 if (strcasecmp(name, "INBOX") == 0) | |
216 name = "inbox"; | |
217 | |
218 if (!mbox_is_valid_name(storage, name)) { | |
219 mail_storage_set_error(storage, "Invalid mailbox name"); | |
220 return FALSE; | |
221 } | |
222 | |
223 /* make sure it doesn't exist already */ | |
224 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name); | |
225 if (stat(path, &st) == 0) { | |
226 mail_storage_set_error(storage, "Mailbox already exists"); | |
227 return FALSE; | |
228 } | |
229 | |
230 if (errno != EEXIST) { | |
231 mail_storage_set_critical(storage, "stat() failed for mbox " | |
232 "file %s: %m", path); | |
233 return FALSE; | |
234 } | |
235 | |
236 /* create the mailbox file */ | |
237 fd = open(path, O_RDWR | O_CREAT | O_EXCL); | |
238 if (fd != -1) { | |
239 (void)close(fd); | |
240 return TRUE; | |
241 } else if (errno == EEXIST) { | |
242 /* mailbox was just created between stat() and open() call.. */ | |
243 mail_storage_set_error(storage, "Mailbox already exists"); | |
244 return FALSE; | |
245 } else { | |
246 mail_storage_set_critical(storage, "Can't create mailbox " | |
247 "%s: %m", name); | |
248 return FALSE; | |
249 } | |
250 } | |
251 | |
252 static int mbox_delete_mailbox(MailStorage *storage, const char *name) | |
253 { | |
254 const char *index_dir; | |
255 char path[1024]; | |
256 | |
257 mail_storage_clear_error(storage); | |
258 | |
259 if (strcasecmp(name, "INBOX") == 0) { | |
260 mail_storage_set_error(storage, "INBOX can't be deleted."); | |
261 return FALSE; | |
262 } | |
263 | |
24
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
264 if (!mbox_is_valid_name(storage, name)) { |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
265 mail_storage_set_error(storage, "Invalid mailbox name"); |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
266 return FALSE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
267 } |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
268 |
0 | 269 /* first unlink the mbox file */ |
270 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name); | |
271 if (unlink(path) == -1) { | |
272 if (errno == ENOENT) { | |
273 mail_storage_set_error(storage, | |
136
899ea73710fc
"Mailbox doesn't exist" error now gives the name of the mailbox that was
Timo Sirainen <tss@iki.fi>
parents:
24
diff
changeset
|
274 "Mailbox doesn't exist: %s", |
899ea73710fc
"Mailbox doesn't exist" error now gives the name of the mailbox that was
Timo Sirainen <tss@iki.fi>
parents:
24
diff
changeset
|
275 name); |
0 | 276 } else { |
13
bb294faf7379
"Critical errors" aren't displayed to users anymore, ie. anything that is
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
277 mail_storage_set_critical(storage, "Can't delete mbox " |
bb294faf7379
"Critical errors" aren't displayed to users anymore, ie. anything that is
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
278 "file %s: %m", path); |
0 | 279 } |
280 return FALSE; | |
281 } | |
282 | |
283 /* next delete the index directory */ | |
284 index_dir = mbox_get_index_dir(path); | |
285 if (!unlink_directory(index_dir)) { | |
286 mail_storage_set_critical(storage, "unlink_directory(%s) " | |
287 "failed: %m", index_dir); | |
288 return FALSE; | |
289 } | |
290 return TRUE; | |
291 } | |
292 | |
293 static int mbox_rename_mailbox(MailStorage *storage, const char *oldname, | |
294 const char *newname) | |
295 { | |
296 const char *old_indexdir, *new_indexdir; | |
297 char oldpath[1024], newpath[1024]; | |
298 | |
299 mail_storage_clear_error(storage); | |
300 | |
24
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
301 if (!mbox_is_valid_name(storage, oldname) || |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
302 !mbox_is_valid_name(storage, newname)) { |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
303 mail_storage_set_error(storage, "Invalid mailbox name"); |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
304 return FALSE; |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
305 } |
e8de6f485c65
Don't allow using "../" anywhere in mailbox names.
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
306 |
0 | 307 if (strcasecmp(oldname, "INBOX") == 0) |
308 oldname = "inbox"; | |
309 | |
310 /* NOTE: renaming INBOX works just fine with us, it's simply created | |
311 the next time it's needed. */ | |
312 i_snprintf(oldpath, sizeof(oldpath), "%s/%s", storage->dir, oldname); | |
313 i_snprintf(newpath, sizeof(newpath), "%s/%s", storage->dir, newname); | |
314 if (link(oldpath, newpath) == 0) { | |
315 (void)unlink(oldpath); | |
316 /* ... */ | |
317 } else if (errno == EEXIST) { | |
318 mail_storage_set_error(storage, | |
319 "Target mailbox already exists"); | |
320 return FALSE; | |
321 } else { | |
322 mail_storage_set_critical(storage, "link(%s, %s) failed: %m", | |
323 oldpath, newpath); | |
324 return FALSE; | |
325 } | |
326 | |
327 /* we need to rename the index directory as well */ | |
328 old_indexdir = mbox_get_index_dir(oldpath); | |
329 new_indexdir = mbox_get_index_dir(newpath); | |
330 (void)rename(old_indexdir, new_indexdir); | |
331 | |
332 return TRUE; | |
333 } | |
334 | |
335 static int mbox_get_mailbox_name_status(MailStorage *storage, const char *name, | |
336 MailboxNameStatus *status) | |
337 { | |
338 struct stat st; | |
339 char path[1024]; | |
340 | |
341 mail_storage_clear_error(storage); | |
342 | |
343 if (strcasecmp(name, "INBOX") == 0) | |
344 name = "inbox"; | |
345 | |
346 if (!mbox_is_valid_name(storage, name)) { | |
347 *status = MAILBOX_NAME_INVALID; | |
348 return TRUE; | |
349 } | |
350 | |
351 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name); | |
352 if (stat(path, &st) == 0) { | |
353 *status = MAILBOX_NAME_EXISTS; | |
354 return TRUE; | |
355 } else if (errno == ENOENT) { | |
356 *status = MAILBOX_NAME_VALID; | |
357 return TRUE; | |
358 } else { | |
359 mail_storage_set_critical(storage, "mailbox name status: " | |
360 "stat(%s) failed: %m", path); | |
361 return FALSE; | |
362 } | |
363 } | |
364 | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
365 static void mbox_storage_close(Mailbox *box) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
366 { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
367 IndexMailbox *ibox = (IndexMailbox *) box; |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
368 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
369 if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_EXCLUSIVE)) |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
370 mail_storage_set_index_error(ibox); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
371 else { |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
372 /* update flags by rewrite mbox file */ |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
373 mbox_index_rewrite(ibox->index, |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
374 flags_file_list_get(ibox->flagsfile)); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
375 flags_file_list_unref(ibox->flagsfile); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
376 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
377 (void)ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
378 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
379 |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
380 index_storage_close(box); |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
381 } |
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
382 |
0 | 383 MailStorage mbox_storage = { |
384 "mbox", /* name */ | |
385 | |
386 '/', /* hierarchy_sep - can't be changed */ | |
387 | |
388 mbox_create, | |
389 mbox_free, | |
390 mbox_autodetect, | |
391 mbox_open_mailbox, | |
392 mbox_create_mailbox, | |
393 mbox_delete_mailbox, | |
394 mbox_rename_mailbox, | |
395 mbox_find_mailboxes, | |
396 subsfile_set_subscribed, | |
397 mbox_find_subscribed, | |
398 mbox_get_mailbox_name_status, | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
399 mail_storage_get_last_error, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
400 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
401 NULL, |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
13
diff
changeset
|
402 NULL, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
403 NULL |
0 | 404 }; |
405 | |
406 static Mailbox mbox_mailbox = { | |
407 NULL, /* name */ | |
408 NULL, /* storage */ | |
409 | |
160
ff05b320482c
Bigger changes.. full_virtual_size was removed from index record and
Timo Sirainen <tss@iki.fi>
parents:
136
diff
changeset
|
410 mbox_storage_close, |
0 | 411 index_storage_get_status, |
412 index_storage_sync, | |
413 index_storage_expunge, | |
414 index_storage_update_flags, | |
415 index_storage_copy, | |
416 index_storage_fetch, | |
417 index_storage_search, | |
418 mbox_storage_save, | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
419 mail_storage_is_inconsistency_error, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
420 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
421 FALSE, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
422 FALSE |
0 | 423 }; |