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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (C) 2002 Timo Sirainen */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "unlink-directory.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "subscription-file/subscription-file.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6 #include "mbox-index.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include "mbox-storage.h"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #include <stdio.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 #include <stdlib.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include <unistd.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #include <fcntl.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #include <sys/stat.h>
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 #define CREATE_MODE 0770 /* umask() should limit it more */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17 extern MailStorage mbox_storage;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 static Mailbox mbox_mailbox;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 static int mbox_autodetect(const char *data)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 const char *path;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 struct stat st;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 path = t_strconcat(data, "/.imap", NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode) &&
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27 access(path, R_OK|W_OK|X_OK) == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 path = t_strconcat(data, "/inbox", NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) &&
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 access(path, R_OK|W_OK) == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 path = t_strconcat(data, "/mbox", NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode) &&
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37 access(path, R_OK|W_OK) == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 MailStorage *storage;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 const char *home, *path;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48 if (data == NULL || *data == '\0') {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 /* we'll need to figure out the mail location ourself.
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 it's root dir if we've already chroot()ed, otherwise
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51 either $HOME/mail or $HOME/Mail */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 if (mbox_autodetect(""))
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 data = "/";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 home = getenv("HOME");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56 if (home != NULL) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 path = t_strconcat(home, "/mail", NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 if (access(path, R_OK|W_OK|X_OK) == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 data = path;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 path = t_strconcat(home, "/Mail", NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 if (access(path, R_OK|W_OK|X_OK) == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 data = path;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 if (data == NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 return NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 storage = i_new(MailStorage, 1);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 memcpy(storage, &mbox_storage, sizeof(MailStorage));
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 return storage;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 static void mbox_free(MailStorage *storage)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 i_free(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 static int mbox_is_valid_name(MailStorage *storage, const char *name)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 static const char *mbox_get_index_dir(const char *mbox_path)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109 const char *p, *rootpath;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 p = strrchr(mbox_path, '/');
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 if (p == NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 return t_strconcat(".imap/", mbox_path);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 return t_strconcat(rootpath, "/.imap/", p+1, NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120 static int create_mbox_index_dirs(const char *mbox_path, int verify)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122 const char *index_dir, *imap_dir;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 if (mkdir(imap_dir, CREATE_MODE) == -1 && errno != EEXIST)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 if (mkdir(index_dir, CREATE_MODE) == -1 && (errno != EEXIST || !verify))
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 static void verify_inbox(MailStorage *storage)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 char path[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 int fd;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 i_snprintf(path, sizeof(path), "%s/inbox", storage->dir);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 /* make sure inbox file itself exists */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143 fd = open(path, O_RDWR | O_CREAT | O_EXCL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 if (fd != -1)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 (void)close(fd);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 /* make sure the index directories exist */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 (void)create_mbox_index_dirs(path, TRUE);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
150
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 static Mailbox *mbox_open(MailStorage *storage, const char *name, int readonly)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 IndexMailbox *ibox;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154 const char *path, *index_dir;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156 /* name = "foo/bar"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 mbox_path = "/mail/foo/bar"
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 index_dir = "/mail/foo/.imap/bar" */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 path = t_strconcat(storage->dir, "/", name, NULL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160 index_dir = mbox_get_index_dir(path);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 ibox = index_storage_init(storage, &mbox_mailbox,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 mbox_index_alloc(index_dir, path),
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 name, readonly);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 if (ibox != NULL)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 ibox->expunge_locked = mbox_expunge_locked;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 return (Mailbox *) ibox;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 static Mailbox *mbox_open_mailbox(MailStorage *storage, const char *name,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 int readonly)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 struct stat st;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 char path[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 mail_storage_clear_error(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 /* INBOX is always case-insensitive */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 if (strcasecmp(name, "INBOX") == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 /* make sure inbox exists */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181 verify_inbox(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 return mbox_open(storage, "inbox", readonly);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 if (stat(path, &st) == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 /* exists - make sure the required directories are also there */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 (void)create_mbox_index_dirs(path, TRUE);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 return mbox_open(storage, name, readonly);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 return NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201 mail_storage_set_critical(storage, "Can't open mailbox %s: %m",
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
202 name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 return NULL;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 static int mbox_create_mailbox(MailStorage *storage, const char *name)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209 struct stat st;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 char path[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211 int fd;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 mail_storage_clear_error(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 if (strcasecmp(name, "INBOX") == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 name = "inbox";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218 if (!mbox_is_valid_name(storage, name)) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 mail_storage_set_error(storage, "Invalid mailbox name");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 /* make sure it doesn't exist already */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 if (stat(path, &st) == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 mail_storage_set_error(storage, "Mailbox already exists");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
229
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
230 if (errno != EEXIST) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
231 mail_storage_set_critical(storage, "stat() failed for mbox "
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232 "file %s: %m", path);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 /* create the mailbox file */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 fd = open(path, O_RDWR | O_CREAT | O_EXCL);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238 if (fd != -1) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239 (void)close(fd);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 } else if (errno == EEXIST) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 /* mailbox was just created between stat() and open() call.. */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 mail_storage_set_error(storage, "Mailbox already exists");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246 mail_storage_set_critical(storage, "Can't create mailbox "
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247 "%s: %m", name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 static int mbox_delete_mailbox(MailStorage *storage, const char *name)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254 const char *index_dir;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
255 char path[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
256
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 mail_storage_clear_error(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
258
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
259 if (strcasecmp(name, "INBOX") == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
260 mail_storage_set_error(storage, "INBOX can't be deleted.");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
261 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
262 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
269 /* first unlink the mbox file */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
270 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
271 if (unlink(path) == -1) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
272 if (errno == ENOENT) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
279 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
280 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
281 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
282
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
283 /* next delete the index directory */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
284 index_dir = mbox_get_index_dir(path);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
285 if (!unlink_directory(index_dir)) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
286 mail_storage_set_critical(storage, "unlink_directory(%s) "
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
287 "failed: %m", index_dir);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
288 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
289 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
290 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
291 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
292
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
293 static int mbox_rename_mailbox(MailStorage *storage, const char *oldname,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
294 const char *newname)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
295 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
296 const char *old_indexdir, *new_indexdir;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
297 char oldpath[1024], newpath[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
298
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
299 mail_storage_clear_error(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
307 if (strcasecmp(oldname, "INBOX") == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
308 oldname = "inbox";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
309
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
310 /* NOTE: renaming INBOX works just fine with us, it's simply created
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
311 the next time it's needed. */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
312 i_snprintf(oldpath, sizeof(oldpath), "%s/%s", storage->dir, oldname);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
313 i_snprintf(newpath, sizeof(newpath), "%s/%s", storage->dir, newname);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
314 if (link(oldpath, newpath) == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
315 (void)unlink(oldpath);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
316 /* ... */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
317 } else if (errno == EEXIST) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
318 mail_storage_set_error(storage,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
319 "Target mailbox already exists");
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
320 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
321 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
322 mail_storage_set_critical(storage, "link(%s, %s) failed: %m",
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
323 oldpath, newpath);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
324 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
325 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
326
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
327 /* we need to rename the index directory as well */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
328 old_indexdir = mbox_get_index_dir(oldpath);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
329 new_indexdir = mbox_get_index_dir(newpath);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
330 (void)rename(old_indexdir, new_indexdir);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
331
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
332 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
333 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
334
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
335 static int mbox_get_mailbox_name_status(MailStorage *storage, const char *name,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
336 MailboxNameStatus *status)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
337 {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
338 struct stat st;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
339 char path[1024];
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
340
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
341 mail_storage_clear_error(storage);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
342
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
343 if (strcasecmp(name, "INBOX") == 0)
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
344 name = "inbox";
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
345
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
346 if (!mbox_is_valid_name(storage, name)) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
347 *status = MAILBOX_NAME_INVALID;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
348 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
349 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
350
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
351 i_snprintf(path, sizeof(path), "%s/%s", storage->dir, name);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
352 if (stat(path, &st) == 0) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
353 *status = MAILBOX_NAME_EXISTS;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
354 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
355 } else if (errno == ENOENT) {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
356 *status = MAILBOX_NAME_VALID;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
357 return TRUE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
358 } else {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
359 mail_storage_set_critical(storage, "mailbox name status: "
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
360 "stat(%s) failed: %m", path);
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
361 return FALSE;
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
362 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
363 }
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
383 MailStorage mbox_storage = {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
384 "mbox", /* name */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
385
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
386 '/', /* hierarchy_sep - can't be changed */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
387
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
388 mbox_create,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
389 mbox_free,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
390 mbox_autodetect,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
391 mbox_open_mailbox,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
392 mbox_create_mailbox,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
393 mbox_delete_mailbox,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
394 mbox_rename_mailbox,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
395 mbox_find_mailboxes,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
396 subsfile_set_subscribed,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
397 mbox_find_subscribed,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
404 };
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
405
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
406 static Mailbox mbox_mailbox = {
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
407 NULL, /* name */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
408 NULL, /* storage */
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
411 index_storage_get_status,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
412 index_storage_sync,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
413 index_storage_expunge,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
414 index_storage_update_flags,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
415 index_storage_copy,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
416 index_storage_fetch,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
417 index_storage_search,
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
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
3b1985cbc908 Initial revision
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
423 };