summaryrefslogtreecommitdiffabout
path: root/kmicromail
Unidiff
Diffstat (limited to 'kmicromail') (more/less context) (ignore whitespace changes)
-rw-r--r--kmicromail/libetpan/maildir/maildir.c25
-rw-r--r--kmicromail/libetpan/mh/mailmh.c12
2 files changed, 26 insertions, 11 deletions
diff --git a/kmicromail/libetpan/maildir/maildir.c b/kmicromail/libetpan/maildir/maildir.c
index 0e038b1..1ef0b7a 100644
--- a/kmicromail/libetpan/maildir/maildir.c
+++ b/kmicromail/libetpan/maildir/maildir.c
@@ -63,115 +63,120 @@ struct maildir * maildir_new(const char * path)
63 63
64 md->mdir_counter = 0; 64 md->mdir_counter = 0;
65 md->mdir_mtime_new = (time_t) -1; 65 md->mdir_mtime_new = (time_t) -1;
66 md->mdir_mtime_cur = (time_t) -1; 66 md->mdir_mtime_cur = (time_t) -1;
67 67
68 md->mdir_pid = getpid(); 68 md->mdir_pid = getpid();
69 gethostname(md->mdir_hostname, sizeof(md->mdir_hostname)); 69 gethostname(md->mdir_hostname, sizeof(md->mdir_hostname));
70 strncpy(md->mdir_path, path, sizeof(md->mdir_path)); 70 strncpy(md->mdir_path, path, sizeof(md->mdir_path));
71 md->mdir_path[PATH_MAX - 1] = '\0'; 71 md->mdir_path[PATH_MAX - 1] = '\0';
72 72
73 md->mdir_msg_list = carray_new(128); 73 md->mdir_msg_list = carray_new(128);
74 if (md->mdir_msg_list == NULL) 74 if (md->mdir_msg_list == NULL)
75 goto free; 75 goto free;
76 76
77 md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE); 77 md->mdir_msg_hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYNONE);
78 if (md->mdir_msg_hash == NULL) 78 if (md->mdir_msg_hash == NULL)
79 goto free_msg_list; 79 goto free_msg_list;
80 80
81 return md; 81 return md;
82 82
83 free_msg_list: 83 free_msg_list:
84 carray_free(md->mdir_msg_list); 84 carray_free(md->mdir_msg_list);
85 free: 85 free:
86 free(md); 86 free(md);
87 err: 87 err:
88 return NULL; 88 return NULL;
89} 89}
90 90
91static void maildir_flush(struct maildir * md, int msg_new); 91static void maildir_flush(struct maildir * md, int msg_new);
92 92
93void maildir_free(struct maildir * md) 93void maildir_free(struct maildir * md)
94{ 94{
95 maildir_flush(md, 0); 95 maildir_flush(md, 0);
96 maildir_flush(md, 1); 96 maildir_flush(md, 1);
97 chash_free(md->mdir_msg_hash); 97 chash_free(md->mdir_msg_hash);
98 carray_free(md->mdir_msg_list); 98 carray_free(md->mdir_msg_list);
99 free(md); 99 free(md);
100} 100}
101 101
102#define MAX_TRY_ALLOC 32 102#define MAX_TRY_ALLOC 32
103 103
104static char * maildir_get_new_message_filename(struct maildir * md, 104static char * maildir_get_new_message_filename(struct maildir * md,
105 char * tmpfile) 105 char * tmpfile)
106{ 106{
107 char filename[PATH_MAX]; 107 char filename[PATH_MAX];
108 char basename[PATH_MAX]; 108 char basename[PATH_MAX];
109 int k; 109 int k;
110 time_t now; 110 time_t now;
111 111 struct stat f_stat;
112 now = time(NULL); 112 now = time(NULL);
113 k = 0; 113 k = 0;
114
115 fprintf(stderr,"maildir_get_new_message_filename: %s \n", tmpfile);
114 while (k < MAX_TRY_ALLOC) { 116 while (k < MAX_TRY_ALLOC) {
115 snprintf(basename, sizeof(basename), "%lu.%u_%u.%s", 117 snprintf(basename, sizeof(basename), "%lu.%u_%u.%s",
116 (unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname); 118 (unsigned long) now, md->mdir_pid, md->mdir_counter, md->mdir_hostname);
117 snprintf(filename, sizeof(filename), "%s/tmp/%s", 119 snprintf(filename, sizeof(filename), "%s/tmp/%s",
118 md->mdir_path, basename); 120 md->mdir_path, basename);
119 121 fprintf(stderr,"filename %s \n", filename);
120 if (link(tmpfile, filename) == 0) { 122 // LR changed following lines
123 if ( stat( filename, &f_stat ) == -1 ) {
124 //if (link(tmpfile, filename) == 0) {
121 char * dup_filename; 125 char * dup_filename;
122 126
123 dup_filename = strdup(filename); 127 dup_filename = strdup(filename);
124 if (dup_filename == NULL) { 128 if (dup_filename == NULL) {
125 unlink(filename); 129 //unlink(filename);
126 return NULL; 130 return NULL;
127 } 131 }
128 132 fprintf(stderr,"filename %s %s \n", tmpfile,dup_filename);
129 unlink(tmpfile); 133 //unlink(tmpfile);
134 rename (tmpfile,dup_filename );
130 md->mdir_counter ++; 135 md->mdir_counter ++;
131 136
132 return dup_filename; 137 return dup_filename;
133 } 138 }
134 139
135 md->mdir_counter ++; 140 md->mdir_counter ++;
136 k ++; 141 k ++;
137 } 142 }
138 143
139 return NULL; 144 return NULL;
140} 145}
141 146
142 147
143static void msg_free(struct maildir_msg * msg) 148static void msg_free(struct maildir_msg * msg)
144{ 149{
145 free(msg->msg_uid); 150 free(msg->msg_uid);
146 free(msg->msg_filename); 151 free(msg->msg_filename);
147 free(msg); 152 free(msg);
148} 153}
149 154
150/* 155/*
151 msg_new() 156 msg_new()
152 157
153 filename is given without path 158 filename is given without path
154*/ 159*/
155 160
156static struct maildir_msg * msg_new(char * filename, int new_msg) 161static struct maildir_msg * msg_new(char * filename, int new_msg)
157{ 162{
158 struct maildir_msg * msg; 163 struct maildir_msg * msg;
159 char * p; 164 char * p;
160 int flags; 165 int flags;
161 size_t uid_len; 166 size_t uid_len;
162 char * begin_uid; 167 char * begin_uid;
163 168
164 /* name of file : xxx-xxx_xxx-xxx:2,SRFT */ 169 /* name of file : xxx-xxx_xxx-xxx:2,SRFT */
165 170
166 msg = malloc(sizeof(* msg)); 171 msg = malloc(sizeof(* msg));
167 if (msg == NULL) 172 if (msg == NULL)
168 goto err; 173 goto err;
169 174
170 msg->msg_filename = strdup(filename); 175 msg->msg_filename = strdup(filename);
171 if (msg->msg_filename == NULL) 176 if (msg->msg_filename == NULL)
172 goto free; 177 goto free;
173 178
174 begin_uid = filename; 179 begin_uid = filename;
175 180
176 uid_len = strlen(begin_uid); 181 uid_len = strlen(begin_uid);
177 182
@@ -227,96 +232,97 @@ static struct maildir_msg * msg_new(char * filename, int new_msg)
227static void maildir_flush(struct maildir * md, int msg_new) 232static void maildir_flush(struct maildir * md, int msg_new)
228{ 233{
229 unsigned int i; 234 unsigned int i;
230 235
231 i = 0; 236 i = 0;
232 while (i < carray_count(md->mdir_msg_list)) { 237 while (i < carray_count(md->mdir_msg_list)) {
233 struct maildir_msg * msg; 238 struct maildir_msg * msg;
234 int delete; 239 int delete;
235 240
236 msg = carray_get(md->mdir_msg_list, i); 241 msg = carray_get(md->mdir_msg_list, i);
237 242
238 if (msg_new) { 243 if (msg_new) {
239 delete = 0; 244 delete = 0;
240 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 245 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
241 delete = 1; 246 delete = 1;
242 } 247 }
243 else { 248 else {
244 delete = 1; 249 delete = 1;
245 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 250 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
246 delete = 0; 251 delete = 0;
247 } 252 }
248 253
249 if (delete) { 254 if (delete) {
250 chashdatum key; 255 chashdatum key;
251 256
252 key.data = msg->msg_uid; 257 key.data = msg->msg_uid;
253 key.len = strlen(msg->msg_uid); 258 key.len = strlen(msg->msg_uid);
254 chash_delete(md->mdir_msg_hash, &key, NULL); 259 chash_delete(md->mdir_msg_hash, &key, NULL);
255 260
256 carray_delete(md->mdir_msg_list, i); 261 carray_delete(md->mdir_msg_list, i);
257 msg_free(msg); 262 msg_free(msg);
258 } 263 }
259 else { 264 else {
260 i ++; 265 i ++;
261 } 266 }
262 } 267 }
263} 268}
264 269
265static int add_message(struct maildir * md, 270static int add_message(struct maildir * md,
266 char * filename, int is_new) 271 char * filename, int is_new)
267{ 272{
268 struct maildir_msg * msg; 273 struct maildir_msg * msg;
269 chashdatum key; 274 chashdatum key;
270 chashdatum value; 275 chashdatum value;
271 unsigned int i; 276 unsigned int i;
272 int res; 277 int res;
273 int r; 278 int r;
274 279
280 fprintf(stderr,"add_message filename: %s \n", filename);
275 msg = msg_new(filename, is_new); 281 msg = msg_new(filename, is_new);
276 if (msg == NULL) { 282 if (msg == NULL) {
277 res = MAILDIR_ERROR_MEMORY; 283 res = MAILDIR_ERROR_MEMORY;
278 goto err; 284 goto err;
279 } 285 }
280 286
281 r = carray_add(md->mdir_msg_list, msg, &i); 287 r = carray_add(md->mdir_msg_list, msg, &i);
282 if (r < 0) { 288 if (r < 0) {
283 res = MAILDIR_ERROR_MEMORY; 289 res = MAILDIR_ERROR_MEMORY;
284 goto free_msg; 290 goto free_msg;
285 } 291 }
286 292
287 key.data = msg->msg_uid; 293 key.data = msg->msg_uid;
288 key.len = strlen(msg->msg_uid); 294 key.len = strlen(msg->msg_uid);
289 value.data = msg; 295 value.data = msg;
290 value.len = 0; 296 value.len = 0;
291 297
292 r = chash_set(md->mdir_msg_hash, &key, &value, NULL); 298 r = chash_set(md->mdir_msg_hash, &key, &value, NULL);
293 if (r < 0) { 299 if (r < 0) {
294 res = MAILDIR_ERROR_MEMORY; 300 res = MAILDIR_ERROR_MEMORY;
295 goto delete; 301 goto delete;
296 } 302 }
297 303
298 return MAILDIR_NO_ERROR; 304 return MAILDIR_NO_ERROR;
299 305
300 delete: 306 delete:
301 carray_delete(md->mdir_msg_list, i); 307 carray_delete(md->mdir_msg_list, i);
302 free_msg: 308 free_msg:
303 msg_free(msg); 309 msg_free(msg);
304 err: 310 err:
305 return res; 311 return res;
306} 312}
307 313
308static int add_directory(struct maildir * md, char * path, int is_new) 314static int add_directory(struct maildir * md, char * path, int is_new)
309{ 315{
310 DIR * d; 316 DIR * d;
311 struct dirent * entry; 317 struct dirent * entry;
312 int res; 318 int res;
313 int r; 319 int r;
314 char filename[PATH_MAX]; 320 char filename[PATH_MAX];
315 321
316 d = opendir(path); 322 d = opendir(path);
317 if (d == NULL) { 323 if (d == NULL) {
318 res = MAILDIR_ERROR_DIRECTORY; 324 res = MAILDIR_ERROR_DIRECTORY;
319 goto err; 325 goto err;
320 } 326 }
321 327
322 while ((entry = readdir(d)) != NULL) { 328 while ((entry = readdir(d)) != NULL) {
@@ -401,96 +407,97 @@ int maildir_update(struct maildir * md)
401 407
402 free: 408 free:
403 maildir_flush(md, 0); 409 maildir_flush(md, 0);
404 maildir_flush(md, 1); 410 maildir_flush(md, 1);
405 md->mdir_mtime_cur = (time_t) -1; 411 md->mdir_mtime_cur = (time_t) -1;
406 md->mdir_mtime_new = (time_t) -1; 412 md->mdir_mtime_new = (time_t) -1;
407 return res; 413 return res;
408} 414}
409 415
410#ifndef LIBETPAN_SYSTEM_BASENAME 416#ifndef LIBETPAN_SYSTEM_BASENAME
411static char * libetpan_basename(char * filename) 417static char * libetpan_basename(char * filename)
412{ 418{
413 char * next; 419 char * next;
414 char * p; 420 char * p;
415 421
416 p = filename; 422 p = filename;
417 next = strchr(p, '/'); 423 next = strchr(p, '/');
418 424
419 while (next != NULL) { 425 while (next != NULL) {
420 p = next; 426 p = next;
421 next = strchr(p + 1, '/'); 427 next = strchr(p + 1, '/');
422 } 428 }
423 429
424 if (p == filename) 430 if (p == filename)
425 return filename; 431 return filename;
426 else 432 else
427 return p + 1; 433 return p + 1;
428} 434}
429#else 435#else
430#define libetpan_basename(a) basename(a) 436#define libetpan_basename(a) basename(a)
431#endif 437#endif
432 438
433int maildir_message_add_uid(struct maildir * md, 439int maildir_message_add_uid(struct maildir * md,
434 const char * message, size_t size, 440 const char * message, size_t size,
435 char * uid, size_t max_uid_len) 441 char * uid, size_t max_uid_len)
436{ 442{
437 char path_new[PATH_MAX]; 443 char path_new[PATH_MAX];
438 char tmpname[PATH_MAX]; 444 char tmpname[PATH_MAX];
439 int fd; 445 int fd;
440 int r; 446 int r;
441 char * mapping; 447 char * mapping;
442 char * delivery_tmp_name; 448 char * delivery_tmp_name;
443 char * delivery_tmp_basename; 449 char * delivery_tmp_basename;
444 char delivery_new_name[PATH_MAX]; 450 char delivery_new_name[PATH_MAX];
445 char * delivery_new_basename; 451 char * delivery_new_basename;
446 int res; 452 int res;
447 struct stat stat_info; 453 struct stat stat_info;
448 454
455 fprintf(stderr,"maildir_message_add_uid for uid: %s \n", uid);
449 r = maildir_update(md); 456 r = maildir_update(md);
450 if (r != MAILDIR_NO_ERROR) { 457 if (r != MAILDIR_NO_ERROR) {
451 res = r; 458 res = r;
452 goto err; 459 goto err;
453 } 460 }
454 461
455 /* write to tmp/ with a classic temporary file */ 462 /* write to tmp/ with a classic temporary file */
456 463
457 snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX", 464 snprintf(tmpname, sizeof(tmpname), "%s/tmp/etpan-maildir-XXXXXX",
458 md->mdir_path); 465 md->mdir_path);
459 fd = mkstemp(tmpname); 466 fd = mkstemp(tmpname);
460 if (fd < 0) { 467 if (fd < 0) {
461 res = MAILDIR_ERROR_FILE; 468 res = MAILDIR_ERROR_FILE;
462 goto err; 469 goto err;
463 } 470 }
464 471
465 r = ftruncate(fd, size); 472 r = ftruncate(fd, size);
466 if (r < 0) { 473 if (r < 0) {
467 res = MAILDIR_ERROR_FILE; 474 res = MAILDIR_ERROR_FILE;
468 goto close; 475 goto close;
469 } 476 }
470 477
471 mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 478 mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
472 if (mapping == MAP_FAILED) { 479 if (mapping == MAP_FAILED) {
473 res = MAILDIR_ERROR_FILE; 480 res = MAILDIR_ERROR_FILE;
474 goto close; 481 goto close;
475 } 482 }
476 483
477 memcpy(mapping, message, size); 484 memcpy(mapping, message, size);
478 485
479 msync(mapping, size, MS_SYNC); 486 msync(mapping, size, MS_SYNC);
480 munmap(mapping, size); 487 munmap(mapping, size);
481 488
482 close(fd); 489 close(fd);
483 490
484 /* write to tmp/ with maildir standard name */ 491 /* write to tmp/ with maildir standard name */
485 492
486 delivery_tmp_name = maildir_get_new_message_filename(md, tmpname); 493 delivery_tmp_name = maildir_get_new_message_filename(md, tmpname);
487 if (delivery_tmp_name == NULL) { 494 if (delivery_tmp_name == NULL) {
488 res = MAILDIR_ERROR_FILE; 495 res = MAILDIR_ERROR_FILE;
489 goto unlink; 496 goto unlink;
490 } 497 }
491 498
492 /* write to new/ with maildir standard name */ 499 /* write to new/ with maildir standard name */
493 500
494 strncpy(tmpname, delivery_tmp_name, sizeof(tmpname)); 501 strncpy(tmpname, delivery_tmp_name, sizeof(tmpname));
495 tmpname[sizeof(tmpname) - 1] = '\0'; 502 tmpname[sizeof(tmpname) - 1] = '\0';
496 503
@@ -513,201 +520,205 @@ int maildir_message_add_uid(struct maildir * md,
513 goto unlink_tmp; 520 goto unlink_tmp;
514 } 521 }
515 522
516 md->mdir_mtime_new = stat_info.st_mtime; 523 md->mdir_mtime_new = stat_info.st_mtime;
517 524
518 delivery_new_basename = libetpan_basename(delivery_new_name); 525 delivery_new_basename = libetpan_basename(delivery_new_name);
519 526
520 r = add_message(md, delivery_new_basename, 1); 527 r = add_message(md, delivery_new_basename, 1);
521 if (r != MAILDIR_NO_ERROR) { 528 if (r != MAILDIR_NO_ERROR) {
522 unlink(delivery_new_name); 529 unlink(delivery_new_name);
523 res = MAILDIR_ERROR_FILE; 530 res = MAILDIR_ERROR_FILE;
524 goto unlink_tmp; 531 goto unlink_tmp;
525 } 532 }
526 533
527 if (uid != NULL) 534 if (uid != NULL)
528 strncpy(uid, delivery_new_basename, max_uid_len); 535 strncpy(uid, delivery_new_basename, max_uid_len);
529 536
530 unlink(delivery_tmp_name); 537 unlink(delivery_tmp_name);
531 free(delivery_tmp_name); 538 free(delivery_tmp_name);
532 539
533 return MAILDIR_NO_ERROR; 540 return MAILDIR_NO_ERROR;
534 541
535 unlink_tmp: 542 unlink_tmp:
536 unlink(delivery_tmp_name); 543 unlink(delivery_tmp_name);
537 free(delivery_tmp_name); 544 free(delivery_tmp_name);
538 goto err; 545 goto err;
539 close: 546 close:
540 close(fd); 547 close(fd);
541 unlink: 548 unlink:
542 unlink(tmpname); 549 unlink(tmpname);
543 err: 550 err:
544 return res; 551 return res;
545} 552}
546 553
547int maildir_message_add(struct maildir * md, 554int maildir_message_add(struct maildir * md,
548 const char * message, size_t size) 555 const char * message, size_t size)
549{ 556{
550 return maildir_message_add_uid(md, message, size, 557 return maildir_message_add_uid(md, message, size,
551 NULL, 0); 558 NULL, 0);
552} 559}
553 560
554int maildir_message_add_file_uid(struct maildir * md, int fd, 561int maildir_message_add_file_uid(struct maildir * md, int fd,
555 char * uid, size_t max_uid_len) 562 char * uid, size_t max_uid_len)
556{ 563{
557 char * message; 564 char * message;
558 struct stat buf; 565 struct stat buf;
559 int r; 566 int r;
560 567
568 fprintf(stderr,"maildir_message_add_file_uid: %s \n", uid);
561 if (fstat(fd, &buf) == -1) 569 if (fstat(fd, &buf) == -1)
562 return MAILDIR_ERROR_FILE; 570 return MAILDIR_ERROR_FILE;
563 571
564 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 572 message = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
565 if (message == MAP_FAILED) 573 if (message == MAP_FAILED)
566 return MAILDIR_ERROR_FILE; 574 return MAILDIR_ERROR_FILE;
567 575
568 r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len); 576 r = maildir_message_add_uid(md, message, buf.st_size, uid, max_uid_len);
569 577
570 munmap(message, buf.st_size); 578 munmap(message, buf.st_size);
571 579
572 return r; 580 return r;
573} 581}
574 582
575int maildir_message_add_file(struct maildir * md, int fd) 583int maildir_message_add_file(struct maildir * md, int fd)
576{ 584{
585 fprintf(stderr,"maildir_message_add_file \n");
577 return maildir_message_add_file_uid(md, fd, 586 return maildir_message_add_file_uid(md, fd,
578 NULL, 0); 587 NULL, 0);
579} 588}
580 589
581char * maildir_message_get(struct maildir * md, const char * uid) 590char * maildir_message_get(struct maildir * md, const char * uid)
582{ 591{
583 chashdatum key; 592 chashdatum key;
584 chashdatum value; 593 chashdatum value;
585 char filename[PATH_MAX]; 594 char filename[PATH_MAX];
586 char * dup_filename; 595 char * dup_filename;
587 struct maildir_msg * msg; 596 struct maildir_msg * msg;
588 char * dir; 597 char * dir;
589 int r; 598 int r;
590 599
600 fprintf(stderr,"maildir_message_get for uid: %s \n", uid);
591 key.data = (void *) uid; 601 key.data = (void *) uid;
592 key.len = strlen(uid); 602 key.len = strlen(uid);
593 r = chash_get(md->mdir_msg_hash, &key, &value); 603 r = chash_get(md->mdir_msg_hash, &key, &value);
594 if (r < 0) 604 if (r < 0)
595 return NULL; 605 return NULL;
596 606
597 msg = value.data; 607 msg = value.data;
598 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 608 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
599 dir = "new"; 609 dir = "new";
600 else 610 else
601 dir = "cur"; 611 dir = "cur";
602 612
603 snprintf(filename, sizeof(filename), "%s/%s/%s", 613 snprintf(filename, sizeof(filename), "%s/%s/%s",
604 md->mdir_path, dir, msg->msg_filename); 614 md->mdir_path, dir, msg->msg_filename);
605 615
606 dup_filename = strdup(filename); 616 dup_filename = strdup(filename);
607 if (dup_filename == NULL) 617 if (dup_filename == NULL)
608 return NULL; 618 return NULL;
609 619
610 return dup_filename; 620 return dup_filename;
611} 621}
612 622
613int maildir_message_remove(struct maildir * md, const char * uid) 623int maildir_message_remove(struct maildir * md, const char * uid)
614{ 624{
615 chashdatum key; 625 chashdatum key;
616 chashdatum value; 626 chashdatum value;
617 char filename[PATH_MAX]; 627 char filename[PATH_MAX];
618 struct maildir_msg * msg; 628 struct maildir_msg * msg;
619 char * dir; 629 char * dir;
620 int r; 630 int r;
621 int res; 631 int res;
622 632
633 fprintf(stderr,"maildir_message_remove for uid: %s \n", uid);
623 key.data = (void *) uid; 634 key.data = (void *) uid;
624 key.len = strlen(uid); 635 key.len = strlen(uid);
625 r = chash_get(md->mdir_msg_hash, &key, &value); 636 r = chash_get(md->mdir_msg_hash, &key, &value);
626 if (r < 0) { 637 if (r < 0) {
627 res = MAILDIR_ERROR_NOT_FOUND; 638 res = MAILDIR_ERROR_NOT_FOUND;
628 goto err; 639 goto err;
629 } 640 }
630 641
631 msg = value.data; 642 msg = value.data;
632 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 643 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
633 dir = "new"; 644 dir = "new";
634 else 645 else
635 dir = "cur"; 646 dir = "cur";
636 647
637 snprintf(filename, sizeof(filename), "%s/%s/%s", 648 snprintf(filename, sizeof(filename), "%s/%s/%s",
638 md->mdir_path, dir, msg->msg_filename); 649 md->mdir_path, dir, msg->msg_filename);
639 650
640 r = unlink(filename); 651 r = unlink(filename);
641 if (r < 0) { 652 if (r < 0) {
642 res = MAILDIR_ERROR_FILE; 653 res = MAILDIR_ERROR_FILE;
643 goto err; 654 goto err;
644 } 655 }
645 656
646 return MAILDIR_NO_ERROR; 657 return MAILDIR_NO_ERROR;
647 658
648 err: 659 err:
649 return res; 660 return res;
650} 661}
651 662
652int maildir_message_change_flags(struct maildir * md, 663int maildir_message_change_flags(struct maildir * md,
653 const char * uid, int new_flags) 664 const char * uid, int new_flags)
654{ 665{
655 chashdatum key; 666 chashdatum key;
656 chashdatum value; 667 chashdatum value;
657 char filename[PATH_MAX]; 668 char filename[PATH_MAX];
658 struct maildir_msg * msg; 669 struct maildir_msg * msg;
659 char * dir; 670 char * dir;
660 int r; 671 int r;
661 char new_filename[PATH_MAX]; 672 char new_filename[PATH_MAX];
662 char flag_str[5]; 673 char flag_str[5];
663 size_t i; 674 size_t i;
664 int res; 675 int res;
665 676 fprintf(stderr,"maildir_message_change_flags for uid: %s \n", uid);
666 key.data = (void *) uid; 677 key.data = (void *) uid;
667 key.len = strlen(uid); 678 key.len = strlen(uid);
668 r = chash_get(md->mdir_msg_hash, &key, &value); 679 r = chash_get(md->mdir_msg_hash, &key, &value);
669 if (r < 0) { 680 if (r < 0) {
670 res = MAILDIR_ERROR_NOT_FOUND; 681 res = MAILDIR_ERROR_NOT_FOUND;
671 goto err; 682 goto err;
672 } 683 }
673 684
674 msg = value.data; 685 msg = value.data;
675 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0) 686 if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
676 dir = "new"; 687 dir = "new";
677 else 688 else
678 dir = "cur"; 689 dir = "cur";
679 690
680 snprintf(filename, sizeof(filename), "%s/%s/%s", 691 snprintf(filename, sizeof(filename), "%s/%s/%s",
681 md->mdir_path, dir, msg->msg_filename); 692 md->mdir_path, dir, msg->msg_filename);
682 693
683 if ((new_flags & MAILDIR_FLAG_NEW) != 0) 694 if ((new_flags & MAILDIR_FLAG_NEW) != 0)
684 dir = "new"; 695 dir = "new";
685 else 696 else
686 dir = "cur"; 697 dir = "cur";
687 698
688 i = 0; 699 i = 0;
689 if ((new_flags & MAILDIR_FLAG_SEEN) != 0) { 700 if ((new_flags & MAILDIR_FLAG_SEEN) != 0) {
690 flag_str[i] = 'S'; 701 flag_str[i] = 'S';
691 i ++; 702 i ++;
692 } 703 }
693 if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) { 704 if ((new_flags & MAILDIR_FLAG_REPLIED) != 0) {
694 flag_str[i] = 'R'; 705 flag_str[i] = 'R';
695 i ++; 706 i ++;
696 } 707 }
697 if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) { 708 if ((new_flags & MAILDIR_FLAG_FLAGGED) != 0) {
698 flag_str[i] = 'F'; 709 flag_str[i] = 'F';
699 i ++; 710 i ++;
700 } 711 }
701 if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) { 712 if ((new_flags & MAILDIR_FLAG_TRASHED) != 0) {
702 flag_str[i] = 'T'; 713 flag_str[i] = 'T';
703 i ++; 714 i ++;
704 } 715 }
705 flag_str[i] = 0; 716 flag_str[i] = 0;
706 717
707 if (flag_str[0] == '\0') 718 if (flag_str[0] == '\0')
708 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s", 719 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s",
709 md->mdir_path, dir, msg->msg_uid); 720 md->mdir_path, dir, msg->msg_uid);
710 else 721 else
711 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s", 722 snprintf(new_filename, sizeof(new_filename), "%s/%s/%s:2,%s",
712 md->mdir_path, dir, msg->msg_uid, flag_str); 723 md->mdir_path, dir, msg->msg_uid, flag_str);
713 724
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c
index 119f217..5e2b4cc 100644
--- a/kmicromail/libetpan/mh/mailmh.c
+++ b/kmicromail/libetpan/mh/mailmh.c
@@ -562,114 +562,118 @@ int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder,
562 struct mailmh_folder * parent; 562 struct mailmh_folder * parent;
563 char * new_foldername; 563 char * new_foldername;
564 564
565 parent = src_folder->fl_parent; 565 parent = src_folder->fl_parent;
566 if (parent == NULL) 566 if (parent == NULL)
567 return MAILMH_ERROR_RENAME; 567 return MAILMH_ERROR_RENAME;
568 568
569 new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); 569 new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name));
570 if (new_foldername == NULL) 570 if (new_foldername == NULL)
571 return MAILMH_ERROR_MEMORY; 571 return MAILMH_ERROR_MEMORY;
572 572
573 strcpy(new_foldername, dst_folder->fl_filename); 573 strcpy(new_foldername, dst_folder->fl_filename);
574 strcat(new_foldername, MAIL_DIR_SEPARATOR_S); 574 strcat(new_foldername, MAIL_DIR_SEPARATOR_S);
575 strcat(new_foldername, new_name); 575 strcat(new_foldername, new_name);
576 576
577 r = rename(src_folder->fl_filename, new_foldername); 577 r = rename(src_folder->fl_filename, new_foldername);
578 free(new_foldername); 578 free(new_foldername);
579 if (r < 0) 579 if (r < 0)
580 return MAILMH_ERROR_RENAME; 580 return MAILMH_ERROR_RENAME;
581 581
582 r = mailmh_folder_remove_subfolder(src_folder); 582 r = mailmh_folder_remove_subfolder(src_folder);
583 if (r != MAILMH_NO_ERROR) 583 if (r != MAILMH_NO_ERROR)
584 return r; 584 return r;
585 585
586 folder = mailmh_folder_new(dst_folder, new_name); 586 folder = mailmh_folder_new(dst_folder, new_name);
587 if (folder == NULL) 587 if (folder == NULL)
588 return MAILMH_ERROR_MEMORY; 588 return MAILMH_ERROR_MEMORY;
589 589
590 r = carray_add(parent->fl_subfolders_tab, folder, NULL); 590 r = carray_add(parent->fl_subfolders_tab, folder, NULL);
591 if (r < 0) { 591 if (r < 0) {
592 mailmh_folder_free(folder); 592 mailmh_folder_free(folder);
593 return MAILMH_ERROR_MEMORY; 593 return MAILMH_ERROR_MEMORY;
594 } 594 }
595 595
596 return MAILMH_NO_ERROR; 596 return MAILMH_NO_ERROR;
597} 597}
598 598
599#define MAX_TRY_ALLOC 32 599#define MAX_TRY_ALLOC 32
600 600
601/* initial file MUST be in the same directory */ 601/* initial file MUST be in the same directory */
602 602
603static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, 603static int mailmh_folder_alloc_msg(struct mailmh_folder * folder,
604 char * filename, uint32_t * result) 604 char * filename, uint32_t * result)
605{ 605{
606 uint32_t max; 606 uint32_t max;
607 uint32_t k; 607 uint32_t k;
608 char * new_filename; 608 char * new_filename;
609 size_t len; 609 size_t len;
610 struct stat f_stat;
610 611
611 len = strlen(folder->fl_filename) + 20; 612 len = strlen(folder->fl_filename) + 20;
612 new_filename = malloc(len); 613 new_filename = malloc(len);
613 if (new_filename == NULL) 614 if (new_filename == NULL)
614 return MAILMH_ERROR_MEMORY; 615 return MAILMH_ERROR_MEMORY;
615 616
616 max = folder->fl_max_index + 1; 617 max = folder->fl_max_index + 1;
617 618
619 //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename);
618 k = 0; 620 k = 0;
619 while (k < MAX_TRY_ALLOC) { 621 while (k < MAX_TRY_ALLOC) {
620 snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, 622 snprintf(new_filename, len, "%s%c%lu", folder->fl_filename,
621 MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); 623 MAIL_DIR_SEPARATOR, (unsigned long) (max + k));
622 624 //fprintf(stderr,"mailmh_folder_alloc_msg new_filename: %s \n", new_filename);
623 if (link(filename, new_filename) == 0) { 625 if ( stat( new_filename, &f_stat ) == -1 ) {
626 // if (link(filename, new_filename) == 0) {
624 int r; 627 int r;
625 628 //fprintf(stderr,"filename found \n");
629 //unlink(filename);
630 rename (filename,new_filename );
626 free(new_filename); 631 free(new_filename);
627 unlink(filename);
628 632
629 if (k > MAX_TRY_ALLOC / 2) { 633 if (k > MAX_TRY_ALLOC / 2) {
630 r = mailmh_folder_update(folder); 634 r = mailmh_folder_update(folder);
631 /* ignore errors */ 635 /* ignore errors */
632 } 636 }
633 637
634 * result = max + k; 638 * result = max + k;
635 639
636 folder->fl_max_index = max + k; 640 folder->fl_max_index = max + k;
637 641
638 return MAILMH_NO_ERROR; 642 return MAILMH_NO_ERROR;
639 } 643 }
640 else if (errno == EXDEV) { 644 else if (errno == EXDEV) {
641 free(filename); 645 free(filename);
642 return MAILMH_ERROR_FOLDER; 646 return MAILMH_ERROR_FOLDER;
643 } 647 }
644 k ++; 648 k ++;
645 } 649 }
646 650
647 free(new_filename); 651 free(new_filename);
648 652
649 return MAILMH_ERROR_FOLDER; 653 return MAILMH_ERROR_FOLDER;
650} 654}
651 655
652int mailmh_folder_get_message_filename(struct mailmh_folder * folder, 656int mailmh_folder_get_message_filename(struct mailmh_folder * folder,
653 uint32_t index, char ** result) 657 uint32_t index, char ** result)
654{ 658{
655 char * filename; 659 char * filename;
656 int len; 660 int len;
657 661
658#if 0 662#if 0
659 r = mailmh_folder_update(folder); 663 r = mailmh_folder_update(folder);
660 if (r != MAILMH_NO_ERROR) 664 if (r != MAILMH_NO_ERROR)
661 return r; 665 return r;
662#endif 666#endif
663 667
664 len = strlen(folder->fl_filename) + 20; 668 len = strlen(folder->fl_filename) + 20;
665 filename = malloc(len); 669 filename = malloc(len);
666 if (filename == NULL) 670 if (filename == NULL)
667 return MAILMH_ERROR_MEMORY; 671 return MAILMH_ERROR_MEMORY;
668 672
669 snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, 673 snprintf(filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR,
670 (unsigned long) index); 674 (unsigned long) index);
671 675
672 * result = filename; 676 * result = filename;
673 677
674 return MAILMH_NO_ERROR;; 678 return MAILMH_NO_ERROR;;
675} 679}