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
@@ -271,342 +271,347 @@ struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root,
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;