-rw-r--r-- | kmicromail/libetpan/mh/mailmh.c | 473 |
1 files changed, 239 insertions, 234 deletions
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c index 5e2b4cc..1087ce1 100644 --- a/kmicromail/libetpan/mh/mailmh.c +++ b/kmicromail/libetpan/mh/mailmh.c | |||
@@ -281,322 +281,327 @@ struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, | |||
281 | return data.data; | 281 | return data.data; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | 284 | ||
285 | int mailmh_folder_update(struct mailmh_folder * folder) | 285 | int mailmh_folder_update(struct mailmh_folder * folder) |
286 | { | 286 | { |
287 | DIR * d; | 287 | DIR * d; |
288 | struct dirent * ent; | 288 | struct dirent * ent; |
289 | struct stat buf; | 289 | struct stat buf; |
290 | char * mh_seq; | 290 | char * mh_seq; |
291 | char filename[PATH_MAX]; | 291 | char filename[PATH_MAX]; |
292 | int res; | 292 | int res; |
293 | int r; | 293 | int r; |
294 | uint32_t max_index; | 294 | uint32_t max_index; |
295 | #if 0 | 295 | #if 0 |
296 | int add_folder; | 296 | int add_folder; |
297 | #endif | 297 | #endif |
298 | unsigned int i; | 298 | unsigned int i; |
299 | 299 | ||
300 | if (stat(folder->fl_filename, &buf) == -1) { | 300 | if (stat(folder->fl_filename, &buf) == -1) { |
301 | res = MAILMH_ERROR_FOLDER; | 301 | res = MAILMH_ERROR_FOLDER; |
302 | goto err; | 302 | goto err; |
303 | } | 303 | } |
304 | 304 | ||
305 | if (folder->fl_mtime == buf.st_mtime) { | 305 | if (folder->fl_mtime == buf.st_mtime) { |
306 | res = MAILMH_NO_ERROR; | 306 | res = MAILMH_NO_ERROR; |
307 | goto err; | 307 | goto err; |
308 | } | 308 | } |
309 | 309 | ||
310 | folder->fl_mtime = buf.st_mtime; | 310 | folder->fl_mtime = buf.st_mtime; |
311 | 311 | ||
312 | d = opendir(folder->fl_filename); | 312 | d = opendir(folder->fl_filename); |
313 | if (d == NULL) { | 313 | if (d == NULL) { |
314 | res = MAILMH_ERROR_FOLDER; | 314 | res = MAILMH_ERROR_FOLDER; |
315 | goto err; | 315 | goto err; |
316 | } | 316 | } |
317 | 317 | ||
318 | max_index = 0; | 318 | max_index = 0; |
319 | 319 | ||
320 | #if 0 | 320 | #if 0 |
321 | if (folder->fl_subfolders_tab->len == 0) | 321 | if (folder->fl_subfolders_tab->len == 0) |
322 | add_folder = 1; | 322 | add_folder = 1; |
323 | else | 323 | else |
324 | add_folder = 0; | 324 | add_folder = 0; |
325 | #endif | 325 | #endif |
326 | 326 | ||
327 | /* clear the message list */ | 327 | /* clear the message list */ |
328 | 328 | ||
329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { | 329 | for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { |
330 | struct mailmh_msg_info * msg_info; | 330 | struct mailmh_msg_info * msg_info; |
331 | chashdatum key; | 331 | chashdatum key; |
332 | 332 | ||
333 | msg_info = carray_get(folder->fl_msgs_tab, i); | 333 | msg_info = carray_get(folder->fl_msgs_tab, i); |
334 | if (msg_info == NULL) | 334 | if (msg_info == NULL) |
335 | continue; | 335 | continue; |
336 | 336 | ||
337 | #if 0 | 337 | #if 0 |
338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); | 338 | cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); |
339 | #endif | 339 | #endif |
340 | key.data = &msg_info->msg_index; | 340 | key.data = &msg_info->msg_index; |
341 | key.len = sizeof(msg_info->msg_index); | 341 | key.len = sizeof(msg_info->msg_index); |
342 | chash_delete(folder->fl_msgs_hash, &key, NULL); | 342 | chash_delete(folder->fl_msgs_hash, &key, NULL); |
343 | 343 | ||
344 | mailmh_msg_info_free(msg_info); | 344 | mailmh_msg_info_free(msg_info); |
345 | } | 345 | } |
346 | 346 | ||
347 | carray_set_size(folder->fl_msgs_tab, 0); | 347 | carray_set_size(folder->fl_msgs_tab, 0); |
348 | 348 | ||
349 | do { | 349 | do { |
350 | uint32_t index; | 350 | uint32_t index; |
351 | 351 | ||
352 | ent = readdir(d); | 352 | ent = readdir(d); |
353 | 353 | ||
354 | if (ent != NULL) { | 354 | if (ent != NULL) { |
355 | 355 | ||
356 | snprintf(filename, PATH_MAX, | 356 | snprintf(filename, PATH_MAX, |
357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); | 357 | "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); |
358 | 358 | ||
359 | if (stat(filename, &buf) == -1) | 359 | if (stat(filename, &buf) == -1) |
360 | continue; | 360 | continue; |
361 | 361 | ||
362 | if (S_ISREG(buf.st_mode)) { | 362 | if (S_ISREG(buf.st_mode)) { |
363 | index = strtoul(ent->d_name, NULL, 10); | 363 | index = strtoul(ent->d_name, NULL, 10); |
364 | if (index != 0) { | 364 | if (index != 0) { |
365 | struct mailmh_msg_info * msg_info; | 365 | struct mailmh_msg_info * msg_info; |
366 | unsigned int array_index; | 366 | unsigned int array_index; |
367 | chashdatum key; | 367 | chashdatum key; |
368 | chashdatum data; | 368 | chashdatum data; |
369 | 369 | ||
370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); | 370 | msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); |
371 | if (msg_info == NULL) { | 371 | if (msg_info == NULL) { |
372 | res = MAILMH_ERROR_MEMORY; | 372 | res = MAILMH_ERROR_MEMORY; |
373 | goto closedir; | 373 | goto closedir; |
374 | } | 374 | } |
375 | 375 | ||
376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); | 376 | r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); |
377 | if (r < 0) { | 377 | if (r < 0) { |
378 | mailmh_msg_info_free(msg_info); | 378 | mailmh_msg_info_free(msg_info); |
379 | res = MAILMH_ERROR_MEMORY; | 379 | res = MAILMH_ERROR_MEMORY; |
380 | goto closedir; | 380 | goto closedir; |
381 | } | 381 | } |
382 | msg_info->msg_array_index = array_index; | 382 | msg_info->msg_array_index = array_index; |
383 | 383 | ||
384 | if (index > max_index) | 384 | if (index > max_index) |
385 | max_index = index; | 385 | max_index = index; |
386 | 386 | ||
387 | #if 0 | 387 | #if 0 |
388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); | 388 | r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); |
389 | #endif | 389 | #endif |
390 | key.data = &msg_info->msg_index; | 390 | key.data = &msg_info->msg_index; |
391 | key.len = sizeof(msg_info->msg_index); | 391 | key.len = sizeof(msg_info->msg_index); |
392 | data.data = msg_info; | 392 | data.data = msg_info; |
393 | data.len = 0; | 393 | data.len = 0; |
394 | 394 | ||
395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); | 395 | r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); |
396 | if (r < 0) { | 396 | if (r < 0) { |
397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); | 397 | carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); |
398 | mailmh_msg_info_free(msg_info); | 398 | mailmh_msg_info_free(msg_info); |
399 | res = MAILMH_ERROR_MEMORY; | 399 | res = MAILMH_ERROR_MEMORY; |
400 | goto closedir; | 400 | goto closedir; |
401 | } | 401 | } |
402 | } | 402 | //LR memory leak? added next line |
403 | } | 403 | //mailmh_msg_info_free(msg_info); |
404 | else if (S_ISDIR(buf.st_mode)) { | 404 | //it seems so that it should be freed later, |
405 | struct mailmh_folder * subfolder; | 405 | // but it is not in every case |
406 | unsigned int array_index; | 406 | //PENDING fixme in ompi somewhere |
407 | chashdatum key; | 407 | } |
408 | chashdatum data; | 408 | } |
409 | 409 | else if (S_ISDIR(buf.st_mode)) { | |
410 | if (ent->d_name[0] == '.') { | 410 | struct mailmh_folder * subfolder; |
411 | if (ent->d_name[1] == 0) | 411 | unsigned int array_index; |
412 | continue; | 412 | chashdatum key; |
413 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) | 413 | chashdatum data; |
414 | continue; | 414 | |
415 | } | 415 | if (ent->d_name[0] == '.') { |
416 | 416 | if (ent->d_name[1] == 0) | |
417 | key.data = ent->d_name; | 417 | continue; |
418 | key.len = strlen(ent->d_name); | 418 | if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) |
419 | r = chash_get(folder->fl_subfolders_hash, &key, &data); | 419 | continue; |
420 | if (r < 0) { | 420 | } |
421 | subfolder = mailmh_folder_new(folder, ent->d_name); | 421 | |
422 | if (subfolder == NULL) { | 422 | key.data = ent->d_name; |
423 | res = MAILMH_ERROR_MEMORY; | 423 | key.len = strlen(ent->d_name); |
424 | goto closedir; | 424 | r = chash_get(folder->fl_subfolders_hash, &key, &data); |
425 | } | 425 | if (r < 0) { |
426 | subfolder = mailmh_folder_new(folder, ent->d_name); | ||
427 | if (subfolder == NULL) { | ||
428 | res = MAILMH_ERROR_MEMORY; | ||
429 | goto closedir; | ||
430 | } | ||
426 | 431 | ||
427 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); | 432 | r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); |
428 | if (r < 0) { | 433 | if (r < 0) { |
429 | mailmh_folder_free(subfolder); | 434 | mailmh_folder_free(subfolder); |
430 | res = MAILMH_ERROR_MEMORY; | 435 | res = MAILMH_ERROR_MEMORY; |
431 | goto closedir; | 436 | goto closedir; |
432 | } | 437 | } |
433 | subfolder->fl_array_index = array_index; | 438 | subfolder->fl_array_index = array_index; |
434 | 439 | ||
435 | key.data = subfolder->fl_filename; | 440 | key.data = subfolder->fl_filename; |
436 | key.len = strlen(subfolder->fl_filename); | 441 | key.len = strlen(subfolder->fl_filename); |
437 | data.data = subfolder; | 442 | data.data = subfolder; |
438 | data.len = 0; | 443 | data.len = 0; |
439 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); | 444 | r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); |
440 | if (r < 0) { | 445 | if (r < 0) { |
441 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); | 446 | carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); |
442 | mailmh_folder_free(subfolder); | 447 | mailmh_folder_free(subfolder); |
443 | res = MAILMH_ERROR_MEMORY; | 448 | res = MAILMH_ERROR_MEMORY; |
444 | goto closedir; | 449 | goto closedir; |
445 | } | 450 | } |
446 | } | 451 | } |
447 | } | 452 | } |
453 | } | ||
448 | } | 454 | } |
449 | } | 455 | while (ent != NULL); |
450 | while (ent != NULL); | ||
451 | 456 | ||
452 | folder->fl_max_index = max_index; | 457 | folder->fl_max_index = max_index; |
453 | 458 | ||
454 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); | 459 | mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); |
455 | if (mh_seq == NULL) { | 460 | if (mh_seq == NULL) { |
456 | res = MAILMH_ERROR_MEMORY; | 461 | res = MAILMH_ERROR_MEMORY; |
457 | goto closedir; | 462 | goto closedir; |
458 | } | 463 | } |
459 | strcpy(mh_seq, folder->fl_filename); | 464 | strcpy(mh_seq, folder->fl_filename); |
460 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); | 465 | strcat(mh_seq, MAIL_DIR_SEPARATOR_S); |
461 | strcat(mh_seq, ".mh_sequences"); | 466 | strcat(mh_seq, ".mh_sequences"); |
462 | 467 | ||
463 | if (stat(mh_seq, &buf) == -1) { | 468 | if (stat(mh_seq, &buf) == -1) { |
464 | int fd; | 469 | int fd; |
465 | 470 | ||
466 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); | 471 | fd = creat(mh_seq, S_IRUSR | S_IWUSR); |
467 | if (fd != -1) | 472 | if (fd != -1) |
468 | close(fd); | 473 | close(fd); |
469 | } | 474 | } |
470 | free(mh_seq); | 475 | free(mh_seq); |
471 | 476 | ||
472 | closedir(d); | 477 | closedir(d); |
473 | 478 | ||
474 | return MAILMH_NO_ERROR; | 479 | return MAILMH_NO_ERROR; |
475 | 480 | ||
476 | closedir: | 481 | closedir: |
477 | closedir(d); | 482 | closedir(d); |
478 | err: | 483 | err: |
479 | return res; | 484 | return res; |
480 | } | 485 | } |
481 | 486 | ||
482 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, | 487 | int mailmh_folder_add_subfolder(struct mailmh_folder * parent, |
483 | const char * name) | 488 | const char * name) |
484 | { | 489 | { |
485 | char * foldername; | 490 | char * foldername; |
486 | int r; | 491 | int r; |
487 | struct mailmh_folder * folder; | 492 | struct mailmh_folder * folder; |
488 | unsigned int array_index; | 493 | unsigned int array_index; |
489 | chashdatum key; | 494 | chashdatum key; |
490 | chashdatum data; | 495 | chashdatum data; |
491 | 496 | ||
492 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); | 497 | foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); |
493 | if (foldername == NULL) | 498 | if (foldername == NULL) |
494 | return MAILMH_ERROR_MEMORY; | 499 | return MAILMH_ERROR_MEMORY; |
495 | strcpy(foldername, parent->fl_filename); | 500 | strcpy(foldername, parent->fl_filename); |
496 | strcat(foldername, MAIL_DIR_SEPARATOR_S); | 501 | strcat(foldername, MAIL_DIR_SEPARATOR_S); |
497 | strcat(foldername, name); | 502 | strcat(foldername, name); |
498 | 503 | ||
499 | r = mkdir(foldername, 0700); | 504 | r = mkdir(foldername, 0700); |
500 | free(foldername); | 505 | free(foldername); |
501 | 506 | ||
502 | if (r < 0) | 507 | if (r < 0) |
503 | return MAILMH_ERROR_FOLDER; | 508 | return MAILMH_ERROR_FOLDER; |
504 | 509 | ||
505 | folder = mailmh_folder_new(parent, name); | 510 | folder = mailmh_folder_new(parent, name); |
506 | if (folder == NULL) | 511 | if (folder == NULL) |
507 | return MAILMH_ERROR_MEMORY; | 512 | return MAILMH_ERROR_MEMORY; |
508 | 513 | ||
509 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); | 514 | r = carray_add(parent->fl_subfolders_tab, folder, &array_index); |
510 | if (r < 0) { | 515 | if (r < 0) { |
511 | mailmh_folder_free(folder); | 516 | mailmh_folder_free(folder); |
512 | return MAILMH_ERROR_MEMORY; | 517 | return MAILMH_ERROR_MEMORY; |
513 | } | 518 | } |
514 | folder->fl_array_index = array_index; | 519 | folder->fl_array_index = array_index; |
515 | 520 | ||
516 | key.data = folder->fl_filename; | 521 | key.data = folder->fl_filename; |
517 | key.len = strlen(folder->fl_filename); | 522 | key.len = strlen(folder->fl_filename); |
518 | data.data = folder; | 523 | data.data = folder; |
519 | data.len = 0; | 524 | data.len = 0; |
520 | 525 | ||
521 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); | 526 | r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); |
522 | if (r < 0) { | 527 | if (r < 0) { |
523 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); | 528 | carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); |
524 | mailmh_folder_free(folder); | 529 | mailmh_folder_free(folder); |
525 | return MAILMH_ERROR_MEMORY; | 530 | return MAILMH_ERROR_MEMORY; |
526 | } | 531 | } |
527 | 532 | ||
528 | return MAILMH_NO_ERROR; | 533 | return MAILMH_NO_ERROR; |
529 | } | 534 | } |
530 | 535 | ||
531 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) | 536 | int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) |
532 | { | 537 | { |
533 | struct mailmh_folder * parent; | 538 | struct mailmh_folder * parent; |
534 | chashdatum key; | 539 | chashdatum key; |
535 | chashdatum data; | 540 | chashdatum data; |
536 | int r; | 541 | int r; |
537 | 542 | ||
538 | parent = folder->fl_parent; | 543 | parent = folder->fl_parent; |
539 | 544 | ||
540 | key.data = folder->fl_filename; | 545 | key.data = folder->fl_filename; |
541 | key.len = strlen(folder->fl_filename); | 546 | key.len = strlen(folder->fl_filename); |
542 | 547 | ||
543 | r = chash_get(parent->fl_subfolders_hash, &key, &data); | 548 | r = chash_get(parent->fl_subfolders_hash, &key, &data); |
544 | if (r < 0) | 549 | if (r < 0) |
545 | return MAILMH_ERROR_FOLDER; | 550 | return MAILMH_ERROR_FOLDER; |
546 | 551 | ||
547 | chash_delete(parent->fl_subfolders_hash, &key, NULL); | 552 | chash_delete(parent->fl_subfolders_hash, &key, NULL); |
548 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); | 553 | carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); |
549 | 554 | ||
550 | mailmh_folder_free(folder); | 555 | mailmh_folder_free(folder); |
551 | 556 | ||
552 | return MAILMH_NO_ERROR; | 557 | return MAILMH_NO_ERROR; |
553 | 558 | ||
554 | } | 559 | } |
555 | 560 | ||
556 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, | 561 | int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, |
557 | struct mailmh_folder * dst_folder, | 562 | struct mailmh_folder * dst_folder, |
558 | const char * new_name) | 563 | const char * new_name) |
559 | { | 564 | { |
560 | int r; | 565 | int r; |
561 | struct mailmh_folder * folder; | 566 | struct mailmh_folder * folder; |
562 | struct mailmh_folder * parent; | 567 | struct mailmh_folder * parent; |
563 | char * new_foldername; | 568 | char * new_foldername; |
564 | 569 | ||
565 | parent = src_folder->fl_parent; | 570 | parent = src_folder->fl_parent; |
566 | if (parent == NULL) | 571 | if (parent == NULL) |
567 | return MAILMH_ERROR_RENAME; | 572 | return MAILMH_ERROR_RENAME; |
568 | 573 | ||
569 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); | 574 | new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); |
570 | if (new_foldername == NULL) | 575 | if (new_foldername == NULL) |
571 | return MAILMH_ERROR_MEMORY; | 576 | return MAILMH_ERROR_MEMORY; |
572 | 577 | ||
573 | strcpy(new_foldername, dst_folder->fl_filename); | 578 | strcpy(new_foldername, dst_folder->fl_filename); |
574 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); | 579 | strcat(new_foldername, MAIL_DIR_SEPARATOR_S); |
575 | strcat(new_foldername, new_name); | 580 | strcat(new_foldername, new_name); |
576 | 581 | ||
577 | r = rename(src_folder->fl_filename, new_foldername); | 582 | r = rename(src_folder->fl_filename, new_foldername); |
578 | free(new_foldername); | 583 | free(new_foldername); |
579 | if (r < 0) | 584 | if (r < 0) |
580 | return MAILMH_ERROR_RENAME; | 585 | return MAILMH_ERROR_RENAME; |
581 | 586 | ||
582 | r = mailmh_folder_remove_subfolder(src_folder); | 587 | r = mailmh_folder_remove_subfolder(src_folder); |
583 | if (r != MAILMH_NO_ERROR) | 588 | if (r != MAILMH_NO_ERROR) |
584 | return r; | 589 | return r; |
585 | 590 | ||
586 | folder = mailmh_folder_new(dst_folder, new_name); | 591 | folder = mailmh_folder_new(dst_folder, new_name); |
587 | if (folder == NULL) | 592 | if (folder == NULL) |
588 | return MAILMH_ERROR_MEMORY; | 593 | return MAILMH_ERROR_MEMORY; |
589 | 594 | ||
590 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); | 595 | r = carray_add(parent->fl_subfolders_tab, folder, NULL); |
591 | if (r < 0) { | 596 | if (r < 0) { |
592 | mailmh_folder_free(folder); | 597 | mailmh_folder_free(folder); |
593 | return MAILMH_ERROR_MEMORY; | 598 | return MAILMH_ERROR_MEMORY; |
594 | } | 599 | } |
595 | 600 | ||
596 | return MAILMH_NO_ERROR; | 601 | return MAILMH_NO_ERROR; |
597 | } | 602 | } |
598 | 603 | ||
599 | #define MAX_TRY_ALLOC 32 | 604 | #define MAX_TRY_ALLOC 32 |
600 | 605 | ||
601 | /* initial file MUST be in the same directory */ | 606 | /* initial file MUST be in the same directory */ |
602 | 607 | ||