-rw-r--r-- | kmicromail/libetpan/mh/mailmh.c | 473 |
1 files changed, 239 insertions, 234 deletions
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c index 5e2b4cc..1087ce1 100644 --- a/kmicromail/libetpan/mh/mailmh.c +++ b/kmicromail/libetpan/mh/mailmh.c | |||
@@ -1,980 +1,985 @@ | |||
1 | /* | 1 | /* |
2 | * libEtPan! -- a mail stuff library | 2 | * libEtPan! -- a mail stuff library |
3 | * | 3 | * |
4 | * Copyright (C) 2001, 2002 - DINH Viet Hoa | 4 | * Copyright (C) 2001, 2002 - DINH Viet Hoa |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. Neither the name of the libEtPan! project nor the names of its | 15 | * 3. Neither the name of the libEtPan! project nor the names of its |
16 | * contributors may be used to endorse or promote products derived | 16 | * contributors may be used to endorse or promote products derived |
17 | * from this software without specific prior written permission. | 17 | * from this software without specific prior written permission. |
18 | * | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * $Id$ | 33 | * $Id$ |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #include "mailmh.h" | 36 | #include "mailmh.h" |
37 | 37 | ||
38 | /* | 38 | /* |
39 | perfs : | 39 | perfs : |
40 | 40 | ||
41 | /net/home/dinh/Mail/inbox/sylpheed 686 | 41 | /net/home/dinh/Mail/inbox/sylpheed 686 |
42 | 42 | ||
43 | 2724 /net/home/dinh/Mail/inbox/sylpheed | 43 | 2724 /net/home/dinh/Mail/inbox/sylpheed |
44 | 44 | ||
45 | bart:~/LibEtPan/libetpan/tests> time ./mhtest >/dev/null | 45 | bart:~/LibEtPan/libetpan/tests> time ./mhtest >/dev/null |
46 | 46 | ||
47 | real 0m0.385s | 47 | real 0m0.385s |
48 | user 0m0.270s | 48 | user 0m0.270s |
49 | sys 0m0.110s | 49 | sys 0m0.110s |
50 | 50 | ||
51 | */ | 51 | */ |
52 | 52 | ||
53 | #include <dirent.h> | 53 | #include <dirent.h> |
54 | #include <sys/stat.h> | 54 | #include <sys/stat.h> |
55 | #include <errno.h> | 55 | #include <errno.h> |
56 | #include <unistd.h> | 56 | #include <unistd.h> |
57 | #include <sys/mman.h> | 57 | #include <sys/mman.h> |
58 | #include <fcntl.h> | 58 | #include <fcntl.h> |
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include <stdlib.h> | 60 | #include <stdlib.h> |
61 | #include <string.h> | 61 | #include <string.h> |
62 | 62 | ||
63 | #include "libetpan-config.h" | 63 | #include "libetpan-config.h" |
64 | 64 | ||
65 | struct mailmh * mailmh_new(const char * foldername) | 65 | struct mailmh * mailmh_new(const char * foldername) |
66 | { | 66 | { |
67 | struct mailmh * f; | 67 | struct mailmh * f; |
68 | 68 | ||
69 | f = malloc(sizeof(*f)); | 69 | f = malloc(sizeof(*f)); |
70 | if (f == NULL) | 70 | if (f == NULL) |
71 | return NULL; | 71 | return NULL; |
72 | 72 | ||
73 | f->mh_main = mailmh_folder_new(NULL, foldername); | 73 | f->mh_main = mailmh_folder_new(NULL, foldername); |
74 | if (f->mh_main == NULL) { | 74 | if (f->mh_main == NULL) { |
75 | free(f); | 75 | free(f); |
76 | return NULL; | 76 | return NULL; |
77 | } | 77 | } |
78 | 78 | ||
79 | return f; | 79 | return f; |
80 | } | 80 | } |
81 | 81 | ||
82 | void mailmh_free(struct mailmh * f) | 82 | void mailmh_free(struct mailmh * f) |
83 | { | 83 | { |
84 | mailmh_folder_free(f->mh_main); | 84 | mailmh_folder_free(f->mh_main); |
85 | free(f); | 85 | free(f); |
86 | } | 86 | } |
87 | 87 | ||
88 | 88 | ||
89 | 89 | ||
90 | struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size, | 90 | struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size, |
91 | time_t mtime) | 91 | time_t mtime) |
92 | { | 92 | { |
93 | struct mailmh_msg_info * msg_info; | 93 | struct mailmh_msg_info * msg_info; |
94 | 94 | ||
95 | msg_info = malloc(sizeof(* msg_info)); | 95 | msg_info = malloc(sizeof(* msg_info)); |
96 | if (msg_info == NULL) | 96 | if (msg_info == NULL) |
97 | return NULL; | 97 | return NULL; |
98 | msg_info->msg_index = index; | 98 | msg_info->msg_index = index; |
99 | msg_info->msg_size = size; | 99 | msg_info->msg_size = size; |
100 | msg_info->msg_mtime = mtime; | 100 | msg_info->msg_mtime = mtime; |
101 | 101 | ||
102 | msg_info->msg_array_index = 0; | 102 | msg_info->msg_array_index = 0; |
103 | 103 | ||
104 | return msg_info; | 104 | return msg_info; |
105 | } | 105 | } |
106 | 106 | ||
107 | void mailmh_msg_info_free(struct mailmh_msg_info * msg_info) | 107 | void mailmh_msg_info_free(struct mailmh_msg_info * msg_info) |
108 | { | 108 | { |
109 | free(msg_info); | 109 | free(msg_info); |
110 | } | 110 | } |
111 | 111 | ||
112 | struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, | 112 | struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, |
113 | const char * name) | 113 | const char * name) |
114 | { | 114 | { |
115 | char * filename; | 115 | char * filename; |
116 | char * parent_filename; | 116 | char * parent_filename; |
117 | 117 | ||
118 | struct mailmh_folder * folder; | 118 | struct mailmh_folder * folder; |
119 | 119 | ||
120 | folder = malloc(sizeof(* folder)); | 120 | folder = malloc(sizeof(* folder)); |
121 | if (folder == NULL) | 121 | if (folder == NULL) |
122 | goto err; | 122 | goto err; |
123 | 123 | ||
124 | if (parent == NULL) { | 124 | if (parent == NULL) { |
125 | filename = strdup(name); | 125 | filename = strdup(name); |
126 | if (filename == NULL) | 126 | if (filename == NULL) |
127 | goto free_folder; | 127 | goto free_folder; |
128 | } | 128 | } |
129 | else { | 129 | else { |
130 | parent_filename = parent->fl_filename; | 130 | parent_filename = parent->fl_filename; |
131 | filename = malloc(strlen(parent_filename) + strlen(name) + 2); | 131 | filename = malloc(strlen(parent_filename) + strlen(name) + 2); |
132 | if (filename == NULL) | 132 | if (filename == NULL) |
133 | goto free_folder; | 133 | goto free_folder; |
134 | 134 | ||
135 | strcpy(filename, parent_filename); | 135 | strcpy(filename, parent_filename); |
136 | strcat(filename, MAIL_DIR_SEPARATOR_S); | 136 | strcat(filename, MAIL_DIR_SEPARATOR_S); |
137 | strcat(filename, name); | 137 | strcat(filename, name); |
138 | } | 138 | } |
139 | 139 | ||
140 | folder->fl_filename = filename; | 140 | folder->fl_filename = filename; |
141 | 141 | ||
142 | folder->fl_name = strdup(name); | 142 | folder->fl_name = strdup(name); |
143 | if (folder->fl_name == NULL) | 143 | if (folder->fl_name == NULL) |
144 | goto free_filename; | 144 | goto free_filename; |
145 | 145 | ||
146 | folder->fl_msgs_tab = carray_new(128); | 146 | folder->fl_msgs_tab = carray_new(128); |
147 | if (folder->fl_msgs_tab == NULL) | 147 | if (folder->fl_msgs_tab == NULL) |
148 | goto free_name; | 148 | goto free_name; |
149 | 149 | ||
150 | #if 0 | 150 | #if 0 |
151 | folder->fl_msgs_hash = cinthash_new(128); | 151 | folder->fl_msgs_hash = cinthash_new(128); |
152 | if (folder->fl_msgs_hash == NULL) | 152 | if (folder->fl_msgs_hash == NULL) |
153 | goto free_msgs_tab; | 153 | goto free_msgs_tab; |
154 | #endif | 154 | #endif |
155 | folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); | 155 | folder->fl_msgs_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); |
156 | if (folder->fl_msgs_hash == NULL) | 156 | if (folder->fl_msgs_hash == NULL) |
157 | goto free_msgs_tab; | 157 | goto free_msgs_tab; |
158 | 158 | ||
159 | folder->fl_subfolders_tab = carray_new(128); | 159 | folder->fl_subfolders_tab = carray_new(128); |
160 | if (folder->fl_subfolders_tab == NULL) | 160 | if (folder->fl_subfolders_tab == NULL) |
161 | goto free_msgs_hash; | 161 | goto free_msgs_hash; |
162 | 162 | ||
163 | folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE); | 163 | folder->fl_subfolders_hash = chash_new(128, CHASH_COPYNONE); |
164 | if (folder->fl_subfolders_hash == NULL) | 164 | if (folder->fl_subfolders_hash == NULL) |
165 | goto free_subfolders_tab; | 165 | goto free_subfolders_tab; |
166 | 166 | ||
167 | folder->fl_mtime = 0; | 167 | folder->fl_mtime = 0; |
168 | folder->fl_parent = parent; | 168 | folder->fl_parent = parent; |
169 | folder->fl_max_index = 0; | 169 | folder->fl_max_index = 0; |
170 | 170 | ||
171 | return folder; | 171 | return folder; |
172 | 172 | ||
173 | free_subfolders_tab: | 173 | free_subfolders_tab: |
174 | carray_free(folder->fl_subfolders_tab); | 174 | carray_free(folder->fl_subfolders_tab); |
175 | free_msgs_hash: | 175 | free_msgs_hash: |
176 | #if 0 | 176 | #if 0 |
177 | cinthash_free(folder->fl_msgs_hash); | 177 | cinthash_free(folder->fl_msgs_hash); |
178 | #endif | 178 | #endif |
179 | chash_free(folder->fl_msgs_hash); | 179 | chash_free(folder->fl_msgs_hash); |
180 | free_msgs_tab: | 180 | free_msgs_tab: |
181 | carray_free(folder->fl_msgs_tab); | 181 | carray_free(folder->fl_msgs_tab); |
182 | free_name: | 182 | free_name: |
183 | free(folder->fl_name); | 183 | free(folder->fl_name); |
184 | free_filename: | 184 | free_filename: |
185 | free(folder->fl_filename); | 185 | free(folder->fl_filename); |
186 | free_folder: | 186 | free_folder: |
187 | free(folder); | 187 | free(folder); |
188 | err: | 188 | err: |
189 | return NULL; | 189 | return NULL; |
190 | } | 190 | } |
191 | 191 | ||
192 | void mailmh_folder_free(struct mailmh_folder * folder) | 192 | void mailmh_folder_free(struct mailmh_folder * folder) |
193 | { | 193 | { |
194 | unsigned int i; | 194 | unsigned int i; |
195 | 195 | ||
196 | for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) { | 196 | for(i = 0 ; i < carray_count(folder->fl_subfolders_tab) ; i++) { |
197 | struct mailmh_folder * subfolder; | 197 | struct mailmh_folder * subfolder; |
198 | 198 | ||
199 | subfolder = carray_get(folder->fl_subfolders_tab, i); | 199 | subfolder = carray_get(folder->fl_subfolders_tab, i); |
200 | if (subfolder != NULL) | 200 | if (subfolder != NULL) |
201 | mailmh_folder_free(subfolder); | 201 | mailmh_folder_free(subfolder); |
202 | } | 202 | } |
203 | carray_free(folder->fl_subfolders_tab); | 203 | carray_free(folder->fl_subfolders_tab); |
204 | chash_free(folder->fl_subfolders_hash); | 204 | chash_free(folder->fl_subfolders_hash); |
205 | 205 | ||
206 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { | 206 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i++) { |
207 | struct mailmh_msg_info * msg_info; | 207 | struct mailmh_msg_info * msg_info; |
208 | 208 | ||
209 | msg_info = carray_get(folder->fl_msgs_tab, i); | 209 | msg_info = carray_get(folder->fl_msgs_tab, i); |
210 | if (msg_info != NULL) | 210 | if (msg_info != NULL) |
211 | mailmh_msg_info_free(msg_info); | 211 | mailmh_msg_info_free(msg_info); |
212 | } | 212 | } |
213 | carray_free(folder->fl_msgs_tab); | 213 | carray_free(folder->fl_msgs_tab); |
214 | chash_free(folder->fl_msgs_hash); | 214 | chash_free(folder->fl_msgs_hash); |
215 | #if 0 | 215 | #if 0 |
216 | cinthash_free(folder->fl_msgs_hash); | 216 | cinthash_free(folder->fl_msgs_hash); |
217 | #endif | 217 | #endif |
218 | 218 | ||
219 | free(folder->fl_filename); | 219 | free(folder->fl_filename); |
220 | free(folder->fl_name); | 220 | free(folder->fl_name); |
221 | 221 | ||
222 | free(folder); | 222 | free(folder); |
223 | } | 223 | } |
224 | 224 | ||
225 | struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, | 225 | struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, |
226 | const char * filename) | 226 | const char * filename) |
227 | { | 227 | { |
228 | int r; | 228 | int r; |
229 | char pathname[PATH_MAX]; | 229 | char pathname[PATH_MAX]; |
230 | char * p; | 230 | char * p; |
231 | chashdatum key; | 231 | chashdatum key; |
232 | chashdatum data; | 232 | chashdatum data; |
233 | struct mailmh_folder * folder; | 233 | struct mailmh_folder * folder; |
234 | char * start; | 234 | char * start; |
235 | 235 | ||
236 | if (strcmp(root->fl_filename, filename) == 0) | 236 | if (strcmp(root->fl_filename, filename) == 0) |
237 | return root; | 237 | return root; |
238 | 238 | ||
239 | #if 0 | 239 | #if 0 |
240 | r = mailmh_folder_update(root); | 240 | r = mailmh_folder_update(root); |
241 | if (r != MAILMH_NO_ERROR) | 241 | if (r != MAILMH_NO_ERROR) |
242 | return NULL; | 242 | return NULL; |
243 | #endif | 243 | #endif |
244 | 244 | ||
245 | #if 0 | 245 | #if 0 |
246 | for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) { | 246 | for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) { |
247 | struct mailmh_folder * subfolder; | 247 | struct mailmh_folder * subfolder; |
248 | 248 | ||
249 | subfolder = carray_get(root->fl_subfolders_tab, i); | 249 | subfolder = carray_get(root->fl_subfolders_tab, i); |
250 | if (subfolder != NULL) | 250 | if (subfolder != NULL) |
251 | if (strncmp(subfolder->fl_filename, filename, | 251 | if (strncmp(subfolder->fl_filename, filename, |
252 | strlen(subfolder->fl_filename)) == 0) | 252 | strlen(subfolder->fl_filename)) == 0) |
253 | return mailmh_folder_find(subfolder, filename); | 253 | return mailmh_folder_find(subfolder, filename); |
254 | } | 254 | } |
255 | #endif | 255 | #endif |
256 | strncpy(pathname, filename, PATH_MAX); | 256 | strncpy(pathname, filename, PATH_MAX); |
257 | pathname[PATH_MAX - 1] = 0; | 257 | pathname[PATH_MAX - 1] = 0; |
258 | start = pathname + strlen(root->fl_filename) + 1; | 258 | start = pathname + strlen(root->fl_filename) + 1; |
259 | 259 | ||
260 | p = strchr(start, MAIL_DIR_SEPARATOR); | 260 | p = strchr(start, MAIL_DIR_SEPARATOR); |
261 | if (p != NULL) { | 261 | if (p != NULL) { |
262 | * p = 0; | 262 | * p = 0; |
263 | 263 | ||
264 | root = mailmh_folder_find(root, pathname); | 264 | root = mailmh_folder_find(root, pathname); |
265 | if (root != NULL) { | 265 | if (root != NULL) { |
266 | folder = mailmh_folder_find(root, filename); | 266 | folder = mailmh_folder_find(root, filename); |
267 | if (folder == NULL) | 267 | if (folder == NULL) |
268 | return NULL; | 268 | return NULL; |
269 | return folder; | 269 | return folder; |
270 | } | 270 | } |
271 | 271 | ||
272 | return NULL; | 272 | return NULL; |
273 | } | 273 | } |
274 | else { | 274 | else { |
275 | key.data = pathname; | 275 | key.data = pathname; |
276 | key.len = strlen(pathname); | 276 | key.len = strlen(pathname); |
277 | r = chash_get(root->fl_subfolders_hash, &key, &data); | 277 | r = chash_get(root->fl_subfolders_hash, &key, &data); |
278 | if (r < 0) | 278 | if (r < 0) |
279 | return NULL; | 279 | return NULL; |
280 | 280 | ||
281 | return data.data; | 281 | return data.data; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | 284 | ||
285 | int mailmh_folder_update(struct mailmh_folder * folder) | 285 | int mailmh_folder_update(struct mailmh_folder * folder) |
286 | { | 286 | { |
287 | DIR * d; | 287 | DIR * d; |
288 | struct dirent * ent; | 288 | struct dirent * ent; |
289 | struct stat buf; | 289 | struct stat buf; |
290 | char * mh_seq; | 290 | char * mh_seq; |
291 | char filename[PATH_MAX]; | 291 | char filename[PATH_MAX]; |
292 | int res; | 292 | int res; |
293 | int r; | 293 | int r; |
294 | uint32_t max_index; | 294 | uint32_t max_index; |
295 | #if 0 | 295 | #if 0 |
296 | int add_folder; | 296 | int add_folder; |
297 | #endif | 297 | #endif |
298 | unsigned int i; | 298 | unsigned int i; |
299 | 299 | ||
300 | if (stat(folder->fl_filename, &buf) == -1) { | 300 | if (stat(folder->fl_filename, &buf) == -1) { |
301 | res = MAILMH_ERROR_FOLDER; | 301 | res = MAILMH_ERROR_FOLDER; |
302 | goto err; | 302 | goto err; |
303 | } | 303 | } |
304 | 304 | ||
305 | if (folder->fl_mtime == buf.st_mtime) { | 305 | if (folder->fl_mtime == buf.st_mtime) { |
306 | res = MAILMH_NO_ERROR; | 306 | res = MAILMH_NO_ERROR; |
307 | goto err; | 307 | goto err; |
308 | } | 308 | } |
309 | 309 | ||
310 | folder->fl_mtime = buf.st_mtime; | 310 | folder->fl_mtime = buf.st_mtime; |
311 | 311 | ||
312 | d = opendir(folder->fl_filename); | 312 | d = opendir(folder->fl_filename); |
313 | if (d == NULL) { | 313 | if (d == NULL) { |
314 | res = MAILMH_ERROR_FOLDER; | 314 | res = MAILMH_ERROR_FOLDER; |
315 | goto err; | 315 | goto err; |
316 | } | 316 | } |
317 | 317 | ||
318 | max_index = 0; | 318 | max_index = 0; |
319 | 319 | ||
320 | #if 0 | 320 | #if 0 |
321 | if (folder->fl_subfolders_tab->len == 0) | 321 | if (folder->fl_subfolders_tab->len == 0) |
322 | add_folder = 1; | 322 | add_folder = 1; |
323 | else | 323 | else |
324 | add_folder = 0; | 324 | add_folder = 0; |
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | /* clear the message list */ | 327 | /* clear the message list */ |
328 | 328 | ||
329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { | 329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { |
330 | struct mailmh_msg_info * msg_info; | 330 | struct mailmh_msg_info * msg_info; |
331 | chashdatum key; | 331 | chashdatum key; |
332 | 332 | ||
333 | msg_info = carray_get(folder->fl_msgs_tab, i); | 333 | msg_info = carray_get(folder->fl_msgs_tab, i); |
334 | if (msg_info == NULL) | 334 | if (msg_info == NULL) |
335 | continue; | 335 | continue; |
336 | 336 | ||
337 | #if 0 | 337 | #if 0 |
338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); | 338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); |
339 | #endif | 339 | #endif |
340 | key.data = &msg_info->msg_index; | 340 | key.data = &msg_info->msg_index; |
341 | key.len = sizeof(msg_info->msg_index); | 341 | key.len = sizeof(msg_info->msg_index); |
342 | chash_delete(folder->fl_msgs_hash, &key, NULL); | 342 | chash_delete(folder->fl_msgs_hash, &key, NULL); |
343 | 343 | ||
344 | mailmh_msg_info_free(msg_info); | 344 | mailmh_msg_info_free(msg_info); |
345 | } | 345 | } |
346 | 346 | ||
347 | carray_set_size(folder->fl_msgs_tab, 0); | 347 | carray_set_size(folder->fl_msgs_tab, 0); |
348 | 348 | ||
349 | do { | 349 | do { |
350 | uint32_t index; | 350 | uint32_t index; |
351 | 351 | ||
352 | ent = readdir(d); | 352 | ent = readdir(d); |
353 | 353 | ||
354 | if (ent != NULL) { | 354 | if (ent != NULL) { |
355 | 355 | ||
356 | snprintf(filename, PATH_MAX, | 356 | snprintf(filename, PATH_MAX, |
357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); | 357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); |
358 | 358 | ||
359 | if (stat(filename, &buf) == -1) | 359 | if (stat(filename, &buf) == -1) |
360 | continue; | 360 | continue; |
361 | 361 | ||
362 | if (S_ISREG(buf.st_mode)) { | 362 | if (S_ISREG(buf.st_mode)) { |
363 | index = strtoul(ent->d_name, NULL, 10); | 363 | index = strtoul(ent->d_name, NULL, 10); |
364 | if (index != 0) { | 364 | if (index != 0) { |
365 | struct mailmh_msg_info * msg_info; | 365 | struct mailmh_msg_info * msg_info; |
366 | unsigned int array_index; | 366 | unsigned int array_index; |
367 | chashdatum key; | 367 | chashdatum key; |
368 | chashdatum data; | 368 | chashdatum data; |
369 | 369 | ||
370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); | 370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); |
371 | if (msg_info == NULL) { | 371 | if (msg_info == NULL) { |
372 | res = MAILMH_ERROR_MEMORY; | 372 | res = MAILMH_ERROR_MEMORY; |
373 | goto closedir; | 373 | goto closedir; |
374 | } | 374 | } |
375 | 375 | ||
376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); | 376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); |
377 | if (r < 0) { | 377 | if (r < 0) { |
378 | mailmh_msg_info_free(msg_info); | 378 | mailmh_msg_info_free(msg_info); |
379 | res = MAILMH_ERROR_MEMORY; | 379 | res = MAILMH_ERROR_MEMORY; |
380 | goto closedir; | 380 | goto closedir; |
381 | } | 381 | } |
382 | msg_info->msg_array_index = array_index; | 382 | msg_info->msg_array_index = array_index; |
383 | 383 | ||
384 | if (index > max_index) | 384 | if (index > max_index) |
385 | max_index = index; | 385 | max_index = index; |
386 | 386 | ||
387 | #if 0 | 387 | #if 0 |
388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); | 388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); |
389 | #endif | 389 | #endif |
390 | key.data = &msg_info->msg_index; | 390 | key.data = &msg_info->msg_index; |
391 | key.len = sizeof(msg_info->msg_index); | 391 | key.len = sizeof(msg_info->msg_index); |
392 | data.data = msg_info; | 392 | data.data = msg_info; |
393 | data.len = 0; | 393 | data.len = 0; |
394 | 394 | ||
395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); | 395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); |
396 | if (r < 0) { | 396 | if (r < 0) { |
397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); | 397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); |
398 | mailmh_msg_info_free(msg_info); | 398 | mailmh_msg_info_free(msg_info); |
399 | res = MAILMH_ERROR_MEMORY; | 399 | res = MAILMH_ERROR_MEMORY; |
400 | goto closedir; | 400 | goto closedir; |
401 | } | 401 | } |
402 | } | 402 | //LR memory leak? added next line |
403 | } | 403 | //mailmh_msg_info_free(msg_info); |
404 | else if (S_ISDIR(buf.st_mode)) { | 404 | //it seems so that it should be freed later, |
405 | struct mailmh_folder * subfolder; | 405 | // but it is not in every case |
406 | unsigned int array_index; | 406 | //PENDING fixme in ompi somewhere |
407 | chashdatum key; | 407 | } |
408 | chashdatum data; | 408 | } |
409 | 409 | else if (S_ISDIR(buf.st_mode)) { | |
410 | if (ent->d_name[0] == '.') { | 410 | struct mailmh_folder * subfolder; |
411 | if (ent->d_name[1] == 0) | 411 | unsigned int array_index; |
412 | continue; | 412 | chashdatum key; |
413 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) | 413 | chashdatum data; |
414 | continue; | 414 | |
415 | } | 415 | if (ent->d_name[0] == '.') { |
416 | 416 | if (ent->d_name[1] == 0) | |
417 | key.data = ent->d_name; | 417 | continue; |
418 | key.len = strlen(ent->d_name); | 418 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) |
419 | r = chash_get(folder->fl_subfolders_hash, &key, &data); | 419 | continue; |
420 | if (r < 0) { | 420 | } |
421 | subfolder = mailmh_folder_new(folder, ent->d_name); | 421 | |
422 | if (subfolder == NULL) { | 422 | key.data = ent->d_name; |
423 | res = MAILMH_ERROR_MEMORY; | 423 | key.len = strlen(ent->d_name); |
424 | goto closedir; | 424 | r = chash_get(folder->fl_subfolders_hash, &key, &data); |
425 | } | 425 | if (r < 0) { |
426 | subfolder = mailmh_folder_new(folder, ent->d_name); | ||
427 | if (subfolder == NULL) { | ||
428 | res = MAILMH_ERROR_MEMORY; | ||
429 | goto closedir; | ||
430 | } | ||
426 | 431 | ||
427 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); | 432 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); |
428 | if (r < 0) { | 433 | if (r < 0) { |
429 | mailmh_folder_free(subfolder); | 434 | mailmh_folder_free(subfolder); |
430 | res = MAILMH_ERROR_MEMORY; | 435 | res = MAILMH_ERROR_MEMORY; |
431 | goto closedir; | 436 | goto closedir; |
432 | } | 437 | } |
433 | subfolder->fl_array_index = array_index; | 438 | subfolder->fl_array_index = array_index; |
434 | 439 | ||
435 | key.data = subfolder->fl_filename; | 440 | key.data = subfolder->fl_filename; |
436 | key.len = strlen(subfolder->fl_filename); | 441 | key.len = strlen(subfolder->fl_filename); |
437 | data.data = subfolder; | 442 | data.data = subfolder; |
438 | data.len = 0; | 443 | data.len = 0; |
439 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); | 444 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); |
440 | if (r < 0) { | 445 | if (r < 0) { |
441 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); | 446 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); |
442 | mailmh_folder_free(subfolder); | 447 | mailmh_folder_free(subfolder); |
443 | res = MAILMH_ERROR_MEMORY; | 448 | res = MAILMH_ERROR_MEMORY; |
444 | goto closedir; | 449 | goto closedir; |
445 | } | 450 | } |
446 | } | 451 | } |
447 | } | 452 | } |
453 | } | ||
448 | } | 454 | } |
449 | } | 455 | while (ent != NULL); |
450 | while (ent != NULL); | ||
451 | 456 | ||
452 | folder->fl_max_index = max_index; | 457 | folder->fl_max_index = max_index; |
453 | 458 | ||
454 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); | 459 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); |
455 | if (mh_seq == NULL) { | 460 | if (mh_seq == NULL) { |
456 | res = MAILMH_ERROR_MEMORY; | 461 | res = MAILMH_ERROR_MEMORY; |
457 | goto closedir; | 462 | goto closedir; |
458 | } | 463 | } |
459 | strcpy(mh_seq, folder->fl_filename); | 464 | strcpy(mh_seq, folder->fl_filename); |
460 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); | 465 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); |
461 | strcat(mh_seq, ".mh_sequences"); | 466 | strcat(mh_seq, ".mh_sequences"); |
462 | 467 | ||
463 | if (stat(mh_seq, &buf) == -1) { | 468 | if (stat(mh_seq, &buf) == -1) { |
464 | int fd; | 469 | int fd; |
465 | 470 | ||
466 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); | 471 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); |
467 | if (fd != -1) | 472 | if (fd != -1) |
468 | close(fd); | 473 | close(fd); |
469 | } | 474 | } |
470 | free(mh_seq); | 475 | free(mh_seq); |
471 | 476 | ||
472 | closedir(d); | 477 | closedir(d); |
473 | 478 | ||
474 | return MAILMH_NO_ERROR; | 479 | return MAILMH_NO_ERROR; |
475 | 480 | ||
476 | closedir: | 481 | closedir: |
477 | closedir(d); | 482 | closedir(d); |
478 | err: | 483 | err: |
479 | return res; | 484 | return res; |
480 | } | 485 | } |
481 | 486 | ||
482 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, | 487 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, |
483 | const char * name) | 488 | const char * name) |
484 | { | 489 | { |
485 | char * foldername; | 490 | char * foldername; |
486 | int r; | 491 | int r; |
487 | struct mailmh_folder * folder; | 492 | struct mailmh_folder * folder; |
488 | unsigned int array_index; | 493 | unsigned int array_index; |
489 | chashdatum key; | 494 | chashdatum key; |
490 | chashdatum data; | 495 | chashdatum data; |
491 | 496 | ||
492 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); | 497 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); |
493 | if (foldername == NULL) | 498 | if (foldername == NULL) |
494 | return MAILMH_ERROR_MEMORY; | 499 | return MAILMH_ERROR_MEMORY; |
495 | strcpy(foldername, parent->fl_filename); | 500 | strcpy(foldername, parent->fl_filename); |
496 | strcat(foldername, MAIL_DIR_SEPARATOR_S); | 501 | strcat(foldername, MAIL_DIR_SEPARATOR_S); |
497 | strcat(foldername, name); | 502 | strcat(foldername, name); |
498 | 503 | ||
499 | r = mkdir(foldername, 0700); | 504 | r = mkdir(foldername, 0700); |
500 | free(foldername); | 505 | free(foldername); |
501 | 506 | ||
502 | if (r < 0) | 507 | if (r < 0) |
503 | return MAILMH_ERROR_FOLDER; | 508 | return MAILMH_ERROR_FOLDER; |
504 | 509 | ||
505 | folder = mailmh_folder_new(parent, name); | 510 | folder = mailmh_folder_new(parent, name); |
506 | if (folder == NULL) | 511 | if (folder == NULL) |
507 | return MAILMH_ERROR_MEMORY; | 512 | return MAILMH_ERROR_MEMORY; |
508 | 513 | ||
509 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); | 514 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); |
510 | if (r < 0) { | 515 | if (r < 0) { |
511 | mailmh_folder_free(folder); | 516 | mailmh_folder_free(folder); |
512 | return MAILMH_ERROR_MEMORY; | 517 | return MAILMH_ERROR_MEMORY; |
513 | } | 518 | } |
514 | folder->fl_array_index = array_index; | 519 | folder->fl_array_index = array_index; |
515 | 520 | ||
516 | key.data = folder->fl_filename; | 521 | key.data = folder->fl_filename; |
517 | key.len = strlen(folder->fl_filename); | 522 | key.len = strlen(folder->fl_filename); |
518 | data.data = folder; | 523 | data.data = folder; |
519 | data.len = 0; | 524 | data.len = 0; |
520 | 525 | ||
521 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); | 526 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); |
522 | if (r < 0) { | 527 | if (r < 0) { |
523 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); | 528 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); |
524 | mailmh_folder_free(folder); | 529 | mailmh_folder_free(folder); |
525 | return MAILMH_ERROR_MEMORY; | 530 | return MAILMH_ERROR_MEMORY; |
526 | } | 531 | } |
527 | 532 | ||
528 | return MAILMH_NO_ERROR; | 533 | return MAILMH_NO_ERROR; |
529 | } | 534 | } |
530 | 535 | ||
531 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) | 536 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) |
532 | { | 537 | { |
533 | struct mailmh_folder * parent; | 538 | struct mailmh_folder * parent; |
534 | chashdatum key; | 539 | chashdatum key; |
535 | chashdatum data; | 540 | chashdatum data; |
536 | int r; | 541 | int r; |
537 | 542 | ||
538 | parent = folder->fl_parent; | 543 | parent = folder->fl_parent; |
539 | 544 | ||
540 | key.data = folder->fl_filename; | 545 | key.data = folder->fl_filename; |
541 | key.len = strlen(folder->fl_filename); | 546 | key.len = strlen(folder->fl_filename); |
542 | 547 | ||
543 | r = chash_get(parent->fl_subfolders_hash, &key, &data); | 548 | r = chash_get(parent->fl_subfolders_hash, &key, &data); |
544 | if (r < 0) | 549 | if (r < 0) |
545 | return MAILMH_ERROR_FOLDER; | 550 | return MAILMH_ERROR_FOLDER; |
546 | 551 | ||
547 | chash_delete(parent->fl_subfolders_hash, &key, NULL); | 552 | chash_delete(parent->fl_subfolders_hash, &key, NULL); |
548 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); | 553 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); |
549 | 554 | ||
550 | mailmh_folder_free(folder); | 555 | mailmh_folder_free(folder); |
551 | 556 | ||
552 | return MAILMH_NO_ERROR; | 557 | return MAILMH_NO_ERROR; |
553 | 558 | ||
554 | } | 559 | } |
555 | 560 | ||
556 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, | 561 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, |
557 | struct mailmh_folder * dst_folder, | 562 | struct mailmh_folder * dst_folder, |
558 | const char * new_name) | 563 | const char * new_name) |
559 | { | 564 | { |
560 | int r; | 565 | int r; |
561 | struct mailmh_folder * folder; | 566 | struct mailmh_folder * folder; |
562 | struct mailmh_folder * parent; | 567 | struct mailmh_folder * parent; |
563 | char * new_foldername; | 568 | char * new_foldername; |
564 | 569 | ||
565 | parent = src_folder->fl_parent; | 570 | parent = src_folder->fl_parent; |
566 | if (parent == NULL) | 571 | if (parent == NULL) |
567 | return MAILMH_ERROR_RENAME; | 572 | return MAILMH_ERROR_RENAME; |
568 | 573 | ||
569 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); | 574 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); |
570 | if (new_foldername == NULL) | 575 | if (new_foldername == NULL) |
571 | return MAILMH_ERROR_MEMORY; | 576 | return MAILMH_ERROR_MEMORY; |
572 | 577 | ||
573 | strcpy(new_foldername, dst_folder->fl_filename); | 578 | strcpy(new_foldername, dst_folder->fl_filename); |
574 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); | 579 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); |
575 | strcat(new_foldername, new_name); | 580 | strcat(new_foldername, new_name); |
576 | 581 | ||
577 | r = rename(src_folder->fl_filename, new_foldername); | 582 | r = rename(src_folder->fl_filename, new_foldername); |
578 | free(new_foldername); | 583 | free(new_foldername); |
579 | if (r < 0) | 584 | if (r < 0) |
580 | return MAILMH_ERROR_RENAME; | 585 | return MAILMH_ERROR_RENAME; |
581 | 586 | ||
582 | r = mailmh_folder_remove_subfolder(src_folder); | 587 | r = mailmh_folder_remove_subfolder(src_folder); |
583 | if (r != MAILMH_NO_ERROR) | 588 | if (r != MAILMH_NO_ERROR) |
584 | return r; | 589 | return r; |
585 | 590 | ||
586 | folder = mailmh_folder_new(dst_folder, new_name); | 591 | folder = mailmh_folder_new(dst_folder, new_name); |
587 | if (folder == NULL) | 592 | if (folder == NULL) |
588 | return MAILMH_ERROR_MEMORY; | 593 | return MAILMH_ERROR_MEMORY; |
589 | 594 | ||
590 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); | 595 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); |
591 | if (r < 0) { | 596 | if (r < 0) { |
592 | mailmh_folder_free(folder); | 597 | mailmh_folder_free(folder); |
593 | return MAILMH_ERROR_MEMORY; | 598 | return MAILMH_ERROR_MEMORY; |
594 | } | 599 | } |
595 | 600 | ||
596 | return MAILMH_NO_ERROR; | 601 | return MAILMH_NO_ERROR; |
597 | } | 602 | } |
598 | 603 | ||
599 | #define MAX_TRY_ALLOC 32 | 604 | #define MAX_TRY_ALLOC 32 |
600 | 605 | ||
601 | /* initial file MUST be in the same directory */ | 606 | /* initial file MUST be in the same directory */ |
602 | 607 | ||
603 | static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, | 608 | static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, |
604 | char * filename, uint32_t * result) | 609 | char * filename, uint32_t * result) |
605 | { | 610 | { |
606 | uint32_t max; | 611 | uint32_t max; |
607 | uint32_t k; | 612 | uint32_t k; |
608 | char * new_filename; | 613 | char * new_filename; |
609 | size_t len; | 614 | size_t len; |
610 | struct stat f_stat; | 615 | struct stat f_stat; |
611 | 616 | ||
612 | len = strlen(folder->fl_filename) + 20; | 617 | len = strlen(folder->fl_filename) + 20; |
613 | new_filename = malloc(len); | 618 | new_filename = malloc(len); |
614 | if (new_filename == NULL) | 619 | if (new_filename == NULL) |
615 | return MAILMH_ERROR_MEMORY; | 620 | return MAILMH_ERROR_MEMORY; |
616 | 621 | ||
617 | max = folder->fl_max_index + 1; | 622 | max = folder->fl_max_index + 1; |
618 | 623 | ||
619 | //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename); | 624 | //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename); |
620 | k = 0; | 625 | k = 0; |
621 | while (k < MAX_TRY_ALLOC) { | 626 | while (k < MAX_TRY_ALLOC) { |
622 | snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, | 627 | snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, |
623 | MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); | 628 | MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); |
624 | //fprintf(stderr,"mailmh_folder_alloc_msg new_filename: %s \n", new_filename); | 629 | //fprintf(stderr,"mailmh_folder_alloc_msg new_filename: %s \n", new_filename); |
625 | if ( stat( new_filename, &f_stat ) == -1 ) { | 630 | if ( stat( new_filename, &f_stat ) == -1 ) { |
626 | // if (link(filename, new_filename) == 0) { | 631 | // if (link(filename, new_filename) == 0) { |
627 | int r; | 632 | int r; |
628 | //fprintf(stderr,"filename found \n"); | 633 | //fprintf(stderr,"filename found \n"); |
629 | //unlink(filename); | 634 | //unlink(filename); |
630 | rename (filename,new_filename ); | 635 | rename (filename,new_filename ); |
631 | free(new_filename); | 636 | free(new_filename); |
632 | 637 | ||
633 | if (k > MAX_TRY_ALLOC / 2) { | 638 | if (k > MAX_TRY_ALLOC / 2) { |
634 | r = mailmh_folder_update(folder); | 639 | r = mailmh_folder_update(folder); |
635 | /* ignore errors */ | 640 | /* ignore errors */ |
636 | } | 641 | } |
637 | 642 | ||
638 | * result = max + k; | 643 | * result = max + k; |
639 | 644 | ||
640 | folder->fl_max_index = max + k; | 645 | folder->fl_max_index = max + k; |
641 | 646 | ||
642 | return MAILMH_NO_ERROR; | 647 | return MAILMH_NO_ERROR; |
643 | } | 648 | } |
644 | else if (errno == EXDEV) { | 649 | else if (errno == EXDEV) { |
645 | free(filename); | 650 | free(filename); |
646 | return MAILMH_ERROR_FOLDER; | 651 | return MAILMH_ERROR_FOLDER; |
647 | } | 652 | } |
648 | k ++; | 653 | k ++; |
649 | } | 654 | } |
650 | 655 | ||
651 | free(new_filename); | 656 | free(new_filename); |
652 | 657 | ||
653 | return MAILMH_ERROR_FOLDER; | 658 | return MAILMH_ERROR_FOLDER; |
654 | } | 659 | } |
655 | 660 | ||
656 | int mailmh_folder_get_message_filename(struct mailmh_folder * folder, | 661 | int mailmh_folder_get_message_filename(struct mailmh_folder * folder, |
657 | uint32_t index, char ** result) | 662 | uint32_t index, char ** result) |
658 | { | 663 | { |
659 | char * filename; | 664 | char * filename; |
660 | int len; | 665 | int len; |
661 | 666 | ||
662 | #if 0 | 667 | #if 0 |
663 | r = mailmh_folder_update(folder); | 668 | r = mailmh_folder_update(folder); |
664 | if (r != MAILMH_NO_ERROR) | 669 | if (r != MAILMH_NO_ERROR) |
665 | return r; | 670 | return r; |
666 | #endif | 671 | #endif |
667 | 672 | ||
668 | len = strlen(folder->fl_filename) + 20; | 673 | len = strlen(folder->fl_filename) + 20; |
669 | filename = malloc(len); | 674 | filename = malloc(len); |
670 | if (filename == NULL) | 675 | if (filename == NULL) |
671 | return MAILMH_ERROR_MEMORY; | 676 | return MAILMH_ERROR_MEMORY; |
672 | 677 | ||
673 | snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, | 678 | snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, |
674 | (unsigned long) index); | 679 | (unsigned long) index); |
675 | 680 | ||
676 | * result = filename; | 681 | * result = filename; |
677 | 682 | ||
678 | return MAILMH_NO_ERROR;; | 683 | return MAILMH_NO_ERROR;; |
679 | } | 684 | } |
680 | 685 | ||
681 | 686 | ||
682 | int mailmh_folder_get_message_fd(struct mailmh_folder * folder, | 687 | int mailmh_folder_get_message_fd(struct mailmh_folder * folder, |
683 | uint32_t index, int flags, int * result) | 688 | uint32_t index, int flags, int * result) |
684 | { | 689 | { |
685 | char * filename; | 690 | char * filename; |
686 | int fd; | 691 | int fd; |
687 | int r; | 692 | int r; |
688 | 693 | ||
689 | #if 0 | 694 | #if 0 |
690 | r = mailmh_folder_update(folder); | 695 | r = mailmh_folder_update(folder); |
691 | if (r != MAILMH_NO_ERROR) | 696 | if (r != MAILMH_NO_ERROR) |
692 | return r; | 697 | return r; |
693 | #endif | 698 | #endif |
694 | 699 | ||
695 | r = mailmh_folder_get_message_filename(folder, index, &filename); | 700 | r = mailmh_folder_get_message_filename(folder, index, &filename); |
696 | if (r != MAILMH_NO_ERROR) | 701 | if (r != MAILMH_NO_ERROR) |
697 | return r; | 702 | return r; |
698 | 703 | ||
699 | fd = open(filename, flags); | 704 | fd = open(filename, flags); |
700 | free(filename); | 705 | free(filename); |
701 | if (fd == -1) | 706 | if (fd == -1) |
702 | return MAILMH_ERROR_MSG_NOT_FOUND; | 707 | return MAILMH_ERROR_MSG_NOT_FOUND; |
703 | 708 | ||
704 | * result = fd; | 709 | * result = fd; |
705 | 710 | ||
706 | return MAILMH_NO_ERROR; | 711 | return MAILMH_NO_ERROR; |
707 | } | 712 | } |
708 | 713 | ||
709 | int mailmh_folder_get_message_size(struct mailmh_folder * folder, | 714 | int mailmh_folder_get_message_size(struct mailmh_folder * folder, |
710 | uint32_t index, size_t * result) | 715 | uint32_t index, size_t * result) |
711 | { | 716 | { |
712 | int r; | 717 | int r; |
713 | char * filename; | 718 | char * filename; |
714 | struct stat buf; | 719 | struct stat buf; |
715 | 720 | ||
716 | r = mailmh_folder_get_message_filename(folder, index, &filename); | 721 | r = mailmh_folder_get_message_filename(folder, index, &filename); |
717 | if (r != MAILMH_NO_ERROR) | 722 | if (r != MAILMH_NO_ERROR) |
718 | return r; | 723 | return r; |
719 | 724 | ||
720 | r = stat(filename, &buf); | 725 | r = stat(filename, &buf); |
721 | free(filename); | 726 | free(filename); |
722 | if (r < 0) | 727 | if (r < 0) |
723 | return MAILMH_ERROR_FILE; | 728 | return MAILMH_ERROR_FILE; |
724 | 729 | ||
725 | * result = buf.st_size; | 730 | * result = buf.st_size; |
726 | 731 | ||
727 | return MAILMH_NO_ERROR; | 732 | return MAILMH_NO_ERROR; |
728 | } | 733 | } |
729 | 734 | ||
730 | int mailmh_folder_add_message_uid(struct mailmh_folder * folder, | 735 | int mailmh_folder_add_message_uid(struct mailmh_folder * folder, |
731 | const char * message, size_t size, | 736 | const char * message, size_t size, |
732 | uint32_t * pindex) | 737 | uint32_t * pindex) |
733 | { | 738 | { |
734 | char * tmpname; | 739 | char * tmpname; |
735 | int fd; | 740 | int fd; |
736 | size_t namesize; | 741 | size_t namesize; |
737 | size_t left; | 742 | size_t left; |
738 | ssize_t res; | 743 | ssize_t res; |
739 | struct mailmh_msg_info * msg_info; | 744 | struct mailmh_msg_info * msg_info; |
740 | uint32_t index; | 745 | uint32_t index; |
741 | int error; | 746 | int error; |
742 | int r; | 747 | int r; |
743 | unsigned int array_index; | 748 | unsigned int array_index; |
744 | struct stat buf; | 749 | struct stat buf; |
745 | chashdatum key; | 750 | chashdatum key; |
746 | chashdatum data; | 751 | chashdatum data; |
747 | 752 | ||
748 | #if 0 | 753 | #if 0 |
749 | r = mailmh_folder_update(folder); | 754 | r = mailmh_folder_update(folder); |
750 | if (r != MAILMH_NO_ERROR) { | 755 | if (r != MAILMH_NO_ERROR) { |
751 | error = r; | 756 | error = r; |
752 | goto err; | 757 | goto err; |
753 | } | 758 | } |
754 | #endif | 759 | #endif |
755 | 760 | ||
756 | namesize = strlen(folder->fl_filename) + 20; | 761 | namesize = strlen(folder->fl_filename) + 20; |
757 | tmpname = malloc(namesize); | 762 | tmpname = malloc(namesize); |
758 | snprintf(tmpname, namesize, "%s%ctmpXXXXXX", | 763 | snprintf(tmpname, namesize, "%s%ctmpXXXXXX", |
759 | folder->fl_filename, MAIL_DIR_SEPARATOR); | 764 | folder->fl_filename, MAIL_DIR_SEPARATOR); |
760 | fd = mkstemp(tmpname); | 765 | fd = mkstemp(tmpname); |
761 | if (fd < 0) { | 766 | if (fd < 0) { |
762 | error = MAILMH_ERROR_FILE; | 767 | error = MAILMH_ERROR_FILE; |
763 | goto free; | 768 | goto free; |
764 | } | 769 | } |
765 | 770 | ||
766 | left = size; | 771 | left = size; |
767 | while (left > 0) { | 772 | while (left > 0) { |
768 | res = write(fd, message, left); | 773 | res = write(fd, message, left); |
769 | if (res == -1) { | 774 | if (res == -1) { |
770 | close(fd); | 775 | close(fd); |
771 | error = MAILMH_ERROR_FILE; | 776 | error = MAILMH_ERROR_FILE; |
772 | goto free; | 777 | goto free; |
773 | } | 778 | } |
774 | 779 | ||
775 | left -= res; | 780 | left -= res; |
776 | } | 781 | } |
777 | close(fd); | 782 | close(fd); |
778 | 783 | ||
779 | r = stat(tmpname, &buf); | 784 | r = stat(tmpname, &buf); |
780 | if (r < 0) { | 785 | if (r < 0) { |
781 | error = MAILMH_ERROR_FILE; | 786 | error = MAILMH_ERROR_FILE; |
782 | goto free; | 787 | goto free; |
783 | } | 788 | } |
784 | 789 | ||
785 | r = mailmh_folder_alloc_msg(folder, tmpname, &index); | 790 | r = mailmh_folder_alloc_msg(folder, tmpname, &index); |
786 | if (r != MAILMH_NO_ERROR) { | 791 | if (r != MAILMH_NO_ERROR) { |
787 | unlink(tmpname); | 792 | unlink(tmpname); |
788 | error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG; | 793 | error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG; |
789 | goto free; | 794 | goto free; |
790 | } | 795 | } |
791 | free(tmpname); | 796 | free(tmpname); |
792 | 797 | ||
793 | msg_info = mailmh_msg_info_new(index, size, buf.st_mtime); | 798 | msg_info = mailmh_msg_info_new(index, size, buf.st_mtime); |
794 | if (msg_info == NULL) { | 799 | if (msg_info == NULL) { |
795 | mailmh_folder_remove_message(folder, index); | 800 | mailmh_folder_remove_message(folder, index); |
796 | error = MAILMH_ERROR_MEMORY; | 801 | error = MAILMH_ERROR_MEMORY; |
797 | goto err; | 802 | goto err; |
798 | } | 803 | } |
799 | 804 | ||
800 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); | 805 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); |
801 | if (r < 0) { | 806 | if (r < 0) { |
802 | mailmh_folder_remove_message(folder, index); | 807 | mailmh_folder_remove_message(folder, index); |
803 | mailmh_msg_info_free(msg_info); | 808 | mailmh_msg_info_free(msg_info); |
804 | error = MAILMH_ERROR_MEMORY; | 809 | error = MAILMH_ERROR_MEMORY; |
805 | goto err; | 810 | goto err; |
806 | } | 811 | } |
807 | msg_info->msg_array_index = array_index; | 812 | msg_info->msg_array_index = array_index; |
808 | 813 | ||
809 | #if 0 | 814 | #if 0 |
810 | r = cinthash_add(folder->fl_msgs_hash, index, msg_info); | 815 | r = cinthash_add(folder->fl_msgs_hash, index, msg_info); |
811 | #endif | 816 | #endif |
812 | key.data = &index; | 817 | key.data = &index; |
813 | key.len = sizeof(index); | 818 | key.len = sizeof(index); |
814 | data.data = msg_info; | 819 | data.data = msg_info; |
815 | data.len = 0; | 820 | data.len = 0; |
816 | 821 | ||
817 | if (pindex != NULL) | 822 | if (pindex != NULL) |
818 | * pindex = index; | 823 | * pindex = index; |
819 | 824 | ||
820 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); | 825 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); |
821 | if (r < 0) { | 826 | if (r < 0) { |
822 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); | 827 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); |
823 | mailmh_msg_info_free(msg_info); | 828 | mailmh_msg_info_free(msg_info); |
824 | error = MAILMH_ERROR_MEMORY; | 829 | error = MAILMH_ERROR_MEMORY; |
825 | goto err; | 830 | goto err; |
826 | } | 831 | } |
827 | 832 | ||
828 | return MAILMH_NO_ERROR; | 833 | return MAILMH_NO_ERROR; |
829 | 834 | ||
830 | free: | 835 | free: |
831 | free(tmpname); | 836 | free(tmpname); |
832 | err: | 837 | err: |
833 | return error; | 838 | return error; |
834 | } | 839 | } |
835 | 840 | ||
836 | int mailmh_folder_add_message(struct mailmh_folder * folder, | 841 | int mailmh_folder_add_message(struct mailmh_folder * folder, |
837 | const char * message, size_t size) | 842 | const char * message, size_t size) |
838 | { | 843 | { |
839 | return mailmh_folder_add_message_uid(folder, message, size, NULL); | 844 | return mailmh_folder_add_message_uid(folder, message, size, NULL); |
840 | } | 845 | } |
841 | 846 | ||
842 | int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, | 847 | int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, |
843 | int fd, uint32_t * pindex) | 848 | int fd, uint32_t * pindex) |
844 | { | 849 | { |
845 | char * message; | 850 | char * message; |
846 | struct stat buf; | 851 | struct stat buf; |
847 | int r; | 852 | int r; |
848 | 853 | ||
849 | #if 0 | 854 | #if 0 |
850 | r = mailmh_folder_update(folder); | 855 | r = mailmh_folder_update(folder); |
851 | if (r != MAILMH_NO_ERROR) | 856 | if (r != MAILMH_NO_ERROR) |
852 | return r; | 857 | return r; |
853 | #endif | 858 | #endif |
854 | 859 | ||
855 | if (fstat(fd, &buf) == -1) | 860 | if (fstat(fd, &buf) == -1) |
856 | return MAILMH_ERROR_FILE; | 861 | return MAILMH_ERROR_FILE; |
857 | 862 | ||
858 | message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | 863 | message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
859 | if (message == MAP_FAILED) | 864 | if (message == MAP_FAILED) |
860 | return MAILMH_ERROR_FILE; | 865 | return MAILMH_ERROR_FILE; |
861 | 866 | ||
862 | r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex); | 867 | r = mailmh_folder_add_message_uid(folder, message, buf.st_size, pindex); |
863 | 868 | ||
864 | munmap(message, buf.st_size); | 869 | munmap(message, buf.st_size); |
865 | 870 | ||
866 | return r; | 871 | return r; |
867 | } | 872 | } |
868 | 873 | ||
869 | int mailmh_folder_add_message_file(struct mailmh_folder * folder, | 874 | int mailmh_folder_add_message_file(struct mailmh_folder * folder, |
870 | int fd) | 875 | int fd) |
871 | { | 876 | { |
872 | return mailmh_folder_add_message_file_uid(folder, fd, NULL); | 877 | return mailmh_folder_add_message_file_uid(folder, fd, NULL); |
873 | } | 878 | } |
874 | 879 | ||
875 | int mailmh_folder_remove_message(struct mailmh_folder * folder, | 880 | int mailmh_folder_remove_message(struct mailmh_folder * folder, |
876 | uint32_t index) | 881 | uint32_t index) |
877 | { | 882 | { |
878 | char * filename; | 883 | char * filename; |
879 | struct mailmh_msg_info * msg_info; | 884 | struct mailmh_msg_info * msg_info; |
880 | int res; | 885 | int res; |
881 | int r; | 886 | int r; |
882 | chashdatum key; | 887 | chashdatum key; |
883 | chashdatum data; | 888 | chashdatum data; |
884 | 889 | ||
885 | #if 0 | 890 | #if 0 |
886 | r = mailmh_folder_update(folder); | 891 | r = mailmh_folder_update(folder); |
887 | if (r != MAILMH_NO_ERROR) { | 892 | if (r != MAILMH_NO_ERROR) { |
888 | res = r; | 893 | res = r; |
889 | goto err; | 894 | goto err; |
890 | } | 895 | } |
891 | #endif | 896 | #endif |
892 | 897 | ||
893 | r = mailmh_folder_get_message_filename(folder, index, &filename); | 898 | r = mailmh_folder_get_message_filename(folder, index, &filename); |
894 | if (filename == NULL) { | 899 | if (filename == NULL) { |
895 | res = r; | 900 | res = r; |
896 | goto err; | 901 | goto err; |
897 | } | 902 | } |
898 | 903 | ||
899 | if (unlink(filename) == -1) { | 904 | if (unlink(filename) == -1) { |
900 | res = MAILMH_ERROR_FILE; | 905 | res = MAILMH_ERROR_FILE; |
901 | goto free; | 906 | goto free; |
902 | } | 907 | } |
903 | 908 | ||
904 | key.data = &index; | 909 | key.data = &index; |
905 | key.len = sizeof(index); | 910 | key.len = sizeof(index); |
906 | r = chash_get(folder->fl_msgs_hash, &key, &data); | 911 | r = chash_get(folder->fl_msgs_hash, &key, &data); |
907 | #if 0 | 912 | #if 0 |
908 | msg_info = cinthash_find(folder->fl_msgs_hash, index); | 913 | msg_info = cinthash_find(folder->fl_msgs_hash, index); |
909 | #endif | 914 | #endif |
910 | if (r == 0) { | 915 | if (r == 0) { |
911 | msg_info = data.data; | 916 | msg_info = data.data; |
912 | 917 | ||
913 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); | 918 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); |
914 | #if 0 | 919 | #if 0 |
915 | cinthash_remove(folder->fl_msgs_hash, index); | 920 | cinthash_remove(folder->fl_msgs_hash, index); |
916 | #endif | 921 | #endif |
917 | chash_delete(folder->fl_msgs_hash, &key, NULL); | 922 | chash_delete(folder->fl_msgs_hash, &key, NULL); |
918 | } | 923 | } |
919 | 924 | ||
920 | return MAILMH_NO_ERROR; | 925 | return MAILMH_NO_ERROR; |
921 | 926 | ||
922 | free: | 927 | free: |
923 | free(filename); | 928 | free(filename); |
924 | err: | 929 | err: |
925 | return res; | 930 | return res; |
926 | } | 931 | } |
927 | 932 | ||
928 | 933 | ||
929 | int mailmh_folder_move_message(struct mailmh_folder * dest_folder, | 934 | int mailmh_folder_move_message(struct mailmh_folder * dest_folder, |
930 | struct mailmh_folder * src_folder, | 935 | struct mailmh_folder * src_folder, |
931 | uint32_t index) | 936 | uint32_t index) |
932 | { | 937 | { |
933 | int fd; | 938 | int fd; |
934 | char * filename; | 939 | char * filename; |
935 | int r; | 940 | int r; |
936 | 941 | ||
937 | #if 0 | 942 | #if 0 |
938 | r = mailmh_folder_update(dest_folder); | 943 | r = mailmh_folder_update(dest_folder); |
939 | if (r != MAILMH_NO_ERROR) | 944 | if (r != MAILMH_NO_ERROR) |
940 | return r; | 945 | return r; |
941 | r = mailmh_folder_update(src_folder); | 946 | r = mailmh_folder_update(src_folder); |
942 | if (r != MAILMH_NO_ERROR) | 947 | if (r != MAILMH_NO_ERROR) |
943 | return r; | 948 | return r; |
944 | #endif | 949 | #endif |
945 | 950 | ||
946 | /* move on the same filesystem */ | 951 | /* move on the same filesystem */ |
947 | r = mailmh_folder_get_message_filename(src_folder, index, &filename); | 952 | r = mailmh_folder_get_message_filename(src_folder, index, &filename); |
948 | if (r != MAILMH_NO_ERROR) | 953 | if (r != MAILMH_NO_ERROR) |
949 | return r; | 954 | return r; |
950 | 955 | ||
951 | r = mailmh_folder_alloc_msg(dest_folder, filename, &index); | 956 | r = mailmh_folder_alloc_msg(dest_folder, filename, &index); |
952 | free(filename); | 957 | free(filename); |
953 | if (r == MAILMH_NO_ERROR) | 958 | if (r == MAILMH_NO_ERROR) |
954 | return MAILMH_NO_ERROR; | 959 | return MAILMH_NO_ERROR; |
955 | 960 | ||
956 | /* move on the different filesystems */ | 961 | /* move on the different filesystems */ |
957 | r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd); | 962 | r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd); |
958 | if (r != MAILMH_NO_ERROR) | 963 | if (r != MAILMH_NO_ERROR) |
959 | return r; | 964 | return r; |
960 | 965 | ||
961 | r = mailmh_folder_add_message_file(dest_folder, fd); | 966 | r = mailmh_folder_add_message_file(dest_folder, fd); |
962 | if (r != MAILMH_NO_ERROR) { | 967 | if (r != MAILMH_NO_ERROR) { |
963 | close(fd); | 968 | close(fd); |
964 | return r; | 969 | return r; |
965 | } | 970 | } |
966 | 971 | ||
967 | close(fd); | 972 | close(fd); |
968 | 973 | ||
969 | r = mailmh_folder_remove_message(src_folder, index); | 974 | r = mailmh_folder_remove_message(src_folder, index); |
970 | 975 | ||
971 | return MAILMH_NO_ERROR; | 976 | return MAILMH_NO_ERROR; |
972 | } | 977 | } |
973 | 978 | ||
974 | unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder) | 979 | unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder) |
975 | { | 980 | { |
976 | unsigned int i; | 981 | unsigned int i; |
977 | unsigned int count; | 982 | unsigned int count; |
978 | 983 | ||
979 | count = 0; | 984 | count = 0; |
980 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) | 985 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) |