summaryrefslogtreecommitdiffabout
path: root/kmicromail/libetpan
Unidiff
Diffstat (limited to 'kmicromail/libetpan') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/mh/mailmh.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c
index 1087ce1..2d1f26d 100644
--- a/kmicromail/libetpan/mh/mailmh.c
+++ b/kmicromail/libetpan/mh/mailmh.c
@@ -1,990 +1,993 @@
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/*
39perfs : 39perfs :
40 40
41/net/home/dinh/Mail/inbox/sylpheed 686 41/net/home/dinh/Mail/inbox/sylpheed 686
42 42
432724 /net/home/dinh/Mail/inbox/sylpheed 432724 /net/home/dinh/Mail/inbox/sylpheed
44 44
45bart:~/LibEtPan/libetpan/tests> time ./mhtest >/dev/null 45bart:~/LibEtPan/libetpan/tests> time ./mhtest >/dev/null
46 46
47real 0m0.385s 47real 0m0.385s
48user 0m0.270s 48user 0m0.270s
49sys 0m0.110s 49sys 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
65struct mailmh * mailmh_new(const char * foldername) 65struct 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
82void mailmh_free(struct mailmh * f) 82void 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
90struct mailmh_msg_info * mailmh_msg_info_new(uint32_t index, size_t size, 90struct 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
107void mailmh_msg_info_free(struct mailmh_msg_info * msg_info) 107void mailmh_msg_info_free(struct mailmh_msg_info * msg_info)
108{ 108{
109 free(msg_info); 109 free(msg_info);
110} 110}
111 111
112struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent, 112struct 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
192void mailmh_folder_free(struct mailmh_folder * folder) 192void 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
225struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, 225struct 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
285int mailmh_folder_update(struct mailmh_folder * folder) 285int 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 //LR memory leak? added next line 402 //LR memory leak? added next line
403 //mailmh_msg_info_free(msg_info); 403 //mailmh_msg_info_free(msg_info);
404 //it seems so that it should be freed later, 404 //it seems so that it should be freed later,
405 // but it is not in every case 405 // but it is not in every case
406 //PENDING fixme in ompi somewhere 406 //PENDING fixme in ompi somewhere
407 } 407 }
408 } 408 }
409 else if (S_ISDIR(buf.st_mode)) { 409 else if (S_ISDIR(buf.st_mode)) {
410 struct mailmh_folder * subfolder; 410 struct mailmh_folder * subfolder;
411 unsigned int array_index; 411 unsigned int array_index;
412 chashdatum key; 412 chashdatum key;
413 chashdatum data; 413 chashdatum data;
414 414
415 if (ent->d_name[0] == '.') { 415 if (ent->d_name[0] == '.') {
416 if (ent->d_name[1] == 0) 416 if (ent->d_name[1] == 0)
417 continue; 417 continue;
418 if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) 418 if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0))
419 continue; 419 continue;
420 } 420 }
421 421
422 key.data = ent->d_name; 422 key.data = ent->d_name;
423 key.len = strlen(ent->d_name); 423 key.len = strlen(ent->d_name);
424 r = chash_get(folder->fl_subfolders_hash, &key, &data); 424 r = chash_get(folder->fl_subfolders_hash, &key, &data);
425 if (r < 0) { 425 if (r < 0) {
426 subfolder = mailmh_folder_new(folder, ent->d_name); 426 subfolder = mailmh_folder_new(folder, ent->d_name);
427 if (subfolder == NULL) { 427 if (subfolder == NULL) {
428 res = MAILMH_ERROR_MEMORY; 428 res = MAILMH_ERROR_MEMORY;
429 goto closedir; 429 goto closedir;
430 } 430 }
431 431
432 r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); 432 r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index);
433 if (r < 0) { 433 if (r < 0) {
434 mailmh_folder_free(subfolder); 434 mailmh_folder_free(subfolder);
435 res = MAILMH_ERROR_MEMORY; 435 res = MAILMH_ERROR_MEMORY;
436 goto closedir; 436 goto closedir;
437 } 437 }
438 subfolder->fl_array_index = array_index; 438 subfolder->fl_array_index = array_index;
439 439
440 key.data = subfolder->fl_filename; 440 key.data = subfolder->fl_filename;
441 key.len = strlen(subfolder->fl_filename); 441 key.len = strlen(subfolder->fl_filename);
442 data.data = subfolder; 442 data.data = subfolder;
443 data.len = 0; 443 data.len = 0;
444 r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); 444 r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL);
445 if (r < 0) { 445 if (r < 0) {
446 carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); 446 carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index);
447 mailmh_folder_free(subfolder); 447 mailmh_folder_free(subfolder);
448 res = MAILMH_ERROR_MEMORY; 448 res = MAILMH_ERROR_MEMORY;
449 goto closedir; 449 goto closedir;
450 } 450 }
451 } 451 }
452 } 452 }
453 } 453 }
454 } 454 }
455 while (ent != NULL); 455 while (ent != NULL);
456 456
457 folder->fl_max_index = max_index; 457 folder->fl_max_index = max_index;
458 458
459 mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); 459 mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences"));
460 if (mh_seq == NULL) { 460 if (mh_seq == NULL) {
461 res = MAILMH_ERROR_MEMORY; 461 res = MAILMH_ERROR_MEMORY;
462 goto closedir; 462 goto closedir;
463 } 463 }
464 strcpy(mh_seq, folder->fl_filename); 464 strcpy(mh_seq, folder->fl_filename);
465 strcat(mh_seq, MAIL_DIR_SEPARATOR_S); 465 strcat(mh_seq, MAIL_DIR_SEPARATOR_S);
466 strcat(mh_seq, ".mh_sequences"); 466 strcat(mh_seq, ".mh_sequences");
467 467
468 if (stat(mh_seq, &buf) == -1) { 468 if (stat(mh_seq, &buf) == -1) {
469 int fd; 469 int fd;
470 470
471 fd = creat(mh_seq, S_IRUSR | S_IWUSR); 471 fd = creat(mh_seq, S_IRUSR | S_IWUSR);
472 if (fd != -1) 472 if (fd != -1)
473 close(fd); 473 close(fd);
474 } 474 }
475 free(mh_seq); 475 free(mh_seq);
476 476
477 closedir(d); 477 closedir(d);
478 478
479 return MAILMH_NO_ERROR; 479 return MAILMH_NO_ERROR;
480 480
481 closedir: 481 closedir:
482 closedir(d); 482 closedir(d);
483 err: 483 err:
484 return res; 484 return res;
485} 485}
486 486
487int mailmh_folder_add_subfolder(struct mailmh_folder * parent, 487int mailmh_folder_add_subfolder(struct mailmh_folder * parent,
488 const char * name) 488 const char * name)
489{ 489{
490 char * foldername; 490 char * foldername;
491 int r; 491 int r;
492 struct mailmh_folder * folder; 492 struct mailmh_folder * folder;
493 unsigned int array_index; 493 unsigned int array_index;
494 chashdatum key; 494 chashdatum key;
495 chashdatum data; 495 chashdatum data;
496 496
497 foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); 497 foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2);
498 if (foldername == NULL) 498 if (foldername == NULL)
499 return MAILMH_ERROR_MEMORY; 499 return MAILMH_ERROR_MEMORY;
500 strcpy(foldername, parent->fl_filename); 500 strcpy(foldername, parent->fl_filename);
501 strcat(foldername, MAIL_DIR_SEPARATOR_S); 501 strcat(foldername, MAIL_DIR_SEPARATOR_S);
502 strcat(foldername, name); 502 strcat(foldername, name);
503 503
504 r = mkdir(foldername, 0700); 504 r = mkdir(foldername, 0700);
505 free(foldername); 505 free(foldername);
506 506
507 if (r < 0) 507 if (r < 0)
508 return MAILMH_ERROR_FOLDER; 508 return MAILMH_ERROR_FOLDER;
509 509
510 folder = mailmh_folder_new(parent, name); 510 folder = mailmh_folder_new(parent, name);
511 if (folder == NULL) 511 if (folder == NULL)
512 return MAILMH_ERROR_MEMORY; 512 return MAILMH_ERROR_MEMORY;
513 513
514 r = carray_add(parent->fl_subfolders_tab, folder, &array_index); 514 r = carray_add(parent->fl_subfolders_tab, folder, &array_index);
515 if (r < 0) { 515 if (r < 0) {
516 mailmh_folder_free(folder); 516 mailmh_folder_free(folder);
517 return MAILMH_ERROR_MEMORY; 517 return MAILMH_ERROR_MEMORY;
518 } 518 }
519 folder->fl_array_index = array_index; 519 folder->fl_array_index = array_index;
520 520
521 key.data = folder->fl_filename; 521 key.data = folder->fl_filename;
522 key.len = strlen(folder->fl_filename); 522 key.len = strlen(folder->fl_filename);
523 data.data = folder; 523 data.data = folder;
524 data.len = 0; 524 data.len = 0;
525 525
526 r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); 526 r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL);
527 if (r < 0) { 527 if (r < 0) {
528 carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); 528 carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index);
529 mailmh_folder_free(folder); 529 mailmh_folder_free(folder);
530 return MAILMH_ERROR_MEMORY; 530 return MAILMH_ERROR_MEMORY;
531 } 531 }
532 532
533 return MAILMH_NO_ERROR; 533 return MAILMH_NO_ERROR;
534} 534}
535 535
536int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) 536int mailmh_folder_remove_subfolder(struct mailmh_folder * folder)
537{ 537{
538 struct mailmh_folder * parent; 538 struct mailmh_folder * parent;
539 chashdatum key; 539 chashdatum key;
540 chashdatum data; 540 chashdatum data;
541 int r; 541 int r;
542 542
543 parent = folder->fl_parent; 543 parent = folder->fl_parent;
544 544
545 key.data = folder->fl_filename; 545 key.data = folder->fl_filename;
546 key.len = strlen(folder->fl_filename); 546 key.len = strlen(folder->fl_filename);
547 547
548 r = chash_get(parent->fl_subfolders_hash, &key, &data); 548 r = chash_get(parent->fl_subfolders_hash, &key, &data);
549 if (r < 0) 549 if (r < 0)
550 return MAILMH_ERROR_FOLDER; 550 return MAILMH_ERROR_FOLDER;
551 551
552 chash_delete(parent->fl_subfolders_hash, &key, NULL); 552 chash_delete(parent->fl_subfolders_hash, &key, NULL);
553 carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); 553 carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index);
554 554
555 mailmh_folder_free(folder); 555 mailmh_folder_free(folder);
556 556
557 return MAILMH_NO_ERROR; 557 return MAILMH_NO_ERROR;
558 558
559} 559}
560 560
561int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, 561int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
562 struct mailmh_folder * dst_folder, 562 struct mailmh_folder * dst_folder,
563 const char * new_name) 563 const char * new_name)
564{ 564{
565 int r; 565 int r;
566 struct mailmh_folder * folder; 566 struct mailmh_folder * folder;
567 struct mailmh_folder * parent; 567 struct mailmh_folder * parent;
568 char * new_foldername; 568 char * new_foldername;
569 569
570 parent = src_folder->fl_parent; 570 parent = src_folder->fl_parent;
571 if (parent == NULL) 571 if (parent == NULL)
572 return MAILMH_ERROR_RENAME; 572 return MAILMH_ERROR_RENAME;
573 573
574 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));
575 if (new_foldername == NULL) 575 if (new_foldername == NULL)
576 return MAILMH_ERROR_MEMORY; 576 return MAILMH_ERROR_MEMORY;
577 577
578 strcpy(new_foldername, dst_folder->fl_filename); 578 strcpy(new_foldername, dst_folder->fl_filename);
579 strcat(new_foldername, MAIL_DIR_SEPARATOR_S); 579 strcat(new_foldername, MAIL_DIR_SEPARATOR_S);
580 strcat(new_foldername, new_name); 580 strcat(new_foldername, new_name);
581 581
582 r = rename(src_folder->fl_filename, new_foldername); 582 r = rename(src_folder->fl_filename, new_foldername);
583 free(new_foldername); 583 free(new_foldername);
584 if (r < 0) 584 if (r < 0)
585 return MAILMH_ERROR_RENAME; 585 return MAILMH_ERROR_RENAME;
586 586
587 r = mailmh_folder_remove_subfolder(src_folder); 587 r = mailmh_folder_remove_subfolder(src_folder);
588 if (r != MAILMH_NO_ERROR) 588 if (r != MAILMH_NO_ERROR)
589 return r; 589 return r;
590 590
591 folder = mailmh_folder_new(dst_folder, new_name); 591 folder = mailmh_folder_new(dst_folder, new_name);
592 if (folder == NULL) 592 if (folder == NULL)
593 return MAILMH_ERROR_MEMORY; 593 return MAILMH_ERROR_MEMORY;
594 594
595 r = carray_add(parent->fl_subfolders_tab, folder, NULL); 595 r = carray_add(parent->fl_subfolders_tab, folder, NULL);
596 if (r < 0) { 596 if (r < 0) {
597 mailmh_folder_free(folder); 597 mailmh_folder_free(folder);
598 return MAILMH_ERROR_MEMORY; 598 return MAILMH_ERROR_MEMORY;
599 } 599 }
600 600
601 return MAILMH_NO_ERROR; 601 return MAILMH_NO_ERROR;
602} 602}
603 603
604#define MAX_TRY_ALLOC 32 604#define MAX_TRY_ALLOC 32
605 605
606/* initial file MUST be in the same directory */ 606/* initial file MUST be in the same directory */
607 607
608static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, 608static int mailmh_folder_alloc_msg(struct mailmh_folder * folder,
609 char * filename, uint32_t * result) 609 char * filename, uint32_t * result)
610{ 610{
611 uint32_t max; 611 uint32_t max;
612 uint32_t k; 612 uint32_t k;
613 char * new_filename; 613 char * new_filename;
614 size_t len; 614 size_t len;
615 struct stat f_stat; 615 struct stat f_stat;
616 616
617 len = strlen(folder->fl_filename) + 20; 617 len = strlen(folder->fl_filename) + 20;
618 new_filename = malloc(len); 618 new_filename = malloc(len);
619 if (new_filename == NULL) 619 if (new_filename == NULL)
620 return MAILMH_ERROR_MEMORY; 620 return MAILMH_ERROR_MEMORY;
621 621
622 max = folder->fl_max_index + 1; 622 max = folder->fl_max_index + 1;
623 623
624 //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename); 624 //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename);
625 k = 0; 625 k = 0;
626 while (k < MAX_TRY_ALLOC) { 626 while (k < MAX_TRY_ALLOC) {
627 snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, 627 snprintf(new_filename, len, "%s%c%lu", folder->fl_filename,
628 MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); 628 MAIL_DIR_SEPARATOR, (unsigned long) (max + k));
629 //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);
630 if ( stat( new_filename, &f_stat ) == -1 ) { 630 if ( stat( new_filename, &f_stat ) == -1 ) {
631 // if (link(filename, new_filename) == 0) { 631 // if (link(filename, new_filename) == 0) {
632 int r; 632 int r;
633 //fprintf(stderr,"filename found \n"); 633 //fprintf(stderr,"filename found \n");
634 //unlink(filename); 634 //unlink(filename);
635 rename (filename,new_filename ); 635 rename (filename,new_filename );
636 free(new_filename); 636 free(new_filename);
637 637
638 if (k > MAX_TRY_ALLOC / 2) { 638 if (k > MAX_TRY_ALLOC / 2) {
639 r = mailmh_folder_update(folder); 639 r = mailmh_folder_update(folder);
640 /* ignore errors */ 640 /* ignore errors */
641 } 641 }
642 642
643 * result = max + k; 643 * result = max + k;
644 644
645 folder->fl_max_index = max + k; 645 folder->fl_max_index = max + k;
646 646
647 return MAILMH_NO_ERROR; 647 return MAILMH_NO_ERROR;
648 } 648 }
649 else if (errno == EXDEV) { 649 else if (errno == EXDEV) {
650 free(filename); 650 free(filename);
651 return MAILMH_ERROR_FOLDER; 651 return MAILMH_ERROR_FOLDER;
652 } 652 }
653 k ++; 653 k ++;
654 } 654 }
655 655
656 free(new_filename); 656 free(new_filename);
657 657
658 return MAILMH_ERROR_FOLDER; 658 return MAILMH_ERROR_FOLDER;
659} 659}
660 660
661int mailmh_folder_get_message_filename(struct mailmh_folder * folder, 661int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
662 uint32_t index, char ** result) 662 uint32_t index, char ** result)
663{ 663{
664 char * filename; 664 char * filename;
665 int len; 665 int len;
666 666
667#if 0 667#if 0
668 r = mailmh_folder_update(folder); 668 r = mailmh_folder_update(folder);
669 if (r != MAILMH_NO_ERROR) 669 if (r != MAILMH_NO_ERROR)
670 return r; 670 return r;
671#endif 671#endif
672 672
673 len = strlen(folder->fl_filename) + 20; 673 len = strlen(folder->fl_filename) + 20;
674 filename = malloc(len); 674 filename = malloc(len);
675 if (filename == NULL) 675 if (filename == NULL)
676 return MAILMH_ERROR_MEMORY; 676 return MAILMH_ERROR_MEMORY;
677 677
678 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,
679 (unsigned long) index); 679 (unsigned long) index);
680 680
681 * result = filename; 681 * result = filename;
682 682
683 return MAILMH_NO_ERROR;; 683 return MAILMH_NO_ERROR;;
684} 684}
685 685
686 686
687int mailmh_folder_get_message_fd(struct mailmh_folder * folder, 687int mailmh_folder_get_message_fd(struct mailmh_folder * folder,
688 uint32_t index, int flags, int * result) 688 uint32_t index, int flags, int * result)
689{ 689{
690 char * filename; 690 char * filename;
691 int fd; 691 int fd;
692 int r; 692 int r;
693 693
694#if 0 694#if 0
695 r = mailmh_folder_update(folder); 695 r = mailmh_folder_update(folder);
696 if (r != MAILMH_NO_ERROR) 696 if (r != MAILMH_NO_ERROR)
697 return r; 697 return r;
698#endif 698#endif
699 699
700 r = mailmh_folder_get_message_filename(folder, index, &filename); 700 r = mailmh_folder_get_message_filename(folder, index, &filename);
701 if (r != MAILMH_NO_ERROR) 701 if (r != MAILMH_NO_ERROR)
702 return r; 702 return r;
703 703
704 fd = open(filename, flags); 704 fd = open(filename, flags);
705 free(filename); 705 free(filename);
706 if (fd == -1) 706 if (fd == -1)
707 return MAILMH_ERROR_MSG_NOT_FOUND; 707 return MAILMH_ERROR_MSG_NOT_FOUND;
708 708
709 * result = fd; 709 * result = fd;
710 710
711 return MAILMH_NO_ERROR; 711 return MAILMH_NO_ERROR;
712} 712}
713 713
714int mailmh_folder_get_message_size(struct mailmh_folder * folder, 714int mailmh_folder_get_message_size(struct mailmh_folder * folder,
715 uint32_t index, size_t * result) 715 uint32_t index, size_t * result)
716{ 716{
717 int r; 717 int r;
718 char * filename; 718 char * filename;
719 struct stat buf; 719 struct stat buf;
720 720
721 r = mailmh_folder_get_message_filename(folder, index, &filename); 721 r = mailmh_folder_get_message_filename(folder, index, &filename);
722 if (r != MAILMH_NO_ERROR) 722 if (r != MAILMH_NO_ERROR)
723 return r; 723 return r;
724 724
725 r = stat(filename, &buf); 725 r = stat(filename, &buf);
726 free(filename); 726 free(filename);
727 if (r < 0) 727 if (r < 0)
728 return MAILMH_ERROR_FILE; 728 return MAILMH_ERROR_FILE;
729 729
730 * result = buf.st_size; 730 * result = buf.st_size;
731 731
732 return MAILMH_NO_ERROR; 732 return MAILMH_NO_ERROR;
733} 733}
734 734
735int mailmh_folder_add_message_uid(struct mailmh_folder * folder, 735int mailmh_folder_add_message_uid(struct mailmh_folder * folder,
736 const char * message, size_t size, 736 const char * message, size_t size,
737 uint32_t * pindex) 737 uint32_t * pindex)
738{ 738{
739 char * tmpname; 739 char * tmpname;
740 int fd; 740 int fd;
741 size_t namesize; 741 size_t namesize;
742 size_t left; 742 size_t left;
743 ssize_t res; 743 ssize_t res;
744 struct mailmh_msg_info * msg_info; 744 struct mailmh_msg_info * msg_info;
745 uint32_t index; 745 uint32_t index;
746 int error; 746 int error;
747 int r; 747 int r;
748 unsigned int array_index; 748 unsigned int array_index;
749 struct stat buf; 749 struct stat buf;
750 chashdatum key; 750 chashdatum key;
751 chashdatum data; 751 chashdatum data;
752 752
753#if 0 753#if 0
754 r = mailmh_folder_update(folder); 754 r = mailmh_folder_update(folder);
755 if (r != MAILMH_NO_ERROR) { 755 if (r != MAILMH_NO_ERROR) {
756 error = r; 756 error = r;
757 goto err; 757 goto err;
758 } 758 }
759#endif 759#endif
760 760
761 namesize = strlen(folder->fl_filename) + 20; 761 namesize = strlen(folder->fl_filename) + 20;
762 tmpname = malloc(namesize); 762 tmpname = malloc(namesize);
763 snprintf(tmpname, namesize, "%s%ctmpXXXXXX", 763 snprintf(tmpname, namesize, "%s%ctmpXXXXXX",
764 folder->fl_filename, MAIL_DIR_SEPARATOR); 764 folder->fl_filename, MAIL_DIR_SEPARATOR);
765 fd = mkstemp(tmpname); 765 fd = mkstemp(tmpname);
766 if (fd < 0) { 766 if (fd < 0) {
767 error = MAILMH_ERROR_FILE; 767 error = MAILMH_ERROR_FILE;
768 goto free; 768 goto free;
769 } 769 }
770 770
771 left = size; 771 left = size;
772 while (left > 0) { 772 while (left > 0) {
773 res = write(fd, message, left); 773 res = write(fd, message, left);
774 if (res == -1) { 774 if (res == -1) {
775 close(fd); 775 close(fd);
776 error = MAILMH_ERROR_FILE; 776 error = MAILMH_ERROR_FILE;
777 goto free; 777 goto free;
778 } 778 }
779 779
780 left -= res; 780 left -= res;
781 } 781 }
782 close(fd); 782 close(fd);
783 783
784 r = stat(tmpname, &buf); 784 r = stat(tmpname, &buf);
785 if (r < 0) { 785 if (r < 0) {
786 error = MAILMH_ERROR_FILE; 786 error = MAILMH_ERROR_FILE;
787 goto free; 787 goto free;
788 } 788 }
789 789
790 r = mailmh_folder_alloc_msg(folder, tmpname, &index); 790 r = mailmh_folder_alloc_msg(folder, tmpname, &index);
791 if (r != MAILMH_NO_ERROR) { 791 if (r != MAILMH_NO_ERROR) {
792 unlink(tmpname); 792 unlink(tmpname);
793 error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG; 793 error = MAILMH_ERROR_COULD_NOT_ALLOC_MSG;
794 goto free; 794 goto free;
795 } 795 }
796 free(tmpname); 796 free(tmpname);
797 797
798 msg_info = mailmh_msg_info_new(index, size, buf.st_mtime); 798 msg_info = mailmh_msg_info_new(index, size, buf.st_mtime);
799 if (msg_info == NULL) { 799 if (msg_info == NULL) {
800 mailmh_folder_remove_message(folder, index); 800 mailmh_folder_remove_message(folder, index);
801 error = MAILMH_ERROR_MEMORY; 801 error = MAILMH_ERROR_MEMORY;
802 goto err; 802 goto err;
803 } 803 }
804 804
805 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); 805 r = carray_add(folder->fl_msgs_tab, msg_info, &array_index);
806 if (r < 0) { 806 if (r < 0) {
807 mailmh_folder_remove_message(folder, index); 807 mailmh_folder_remove_message(folder, index);
808 mailmh_msg_info_free(msg_info); 808 mailmh_msg_info_free(msg_info);
809 error = MAILMH_ERROR_MEMORY; 809 error = MAILMH_ERROR_MEMORY;
810 goto err; 810 goto err;
811 } 811 }
812 msg_info->msg_array_index = array_index; 812 msg_info->msg_array_index = array_index;
813 813
814#if 0 814#if 0
815 r = cinthash_add(folder->fl_msgs_hash, index, msg_info); 815 r = cinthash_add(folder->fl_msgs_hash, index, msg_info);
816#endif 816#endif
817 key.data = &index; 817 key.data = &index;
818 key.len = sizeof(index); 818 key.len = sizeof(index);
819 data.data = msg_info; 819 data.data = msg_info;
820 data.len = 0; 820 data.len = 0;
821 821
822 if (pindex != NULL) 822 if (pindex != NULL)
823 * pindex = index; 823 * pindex = index;
824 824
825 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); 825 r = chash_set(folder->fl_msgs_hash, &key, &data, NULL);
826 if (r < 0) { 826 if (r < 0) {
827 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);
828 mailmh_msg_info_free(msg_info); 828 mailmh_msg_info_free(msg_info);
829 error = MAILMH_ERROR_MEMORY; 829 error = MAILMH_ERROR_MEMORY;
830 goto err; 830 goto err;
831 } 831 }
832 832
833 return MAILMH_NO_ERROR; 833 return MAILMH_NO_ERROR;
834 834
835 free: 835 free:
836 free(tmpname); 836 free(tmpname);
837 err: 837 err:
838 return error; 838 return error;
839} 839}
840 840
841int mailmh_folder_add_message(struct mailmh_folder * folder, 841int mailmh_folder_add_message(struct mailmh_folder * folder,
842 const char * message, size_t size) 842 const char * message, size_t size)
843{ 843{
844 return mailmh_folder_add_message_uid(folder, message, size, NULL); 844 return mailmh_folder_add_message_uid(folder, message, size, NULL);
845} 845}
846 846
847int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder, 847int mailmh_folder_add_message_file_uid(struct mailmh_folder * folder,
848 int fd, uint32_t * pindex) 848 int fd, uint32_t * pindex)
849{ 849{
850 char * message; 850 char * message;
851 struct stat buf; 851 struct stat buf;
852 int r; 852 int r;
853 853
854#if 0 854#if 0
855 r = mailmh_folder_update(folder); 855 r = mailmh_folder_update(folder);
856 if (r != MAILMH_NO_ERROR) 856 if (r != MAILMH_NO_ERROR)
857 return r; 857 return r;
858#endif 858#endif
859 859
860 if (fstat(fd, &buf) == -1) 860 if (fstat(fd, &buf) == -1)
861 return MAILMH_ERROR_FILE; 861 return MAILMH_ERROR_FILE;
862 862
863 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);
864 if (message == MAP_FAILED) 864 if (message == MAP_FAILED)
865 return MAILMH_ERROR_FILE; 865 return MAILMH_ERROR_FILE;
866 866
867 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);
868 868
869 munmap(message, buf.st_size); 869 munmap(message, buf.st_size);
870 870
871 return r; 871 return r;
872} 872}
873 873
874int mailmh_folder_add_message_file(struct mailmh_folder * folder, 874int mailmh_folder_add_message_file(struct mailmh_folder * folder,
875 int fd) 875 int fd)
876{ 876{
877 return mailmh_folder_add_message_file_uid(folder, fd, NULL); 877 return mailmh_folder_add_message_file_uid(folder, fd, NULL);
878} 878}
879 879
880int mailmh_folder_remove_message(struct mailmh_folder * folder, 880int mailmh_folder_remove_message(struct mailmh_folder * folder,
881 uint32_t index) 881 uint32_t index)
882{ 882{
883 char * filename; 883 char * filename;
884 struct mailmh_msg_info * msg_info; 884 struct mailmh_msg_info * msg_info;
885 int res; 885 int res;
886 int r; 886 int r;
887 chashdatum key; 887 chashdatum key;
888 chashdatum data; 888 chashdatum data;
889 889
890#if 0 890#if 0
891 r = mailmh_folder_update(folder); 891 r = mailmh_folder_update(folder);
892 if (r != MAILMH_NO_ERROR) { 892 if (r != MAILMH_NO_ERROR) {
893 res = r; 893 res = r;
894 goto err; 894 goto err;
895 } 895 }
896#endif 896#endif
897 897
898 r = mailmh_folder_get_message_filename(folder, index, &filename); 898 r = mailmh_folder_get_message_filename(folder, index, &filename);
899 if (filename == NULL) { 899 if (filename == NULL) {
900 res = r; 900 res = r;
901 goto err; 901 goto err;
902 } 902 }
903 903
904 if (unlink(filename) == -1) { 904 if (unlink(filename) == -1) {
905 res = MAILMH_ERROR_FILE; 905 res = MAILMH_ERROR_FILE;
906 goto free; 906 goto free;
907 } 907 }
908 908
909 key.data = &index; 909 key.data = &index;
910 key.len = sizeof(index); 910 key.len = sizeof(index);
911 r = chash_get(folder->fl_msgs_hash, &key, &data); 911 r = chash_get(folder->fl_msgs_hash, &key, &data);
912#if 0 912#if 0
913 msg_info = cinthash_find(folder->fl_msgs_hash, index); 913 msg_info = cinthash_find(folder->fl_msgs_hash, index);
914#endif 914#endif
915 if (r == 0) { 915 if (r == 0) {
916 msg_info = data.data; 916 msg_info = data.data;
917 917
918 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);
919#if 0 919#if 0
920 cinthash_remove(folder->fl_msgs_hash, index); 920 cinthash_remove(folder->fl_msgs_hash, index);
921#endif 921#endif
922 chash_delete(folder->fl_msgs_hash, &key, NULL); 922 chash_delete(folder->fl_msgs_hash, &key, NULL);
923 } 923 }
924 // LR
925 mailmh_msg_info_free( msg_info );
926 free(filename);
924 927
925 return MAILMH_NO_ERROR; 928 return MAILMH_NO_ERROR;
926 929
927 free: 930 free:
928 free(filename); 931 free(filename);
929 err: 932 err:
930 return res; 933 return res;
931} 934}
932 935
933 936
934int mailmh_folder_move_message(struct mailmh_folder * dest_folder, 937int mailmh_folder_move_message(struct mailmh_folder * dest_folder,
935 struct mailmh_folder * src_folder, 938 struct mailmh_folder * src_folder,
936 uint32_t index) 939 uint32_t index)
937{ 940{
938 int fd; 941 int fd;
939 char * filename; 942 char * filename;
940 int r; 943 int r;
941 944
942#if 0 945#if 0
943 r = mailmh_folder_update(dest_folder); 946 r = mailmh_folder_update(dest_folder);
944 if (r != MAILMH_NO_ERROR) 947 if (r != MAILMH_NO_ERROR)
945 return r; 948 return r;
946 r = mailmh_folder_update(src_folder); 949 r = mailmh_folder_update(src_folder);
947 if (r != MAILMH_NO_ERROR) 950 if (r != MAILMH_NO_ERROR)
948 return r; 951 return r;
949#endif 952#endif
950 953
951 /* move on the same filesystem */ 954 /* move on the same filesystem */
952 r = mailmh_folder_get_message_filename(src_folder, index, &filename); 955 r = mailmh_folder_get_message_filename(src_folder, index, &filename);
953 if (r != MAILMH_NO_ERROR) 956 if (r != MAILMH_NO_ERROR)
954 return r; 957 return r;
955 958
956 r = mailmh_folder_alloc_msg(dest_folder, filename, &index); 959 r = mailmh_folder_alloc_msg(dest_folder, filename, &index);
957 free(filename); 960 free(filename);
958 if (r == MAILMH_NO_ERROR) 961 if (r == MAILMH_NO_ERROR)
959 return MAILMH_NO_ERROR; 962 return MAILMH_NO_ERROR;
960 963
961 /* move on the different filesystems */ 964 /* move on the different filesystems */
962 r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd); 965 r = mailmh_folder_get_message_fd(src_folder, index, O_RDONLY, &fd);
963 if (r != MAILMH_NO_ERROR) 966 if (r != MAILMH_NO_ERROR)
964 return r; 967 return r;
965 968
966 r = mailmh_folder_add_message_file(dest_folder, fd); 969 r = mailmh_folder_add_message_file(dest_folder, fd);
967 if (r != MAILMH_NO_ERROR) { 970 if (r != MAILMH_NO_ERROR) {
968 close(fd); 971 close(fd);
969 return r; 972 return r;
970 } 973 }
971 974
972 close(fd); 975 close(fd);
973 976
974 r = mailmh_folder_remove_message(src_folder, index); 977 r = mailmh_folder_remove_message(src_folder, index);
975 978
976 return MAILMH_NO_ERROR; 979 return MAILMH_NO_ERROR;
977} 980}
978 981
979unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder) 982unsigned int mailmh_folder_get_message_number(struct mailmh_folder * folder)
980{ 983{
981 unsigned int i; 984 unsigned int i;
982 unsigned int count; 985 unsigned int count;
983 986
984 count = 0; 987 count = 0;
985 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) 988 for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++)
986 if (carray_get(folder->fl_msgs_tab, i) != NULL) 989 if (carray_get(folder->fl_msgs_tab, i) != NULL)
987 count ++; 990 count ++;
988 991
989 return count; 992 return count;
990} 993}