summaryrefslogtreecommitdiffabout
path: root/kmicromail
Unidiff
Diffstat (limited to 'kmicromail') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/mh/mailmh.c473
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
@@ -159,566 +159,571 @@ struct mailmh_folder * mailmh_folder_new(struct mailmh_folder * parent,
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 } 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
482int mailmh_folder_add_subfolder(struct mailmh_folder * parent, 487int 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
531int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) 536int 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
556int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, 561int 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
603static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, 608static 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
656int mailmh_folder_get_message_filename(struct mailmh_folder * folder, 661int 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
682int mailmh_folder_get_message_fd(struct mailmh_folder * folder, 687int 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
709int mailmh_folder_get_message_size(struct mailmh_folder * folder, 714int 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