UIDL is not looking for "X-UIDL" if not do an md5 of the message.
When expunging check if the message as been modified, for example "X-UIDL" maybe add in the header it will now be save in the message. expunge reuse the same code of mbox_append_message(). add a new header_set_fill() to get the header of the messages form the mailbox.
Showing
13 changed files
with
589 additions
and
91 deletions
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -25,6 +25,8 @@ | ... | @@ -25,6 +25,8 @@ |
25 | 25 | ||
26 | #include <attribute0.h> | 26 | #include <attribute0.h> |
27 | 27 | ||
28 | static int flags_to_string __P ((int, char *, size_t, size_t *)); | ||
29 | |||
28 | int | 30 | int |
29 | attribute_create (attribute_t *pattr, void *owner) | 31 | attribute_create (attribute_t *pattr, void *owner) |
30 | { | 32 | { |
... | @@ -59,6 +61,12 @@ attribute_get_owner (attribute_t attr) | ... | @@ -59,6 +61,12 @@ attribute_get_owner (attribute_t attr) |
59 | } | 61 | } |
60 | 62 | ||
61 | int | 63 | int |
64 | attribute_is_modified (attribute_t attr) | ||
65 | { | ||
66 | return (attr) ? attr->flags != 0 : 0; | ||
67 | } | ||
68 | |||
69 | int | ||
62 | attribute_get_flags (attribute_t attr, int *pflags) | 70 | attribute_get_flags (attribute_t attr, int *pflags) |
63 | { | 71 | { |
64 | if (attr == NULL) | 72 | if (attr == NULL) |
... | @@ -76,7 +84,7 @@ attribute_set_flags (attribute_t attr, int flags) | ... | @@ -76,7 +84,7 @@ attribute_set_flags (attribute_t attr, int flags) |
76 | if (attr == NULL) | 84 | if (attr == NULL) |
77 | return EINVAL; | 85 | return EINVAL; |
78 | if (attr->_set_flags) | 86 | if (attr->_set_flags) |
79 | return attr->_set_flags (attr, flags); | 87 | attr->_set_flags (attr, flags); |
80 | attr->flags |= flags; | 88 | attr->flags |= flags; |
81 | return 0; | 89 | return 0; |
82 | } | 90 | } |
... | @@ -446,7 +454,15 @@ string_to_flags (const char *buffer, int *pflags) | ... | @@ -446,7 +454,15 @@ string_to_flags (const char *buffer, int *pflags) |
446 | return 0; | 454 | return 0; |
447 | } | 455 | } |
448 | 456 | ||
449 | int | 457 | int |
458 | attribute_to_string (attribute_t attr, char *buffer, size_t len, size_t *pn) | ||
459 | { | ||
460 | int flags = 0;; | ||
461 | attribute_get_flags (attr, &flags); | ||
462 | return flags_to_string (flags, buffer, len, pn); | ||
463 | } | ||
464 | |||
465 | static int | ||
450 | flags_to_string (int flags, char *buffer, size_t len, size_t *pn) | 466 | flags_to_string (int flags, char *buffer, size_t len, size_t *pn) |
451 | { | 467 | { |
452 | char status[32]; | 468 | char status[32]; | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -307,22 +307,10 @@ body_get_fd (stream_t stream, int *pfd) | ... | @@ -307,22 +307,10 @@ body_get_fd (stream_t stream, int *pfd) |
307 | static FILE * | 307 | static FILE * |
308 | lazy_create () | 308 | lazy_create () |
309 | { | 309 | { |
310 | FILE *file; | 310 | FILE *file = tmpfile (); |
311 | #ifdef HAVE_MKSTEMP | ||
312 | char tmpbuf[L_tmpnam + 1]; | ||
313 | int fd; | ||
314 | |||
315 | if (tmpnam (tmpbuf) == NULL || | ||
316 | (fd = mkstemp (tmpbuf)) == -1 || | ||
317 | (file = fdopen(fd, "w+")) == NULL) | ||
318 | return NULL; | ||
319 | (void)remove(tmpbuf); | ||
320 | #else | ||
321 | file = tmpfile (); | ||
322 | //file = fopen ("/tmp/mystuff", "w+"); | 311 | //file = fopen ("/tmp/mystuff", "w+"); |
323 | /* make sure the mode is right */ | 312 | /* make sure the mode is right */ |
324 | if (file) | 313 | if (file) |
325 | fchmod (fileno (file), 0600); | 314 | fchmod (fileno (file), 0600); |
326 | #endif | ||
327 | return file; | 315 | return file; |
328 | } | 316 | } | ... | ... |
... | @@ -334,11 +334,36 @@ folder_list (folder_t folder, const char *dirname, const char *basename, | ... | @@ -334,11 +334,36 @@ folder_list (folder_t folder, const char *dirname, const char *basename, |
334 | struct folder_list *pflist) | 334 | struct folder_list *pflist) |
335 | { | 335 | { |
336 | if (folder == NULL || folder->_list == NULL) | 336 | if (folder == NULL || folder->_list == NULL) |
337 | return ENOSYS; | 337 | return EINVAL; |
338 | return folder->_list (folder, dirname, basename, pflist); | 338 | return folder->_list (folder, dirname, basename, pflist); |
339 | } | 339 | } |
340 | 340 | ||
341 | int | 341 | int |
342 | folder_lsub (folder_t folder, const char *dirname, const char *basename, | ||
343 | struct folder_list *pflist) | ||
344 | { | ||
345 | if (folder == NULL || folder->_lsub == NULL) | ||
346 | return ENOSYS; | ||
347 | return folder->_lsub (folder, dirname, basename, pflist); | ||
348 | } | ||
349 | |||
350 | int | ||
351 | folder_subscribe (folder_t folder, const char *name) | ||
352 | { | ||
353 | if (folder == NULL || folder->_subscribe == NULL) | ||
354 | return EINVAL; | ||
355 | return folder->_subscribe (folder, name); | ||
356 | } | ||
357 | |||
358 | int | ||
359 | folder_unsubscribe (folder_t folder, const char *name) | ||
360 | { | ||
361 | if (folder == NULL || folder->_unsubscribe == NULL) | ||
362 | return EINVAL; | ||
363 | return folder->_unsubscribe (folder, name); | ||
364 | } | ||
365 | |||
366 | int | ||
342 | folder_list_destroy (struct folder_list *pflist) | 367 | folder_list_destroy (struct folder_list *pflist) |
343 | { | 368 | { |
344 | size_t i; | 369 | size_t i; |
... | @@ -353,7 +378,10 @@ folder_list_destroy (struct folder_list *pflist) | ... | @@ -353,7 +378,10 @@ folder_list_destroy (struct folder_list *pflist) |
353 | free (pflist->element[i]); | 378 | free (pflist->element[i]); |
354 | } | 379 | } |
355 | } | 380 | } |
356 | free (pflist->element); | 381 | if (i > 0) |
382 | free (pflist->element); | ||
383 | pflist->element = NULL; | ||
384 | pflist->num = 0; | ||
357 | return 0; | 385 | return 0; |
358 | } | 386 | } |
359 | 387 | ... | ... |
... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
24 | #include <errno.h> | 24 | #include <errno.h> |
25 | #include <string.h> | 25 | #include <string.h> |
26 | #include <assert.h> | 26 | #include <assert.h> |
27 | #include <fnmatch.h> | ||
27 | 28 | ||
28 | #include <imap0.h> | 29 | #include <imap0.h> |
29 | 30 | ||
... | @@ -384,17 +385,93 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, | ... | @@ -384,17 +385,93 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, |
384 | { | 385 | { |
385 | f_imap_t f_imap = folder->data; | 386 | f_imap_t f_imap = folder->data; |
386 | int status = 0; | 387 | int status = 0; |
388 | char *path = NULL; | ||
389 | |||
390 | /* NOOP. */ | ||
391 | if (pflist == NULL) | ||
392 | return EINVAL; | ||
387 | 393 | ||
388 | if (ref == NULL) | 394 | if (ref == NULL) |
389 | ref = ""; | 395 | ref = ""; |
390 | if (name == NULL) | 396 | if (name == NULL) |
391 | name = ""; | 397 | name = ""; |
392 | 398 | ||
399 | path = strdup (""); | ||
400 | if (path == NULL) | ||
401 | return ENOMEM; | ||
402 | |||
403 | /* We break the string to pieces and change the occurences of "*?[" for | ||
404 | the imap magic "%" for expansion. Then reassemble the string: | ||
405 | "/home/?/Mail/a*lain*" --> "/usr/%/Mail/%". */ | ||
406 | { | ||
407 | int done = 0; | ||
408 | size_t i; | ||
409 | char **node = NULL; | ||
410 | size_t nodelen = 0; | ||
411 | const char *p = name; | ||
412 | /* Disassemble. */ | ||
413 | while (!done && *p) | ||
414 | { | ||
415 | char **n; | ||
416 | n = realloc (node, (nodelen + 1) * sizeof (*node)); | ||
417 | if (n == NULL) | ||
418 | break; | ||
419 | node = n; | ||
420 | if (*p == '/') | ||
421 | { | ||
422 | node[nodelen] = strdup ("/"); | ||
423 | p++; | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | const char *s = strchr (p, '/'); | ||
428 | if (s) | ||
429 | { | ||
430 | node[nodelen] = calloc (s - p + 1, sizeof (char)); | ||
431 | if (node[nodelen]) | ||
432 | memcpy (node[nodelen], p, s - p); | ||
433 | p = s; | ||
434 | } | ||
435 | else | ||
436 | { | ||
437 | node[nodelen] = strdup (p); | ||
438 | done = 1; | ||
439 | } | ||
440 | if (node[nodelen] && strpbrk (node[nodelen], "*?[")) | ||
441 | { | ||
442 | free (node[nodelen]); | ||
443 | node[nodelen] = strdup ("%"); | ||
444 | } | ||
445 | } | ||
446 | nodelen++; | ||
447 | if (done) | ||
448 | break; | ||
449 | } | ||
450 | /* Reassemble. */ | ||
451 | for (i = 0; i < nodelen; i++) | ||
452 | { | ||
453 | if (node[i]) | ||
454 | { | ||
455 | char *pth; | ||
456 | pth = realloc (path, strlen (path) + strlen (node[i]) + 1); | ||
457 | if (pth) | ||
458 | { | ||
459 | path = pth; | ||
460 | strcat (path, node[i]); | ||
461 | } | ||
462 | free (node[i]); | ||
463 | } | ||
464 | } | ||
465 | if (node) | ||
466 | free (node); | ||
467 | } | ||
468 | |||
393 | switch (f_imap->state) | 469 | switch (f_imap->state) |
394 | { | 470 | { |
395 | case IMAP_NO_STATE: | 471 | case IMAP_NO_STATE: |
396 | status = imap_writeline (f_imap, "g%d LIST \"%s\" \"%s\"\r\n", | 472 | status = imap_writeline (f_imap, "g%d LIST \"%s\" \"%s\"\r\n", |
397 | f_imap->seq++, ref, name); | 473 | f_imap->seq++, ref, path); |
474 | free (path); | ||
398 | CHECK_ERROR (f_imap, status); | 475 | CHECK_ERROR (f_imap, status); |
399 | FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer); | 476 | FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer); |
400 | f_imap->state = IMAP_LIST; | 477 | f_imap->state = IMAP_LIST; |
... | @@ -412,6 +489,39 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, | ... | @@ -412,6 +489,39 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, |
412 | default: | 489 | default: |
413 | break; | 490 | break; |
414 | } | 491 | } |
492 | |||
493 | /* Build the folder list. */ | ||
494 | if (f_imap->callback.flist.num > 0) | ||
495 | { | ||
496 | struct list_response **plist = NULL; | ||
497 | size_t num = f_imap->callback.flist.num; | ||
498 | size_t j = 0; | ||
499 | plist = calloc (num, sizeof (*plist)); | ||
500 | if (plist) | ||
501 | { | ||
502 | size_t i; | ||
503 | for (i = 0; i < num; i++) | ||
504 | { | ||
505 | struct list_response *lr = f_imap->callback.flist.element[i]; | ||
506 | //printf ("%s --> %s\n", lr->name, name); | ||
507 | if (fnmatch (name, lr->name, 0) == 0) | ||
508 | { | ||
509 | plist[i] = calloc (1, sizeof (**plist)); | ||
510 | if (plist[i] == NULL | ||
511 | || (plist[i]->name = strdup (lr->name)) == NULL) | ||
512 | { | ||
513 | break; | ||
514 | } | ||
515 | plist[i]->type = lr->type; | ||
516 | plist[i]->separator = lr->separator; | ||
517 | j++; | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | pflist->element = plist; | ||
522 | pflist->num = j; | ||
523 | } | ||
524 | folder_list_destroy (&(f_imap->callback.flist)); | ||
415 | f_imap->state = IMAP_NO_STATE; | 525 | f_imap->state = IMAP_NO_STATE; |
416 | return status; | 526 | return status; |
417 | } | 527 | } |
... | @@ -423,10 +533,13 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, | ... | @@ -423,10 +533,13 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, |
423 | f_imap_t f_imap = folder->data; | 533 | f_imap_t f_imap = folder->data; |
424 | int status = 0; | 534 | int status = 0; |
425 | 535 | ||
426 | if (ref == NULL) | 536 | /* NOOP. */ |
427 | ref = ""; | 537 | if (pflist == NULL) |
428 | if (name == NULL) | 538 | return EINVAL; |
429 | name = ""; | 539 | |
540 | if (ref == NULL) ref = ""; | ||
541 | if (name == NULL) name = ""; | ||
542 | |||
430 | switch (f_imap->state) | 543 | switch (f_imap->state) |
431 | { | 544 | { |
432 | case IMAP_NO_STATE: | 545 | case IMAP_NO_STATE: |
... | @@ -449,6 +562,37 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, | ... | @@ -449,6 +562,37 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, |
449 | default: | 562 | default: |
450 | break; | 563 | break; |
451 | } | 564 | } |
565 | |||
566 | /* Build the folder list. */ | ||
567 | if (f_imap->callback.flist.num > 0) | ||
568 | { | ||
569 | struct list_response **plist = NULL; | ||
570 | size_t num = f_imap->callback.flist.num; | ||
571 | size_t j = 0; | ||
572 | plist = calloc (num, sizeof (*plist)); | ||
573 | if (plist) | ||
574 | { | ||
575 | size_t i; | ||
576 | for (i = 0; i < num; i++) | ||
577 | { | ||
578 | struct list_response *lr = f_imap->callback.flist.element[i]; | ||
579 | //printf ("%s --> %s\n", lr->name, name); | ||
580 | plist[i] = calloc (1, sizeof (**plist)); | ||
581 | if (plist[i] == NULL | ||
582 | || (plist[i]->name = strdup (lr->name)) == NULL) | ||
583 | { | ||
584 | break; | ||
585 | } | ||
586 | plist[i]->type = lr->type; | ||
587 | plist[i]->separator = lr->separator; | ||
588 | j++; | ||
589 | } | ||
590 | } | ||
591 | pflist->element = plist; | ||
592 | pflist->num = j; | ||
593 | folder_list_destroy (&(f_imap->callback.flist)); | ||
594 | } | ||
595 | f_imap->state = IMAP_NO_STATE; | ||
452 | f_imap->state = IMAP_NO_STATE; | 596 | f_imap->state = IMAP_NO_STATE; |
453 | return 0; | 597 | return 0; |
454 | } | 598 | } |
... | @@ -755,6 +899,86 @@ imap_string (f_imap_t f_imap) | ... | @@ -755,6 +899,86 @@ imap_string (f_imap_t f_imap) |
755 | return status; | 899 | return status; |
756 | } | 900 | } |
757 | 901 | ||
902 | /* FIXME: does not worl for nobloking. */ | ||
903 | static int | ||
904 | imap_list (f_imap_t f_imap) | ||
905 | { | ||
906 | char *tok; | ||
907 | char *sp = NULL; | ||
908 | size_t len = f_imap->nl - f_imap->buffer - 1; | ||
909 | char *buffer; | ||
910 | struct list_response **plr; | ||
911 | struct list_response *lr; | ||
912 | |||
913 | buffer = alloca (len); | ||
914 | memcpy (buffer, f_imap->buffer, len); | ||
915 | buffer[len] = '\0'; | ||
916 | plr = realloc (f_imap->callback.flist.element, | ||
917 | (f_imap->callback.flist.num + 1) * sizeof (*plr)); | ||
918 | if (plr == NULL) | ||
919 | return ENOMEM; | ||
920 | f_imap->callback.flist.element = plr; | ||
921 | lr = plr[f_imap->callback.flist.num] = calloc (1, sizeof (*lr)); | ||
922 | if (lr == NULL) | ||
923 | return ENOMEM; | ||
924 | (f_imap->callback.flist.num)++; | ||
925 | |||
926 | /* Glob untag. */ | ||
927 | tok = strtok_r (buffer, " ", &sp); | ||
928 | /* Glob LIST. */ | ||
929 | tok = strtok_r (NULL, " ", &sp); | ||
930 | /* Get the attibutes. */ | ||
931 | tok = strtok_r (NULL, ")", &sp); | ||
932 | if (tok) | ||
933 | { | ||
934 | char *s = NULL; | ||
935 | char *p = tok; | ||
936 | while ((tok = strtok_r (p, " ()", &s)) != NULL) | ||
937 | { | ||
938 | if (strcasecmp (tok, "\\Noselect") == 0) | ||
939 | { | ||
940 | } | ||
941 | else if (strcasecmp (tok, "\\Marked") == 0) | ||
942 | { | ||
943 | } | ||
944 | else if (strcasecmp (tok, "\\Unmarked") == 0) | ||
945 | { | ||
946 | } | ||
947 | else if (strcasecmp (tok, "\\Noinferiors") == 0) | ||
948 | { | ||
949 | lr->type |= MU_FOLDER_ATTRIBUTE_FILE; | ||
950 | } | ||
951 | else | ||
952 | { | ||
953 | lr->type |= MU_FOLDER_ATTRIBUTE_DIRECTORY; | ||
954 | } | ||
955 | p = NULL; | ||
956 | } | ||
957 | } | ||
958 | /* Hiearchy delimeter. */ | ||
959 | tok = strtok_r (NULL, " ", &sp); | ||
960 | if (tok && strlen (tok) > 2) | ||
961 | lr->separator = tok[1]; | ||
962 | /* The path. */ | ||
963 | tok = strtok_r (NULL, " ", &sp); | ||
964 | if (tok) | ||
965 | { | ||
966 | char *s = strchr (tok, '{'); | ||
967 | if (s) | ||
968 | { | ||
969 | size_t n = strtoul (s + 1, NULL, 10); | ||
970 | lr->name = calloc (n + 1, sizeof (char)); | ||
971 | f_imap->ptr = f_imap->buffer; | ||
972 | imap_readline (f_imap); | ||
973 | memcpy (lr->name, f_imap->buffer, n); | ||
974 | lr->name[n] = '\0'; | ||
975 | } | ||
976 | else | ||
977 | lr->name = strdup (tok); | ||
978 | } | ||
979 | return 0; | ||
980 | } | ||
981 | |||
758 | /* Helping function to figure out the section name of the message: for example | 982 | /* Helping function to figure out the section name of the message: for example |
759 | a 2 part message with the first part being sub in two will be: | 983 | a 2 part message with the first part being sub in two will be: |
760 | {1}, {1,1} {1,2} The first subpart of the message and its sub parts | 984 | {1}, {1,1} {1,2} The first subpart of the message and its sub parts |
... | @@ -803,6 +1027,7 @@ section_name (msg_imap_t msg_imap) | ... | @@ -803,6 +1027,7 @@ section_name (msg_imap_t msg_imap) |
803 | return section; | 1027 | return section; |
804 | } | 1028 | } |
805 | 1029 | ||
1030 | /* FIXME: This does not work for nonblocking. */ | ||
806 | /* Recursive call, to parse the dismay of parentesis "()" in a BODYSTRUCTURE | 1031 | /* Recursive call, to parse the dismay of parentesis "()" in a BODYSTRUCTURE |
807 | call, not we use the short form of BODYSTRUCTURE, BODY with no argument. */ | 1032 | call, not we use the short form of BODYSTRUCTURE, BODY with no argument. */ |
808 | static int | 1033 | static int |
... | @@ -1231,12 +1456,12 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1231,12 +1456,12 @@ imap_parse (f_imap_t f_imap) |
1231 | char *tag, *response, *remainder; | 1456 | char *tag, *response, *remainder; |
1232 | char *buffer; | 1457 | char *buffer; |
1233 | status = imap_readline (f_imap); | 1458 | status = imap_readline (f_imap); |
1234 | /* Comment out to see all reading traffic. */ | ||
1235 | //fprintf (stderr, "\t\t%s", f_imap->buffer); | ||
1236 | if (status != 0) | 1459 | if (status != 0) |
1237 | { | 1460 | { |
1238 | break; | 1461 | break; |
1239 | } | 1462 | } |
1463 | /* Comment out to see all reading traffic. */ | ||
1464 | fprintf (stderr, "\t\t%s", f_imap->buffer); | ||
1240 | 1465 | ||
1241 | /* We do not want to step over f_imap->buffer since it can be use | 1466 | /* We do not want to step over f_imap->buffer since it can be use |
1242 | further down the chain. */ | 1467 | further down the chain. */ |
... | @@ -1429,9 +1654,11 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1429,9 +1654,11 @@ imap_parse (f_imap_t f_imap) |
1429 | } | 1654 | } |
1430 | else if (strcmp (response, "LIST") == 0) | 1655 | else if (strcmp (response, "LIST") == 0) |
1431 | { | 1656 | { |
1657 | status = imap_list (f_imap); | ||
1432 | } | 1658 | } |
1433 | else if (strcmp (response, "LSUB") == 0) | 1659 | else if (strcmp (response, "LSUB") == 0) |
1434 | { | 1660 | { |
1661 | status = imap_list (f_imap); | ||
1435 | } | 1662 | } |
1436 | else if (strcmp (remainder, "RECENT") == 0) | 1663 | else if (strcmp (remainder, "RECENT") == 0) |
1437 | { | 1664 | { | ... | ... |
... | @@ -25,6 +25,7 @@ | ... | @@ -25,6 +25,7 @@ |
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <glob.h> | 27 | #include <glob.h> |
28 | #include <fnmatch.h> | ||
28 | #include <stdio.h> | 29 | #include <stdio.h> |
29 | #include <stdlib.h> | 30 | #include <stdlib.h> |
30 | 31 | ||
... | @@ -83,19 +84,27 @@ static struct _record _path_record = | ... | @@ -83,19 +84,27 @@ static struct _record _path_record = |
83 | record_t path_record = &_path_record; | 84 | record_t path_record = &_path_record; |
84 | 85 | ||
85 | /* lsub/subscribe/unsubscribe are not needed. */ | 86 | /* lsub/subscribe/unsubscribe are not needed. */ |
86 | static void folder_mbox_destroy __P ((folder_t)); | 87 | static void folder_mbox_destroy __P ((folder_t)); |
87 | static int folder_mbox_open __P ((folder_t, int)); | 88 | static int folder_mbox_open __P ((folder_t, int)); |
88 | static int folder_mbox_close __P ((folder_t)); | 89 | static int folder_mbox_close __P ((folder_t)); |
89 | static int folder_mbox_delete __P ((folder_t, const char *)); | 90 | static int folder_mbox_delete __P ((folder_t, const char *)); |
90 | static int folder_mbox_rename __P ((folder_t , const char *, const char *)); | 91 | static int folder_mbox_rename __P ((folder_t , const char *, |
91 | static int folder_mbox_list __P ((folder_t, const char *, const char *, | 92 | const char *)); |
92 | struct folder_list *)); | 93 | static int folder_mbox_list __P ((folder_t, const char *, const char *, |
94 | struct folder_list *)); | ||
95 | static int folder_mbox_subscribe __P ((folder_t, const char *)); | ||
96 | static int folder_mbox_unsubscribe __P ((folder_t, const char *)); | ||
97 | static int folder_mbox_lsub __P ((folder_t, const char *, const char *, | ||
98 | struct folder_list *)); | ||
99 | |||
93 | 100 | ||
94 | static char *get_pathname __P ((const char *, const char *)); | 101 | static char *get_pathname __P ((const char *, const char *)); |
95 | 102 | ||
96 | struct _fmbox | 103 | struct _fmbox |
97 | { | 104 | { |
98 | char *dirname; | 105 | char *dirname; |
106 | char **subscribe; | ||
107 | size_t sublen; | ||
99 | }; | 108 | }; |
100 | typedef struct _fmbox *fmbox_t; | 109 | typedef struct _fmbox *fmbox_t; |
101 | 110 | ||
... | @@ -126,9 +135,11 @@ _folder_mbox_init (folder_t folder) | ... | @@ -126,9 +135,11 @@ _folder_mbox_init (folder_t folder) |
126 | folder->_close = folder_mbox_close; | 135 | folder->_close = folder_mbox_close; |
127 | 136 | ||
128 | folder->_list = folder_mbox_list; | 137 | folder->_list = folder_mbox_list; |
138 | folder->_lsub = folder_mbox_lsub; | ||
139 | folder->_subscribe = folder_mbox_subscribe; | ||
140 | folder->_unsubscribe = folder_mbox_unsubscribe; | ||
129 | folder->_delete = folder_mbox_delete; | 141 | folder->_delete = folder_mbox_delete; |
130 | folder->_rename = folder_mbox_rename; | 142 | folder->_rename = folder_mbox_rename; |
131 | |||
132 | return 0; | 143 | return 0; |
133 | } | 144 | } |
134 | 145 | ||
... | @@ -140,6 +151,8 @@ folder_mbox_destroy (folder_t folder) | ... | @@ -140,6 +151,8 @@ folder_mbox_destroy (folder_t folder) |
140 | fmbox_t fmbox = folder->data; | 151 | fmbox_t fmbox = folder->data; |
141 | if (fmbox->dirname) | 152 | if (fmbox->dirname) |
142 | free (fmbox->dirname); | 153 | free (fmbox->dirname); |
154 | if (fmbox->subscribe) | ||
155 | free (fmbox->subscribe); | ||
143 | free (folder->data); | 156 | free (folder->data); |
144 | folder->data = NULL; | 157 | folder->data = NULL; |
145 | } | 158 | } |
... | @@ -150,7 +163,6 @@ static int | ... | @@ -150,7 +163,6 @@ static int |
150 | folder_mbox_open (folder_t folder, int flags) | 163 | folder_mbox_open (folder_t folder, int flags) |
151 | { | 164 | { |
152 | (void)(folder); | 165 | (void)(folder); |
153 | |||
154 | (void)(flags); | 166 | (void)(flags); |
155 | return 0; | 167 | return 0; |
156 | } | 168 | } |
... | @@ -281,6 +293,84 @@ folder_mbox_list (folder_t folder, const char *dirname, const char *pattern, | ... | @@ -281,6 +293,84 @@ folder_mbox_list (folder_t folder, const char *dirname, const char *pattern, |
281 | return status; | 293 | return status; |
282 | } | 294 | } |
283 | 295 | ||
296 | static int | ||
297 | folder_mbox_lsub (folder_t folder, const char *ref, const char *name, | ||
298 | struct folder_list *pflist) | ||
299 | { | ||
300 | fmbox_t fmbox = folder->data; | ||
301 | size_t j = 0; | ||
302 | |||
303 | if (pflist == NULL) | ||
304 | return EINVAL; | ||
305 | |||
306 | (void)ref; | ||
307 | if (name == NULL || *name == '\0') | ||
308 | name = "*"; | ||
309 | |||
310 | if (fmbox->sublen > 0) | ||
311 | { | ||
312 | struct list_response **plist; | ||
313 | size_t i; | ||
314 | plist = calloc (fmbox->sublen, sizeof (*plist)); | ||
315 | for (i = 0; i < fmbox->sublen; i++) | ||
316 | { | ||
317 | if (fmbox->subscribe[i] | ||
318 | && fnmatch (name, fmbox->subscribe[i], 0) == 0) | ||
319 | { | ||
320 | plist[i] = calloc (1, sizeof (**plist)); | ||
321 | if (plist[i] == NULL | ||
322 | || (plist[i]->name = strdup (fmbox->subscribe[i])) == NULL) | ||
323 | break; | ||
324 | plist[i]->type = MU_FOLDER_ATTRIBUTE_FILE; | ||
325 | plist[i]->separator = '/'; | ||
326 | j++; | ||
327 | } | ||
328 | } | ||
329 | pflist->element = plist; | ||
330 | } | ||
331 | pflist->num = j; | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int | ||
336 | folder_mbox_subscribe (folder_t folder, const char *name) | ||
337 | { | ||
338 | fmbox_t fmbox = folder->data; | ||
339 | char **tmp; | ||
340 | size_t i; | ||
341 | for (i = 0; i < fmbox->sublen; i++) | ||
342 | { | ||
343 | if (fmbox->subscribe[i] && strcmp (fmbox->subscribe[i], name) == 0) | ||
344 | return 0; | ||
345 | } | ||
346 | tmp = realloc (fmbox->subscribe, (fmbox->sublen + 1) * sizeof (*tmp)); | ||
347 | if (tmp == NULL) | ||
348 | return ENOMEM; | ||
349 | fmbox->subscribe = tmp; | ||
350 | fmbox->subscribe[fmbox->sublen] = strdup (name); | ||
351 | if (fmbox->subscribe[fmbox->sublen] == NULL) | ||
352 | return ENOMEM; | ||
353 | fmbox->sublen++; | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static int | ||
358 | folder_mbox_unsubscribe (folder_t folder, const char *name) | ||
359 | { | ||
360 | fmbox_t fmbox = folder->data; | ||
361 | size_t i; | ||
362 | for (i = 0; i < fmbox->sublen; i++) | ||
363 | { | ||
364 | if (fmbox->subscribe[i] && strcmp (fmbox->subscribe[i], name) == 0) | ||
365 | { | ||
366 | free (fmbox->subscribe[i]); | ||
367 | fmbox->subscribe[i] = NULL; | ||
368 | return 0; | ||
369 | } | ||
370 | } | ||
371 | return ENOENT; | ||
372 | } | ||
373 | |||
284 | static char * | 374 | static char * |
285 | get_pathname (const char *dirname, const char *basename) | 375 | get_pathname (const char *dirname, const char *basename) |
286 | { | 376 | { | ... | ... |
... | @@ -28,12 +28,14 @@ | ... | @@ -28,12 +28,14 @@ |
28 | #include <mailutils/stream.h> | 28 | #include <mailutils/stream.h> |
29 | #include <header0.h> | 29 | #include <header0.h> |
30 | 30 | ||
31 | static int header_parse (header_t h, const char *blurb, int len); | 31 | #define HEADER_MODIFIED 1 |
32 | static int header_read (stream_t is, char *buf, size_t buflen, | 32 | |
33 | off_t off, size_t *pnread); | 33 | static int header_parse __P ((header_t, const char *, int)); |
34 | static int header_write (stream_t os, const char *buf, size_t buflen, | 34 | static int header_read __P ((stream_t, char *, size_t, off_t, size_t *)); |
35 | off_t off, size_t *pnwrite); | 35 | static int header_readline __P ((stream_t, char *, size_t, off_t, size_t *)); |
36 | static int fill_blurb (header_t header); | 36 | static int header_write __P ((stream_t, const char *, size_t, off_t, |
37 | size_t *)); | ||
38 | static int fill_blurb __P ((header_t)); | ||
37 | 39 | ||
38 | int | 40 | int |
39 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) | 41 | header_create (header_t *ph, const char *blurb, size_t len, void *owner) |
... | @@ -79,6 +81,12 @@ header_get_owner (header_t header) | ... | @@ -79,6 +81,12 @@ header_get_owner (header_t header) |
79 | return (header) ? header->owner : NULL; | 81 | return (header) ? header->owner : NULL; |
80 | } | 82 | } |
81 | 83 | ||
84 | int | ||
85 | header_is_modified (header_t header) | ||
86 | { | ||
87 | return (header) ? (header->flags & HEADER_MODIFIED) : 0; | ||
88 | } | ||
89 | |||
82 | /* Parsing is done in a rather simple fashion. | 90 | /* Parsing is done in a rather simple fashion. |
83 | meaning we just consider an entry to be | 91 | meaning we just consider an entry to be |
84 | a field-name an a field-value. So they | 92 | a field-name an a field-value. So they |
... | @@ -298,6 +306,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) | ... | @@ -298,6 +306,7 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace) |
298 | } | 306 | } |
299 | header_parse (header, blurb, len + header->blurb_len); | 307 | header_parse (header, blurb, len + header->blurb_len); |
300 | free (blurb); | 308 | free (blurb); |
309 | header->flags |= HEADER_MODIFIED; | ||
301 | return 0; | 310 | return 0; |
302 | } | 311 | } |
303 | 312 | ||
... | @@ -498,23 +507,43 @@ header_set_stream (header_t header, stream_t stream, void *owner) | ... | @@ -498,23 +507,43 @@ header_set_stream (header_t header, stream_t stream, void *owner) |
498 | return 0; | 507 | return 0; |
499 | } | 508 | } |
500 | 509 | ||
510 | int | ||
511 | header_set_fill (header_t header, int | ||
512 | (*_fill) __P ((header_t, char *, size_t, off_t, size_t *)), | ||
513 | void *owner) | ||
514 | { | ||
515 | if (header == NULL) | ||
516 | return EINVAL; | ||
517 | if (header->owner != owner) | ||
518 | return EACCES; | ||
519 | header->_fill = _fill; | ||
520 | return 0; | ||
521 | } | ||
522 | |||
501 | static int | 523 | static int |
502 | fill_blurb (header_t header) | 524 | fill_blurb (header_t header) |
503 | { | 525 | { |
504 | stream_t is; | 526 | stream_t is = NULL; |
505 | int status; | 527 | int status; |
506 | char buf[1024]; | 528 | char buf[1024]; |
507 | char *tbuf; | 529 | char *tbuf; |
508 | size_t nread = 0; | 530 | size_t nread = 0; |
509 | 531 | ||
510 | status = header_get_stream (header, &is); | 532 | if (header->_fill == NULL) |
511 | if (status != 0) | 533 | { |
512 | return status; | 534 | status = header_get_stream (header, &is); |
535 | if (status != 0) | ||
536 | return status; | ||
537 | } | ||
513 | 538 | ||
514 | do | 539 | do |
515 | { | 540 | { |
516 | status = stream_read (is, buf, sizeof (buf), header->temp_blurb_len, | 541 | if (header->_fill) |
517 | &nread); | 542 | status = header->_fill (header, buf, sizeof (buf), |
543 | header->temp_blurb_len, &nread) ; | ||
544 | else | ||
545 | status = stream_read (is, buf, sizeof (buf), | ||
546 | header->temp_blurb_len, &nread); | ||
518 | if (status != 0) | 547 | if (status != 0) |
519 | { | 548 | { |
520 | if (status != EAGAIN && status != EINTR) | 549 | if (status != EAGAIN && status != EINTR) |
... | @@ -572,8 +601,7 @@ header_write (stream_t os, const char *buf, size_t buflen, | ... | @@ -572,8 +601,7 @@ header_write (stream_t os, const char *buf, size_t buflen, |
572 | } | 601 | } |
573 | 602 | ||
574 | static int | 603 | static int |
575 | header_read (stream_t is, char *buf, size_t buflen, | 604 | header_read (stream_t is, char *buf, size_t buflen, off_t off, size_t *pnread) |
576 | off_t off, size_t *pnread) | ||
577 | { | 605 | { |
578 | header_t header = stream_get_owner (is); | 606 | header_t header = stream_get_owner (is); |
579 | int len; | 607 | int len; |
... | @@ -581,6 +609,14 @@ header_read (stream_t is, char *buf, size_t buflen, | ... | @@ -581,6 +609,14 @@ header_read (stream_t is, char *buf, size_t buflen, |
581 | if (is == NULL || header == NULL) | 609 | if (is == NULL || header == NULL) |
582 | return EINVAL; | 610 | return EINVAL; |
583 | 611 | ||
612 | /* Try to fill out the buffer, if we know how. */ | ||
613 | if (header->blurb == NULL) | ||
614 | { | ||
615 | int err = fill_blurb (header); | ||
616 | if (err != 0) | ||
617 | return err; | ||
618 | } | ||
619 | |||
584 | len = header->blurb_len - off; | 620 | len = header->blurb_len - off; |
585 | if (len > 0) | 621 | if (len > 0) |
586 | { | 622 | { |
... | @@ -598,6 +634,52 @@ header_read (stream_t is, char *buf, size_t buflen, | ... | @@ -598,6 +634,52 @@ header_read (stream_t is, char *buf, size_t buflen, |
598 | return 0; | 634 | return 0; |
599 | } | 635 | } |
600 | 636 | ||
637 | static int | ||
638 | header_readline (stream_t is, char *buf, size_t buflen, off_t off, size_t *pn) | ||
639 | { | ||
640 | header_t header = stream_get_owner (is); | ||
641 | int len; | ||
642 | |||
643 | if (is == NULL || header == NULL) | ||
644 | return EINVAL; | ||
645 | |||
646 | if (buf == NULL || buflen == 0) | ||
647 | { | ||
648 | if (pn) | ||
649 | *pn = 0; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | /* Try to fill out the buffer, if we know how. */ | ||
654 | if (header->blurb == NULL) | ||
655 | { | ||
656 | int err = fill_blurb (header); | ||
657 | if (err != 0) | ||
658 | return err; | ||
659 | } | ||
660 | |||
661 | buflen--; /* Space for the null. */ | ||
662 | |||
663 | len = header->blurb_len - off; | ||
664 | if (len > 0) | ||
665 | { | ||
666 | char *nl = memchr (header->blurb + off, '\n', len); | ||
667 | if (nl) | ||
668 | len = nl - (header->blurb + off) + 1; | ||
669 | |||
670 | len = (buflen < (size_t)len) ? buflen : len; | ||
671 | memcpy (buf, header->blurb + off, len); | ||
672 | buf[len] = '\0'; | ||
673 | } | ||
674 | else | ||
675 | len = 0; | ||
676 | |||
677 | if (pn) | ||
678 | *pn = len; | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | |||
601 | int | 683 | int |
602 | header_get_stream (header_t header, stream_t *pstream) | 684 | header_get_stream (header_t header, stream_t *pstream) |
603 | { | 685 | { |
... | @@ -608,7 +690,8 @@ header_get_stream (header_t header, stream_t *pstream) | ... | @@ -608,7 +690,8 @@ header_get_stream (header_t header, stream_t *pstream) |
608 | int status = stream_create (&(header->stream), MU_STREAM_RDWR, header); | 690 | int status = stream_create (&(header->stream), MU_STREAM_RDWR, header); |
609 | if (status != 0) | 691 | if (status != 0) |
610 | return status; | 692 | return status; |
611 | stream_set_read (header->stream, header_read, header); | 693 | stream_set_read (header->stream, header_read, header); |
694 | stream_set_readline (header->stream, header_readline, header); | ||
612 | stream_set_write (header->stream, header_write, header); | 695 | stream_set_write (header->stream, header_write, header); |
613 | } | 696 | } |
614 | *pstream = header->stream; | 697 | *pstream = header->stream; | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -61,6 +61,7 @@ struct _header | ... | @@ -61,6 +61,7 @@ struct _header |
61 | size_t blurb_len; | 61 | size_t blurb_len; |
62 | size_t hdr_count; | 62 | size_t hdr_count; |
63 | struct _hdr *hdr; | 63 | struct _hdr *hdr; |
64 | int flags; | ||
64 | 65 | ||
65 | /* Streams. */ | 66 | /* Streams. */ |
66 | stream_t stream; | 67 | stream_t stream; |
... | @@ -68,6 +69,7 @@ struct _header | ... | @@ -68,6 +69,7 @@ struct _header |
68 | int (*_set_value) __P ((header_t, const char *, const char *, int)); | 69 | int (*_set_value) __P ((header_t, const char *, const char *, int)); |
69 | int (*_lines) __P ((header_t, size_t *)); | 70 | int (*_lines) __P ((header_t, size_t *)); |
70 | int (*_size) __P ((header_t, size_t *)); | 71 | int (*_size) __P ((header_t, size_t *)); |
72 | int (*_fill) __P ((header_t, char *, size_t, off_t, size_t *)); | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | #ifdef _cplusplus | 75 | #ifdef _cplusplus | ... | ... |
... | @@ -121,6 +121,7 @@ struct literal_string | ... | @@ -121,6 +121,7 @@ struct literal_string |
121 | size_t total; | 121 | size_t total; |
122 | msg_imap_t msg_imap; | 122 | msg_imap_t msg_imap; |
123 | enum imap_state type; | 123 | enum imap_state type; |
124 | struct folder_list flist; | ||
124 | size_t nleft; /* nleft to read in the literal. */ | 125 | size_t nleft; /* nleft to read in the literal. */ |
125 | }; | 126 | }; |
126 | 127 | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -32,7 +32,7 @@ | ... | @@ -32,7 +32,7 @@ |
32 | /* | 32 | /* |
33 | */ | 33 | */ |
34 | int | 34 | int |
35 | mailer_create (mailer_t *pmailer, const char *name, int id) | 35 | mailer_create (mailer_t *pmailer, const char *name) |
36 | { | 36 | { |
37 | int status = EINVAL; | 37 | int status = EINVAL; |
38 | record_t record = NULL; | 38 | record_t record = NULL; |
... | @@ -42,7 +42,6 @@ mailer_create (mailer_t *pmailer, const char *name, int id) | ... | @@ -42,7 +42,6 @@ mailer_create (mailer_t *pmailer, const char *name, int id) |
42 | iterator_t iterator; | 42 | iterator_t iterator; |
43 | int found = 0; | 43 | int found = 0; |
44 | 44 | ||
45 | (void)id; | ||
46 | if (pmailer == NULL) | 45 | if (pmailer == NULL) |
47 | return EINVAL; | 46 | return EINVAL; |
48 | 47 | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -183,15 +183,37 @@ _mapfile_size (stream_t stream, off_t *psize) | ... | @@ -183,15 +183,37 @@ _mapfile_size (stream_t stream, off_t *psize) |
183 | { | 183 | { |
184 | struct _mapfile_stream *mfs = stream_get_owner (stream); | 184 | struct _mapfile_stream *mfs = stream_get_owner (stream); |
185 | struct stat stbuf; | 185 | struct stat stbuf; |
186 | int err = 0; | ||
186 | 187 | ||
187 | if (mfs == NULL || mfs->ptr == NULL) | 188 | if (mfs == NULL || mfs->ptr == NULL) |
188 | return EINVAL; | 189 | return EINVAL; |
189 | msync (mfs->ptr, mfs->size, MS_SYNC); | 190 | msync (mfs->ptr, mfs->size, MS_SYNC); |
190 | if (fstat(mfs->fd, &stbuf) != 0) | 191 | if (fstat(mfs->fd, &stbuf) != 0) |
191 | return errno; | 192 | return errno; |
192 | if (psize) | 193 | if (mfs->size != (size_t)stbuf.st_size) |
193 | *psize = stbuf.st_size; | 194 | { |
194 | return 0; | 195 | if (munmap (mfs->ptr, mfs->size) == 0) |
196 | { | ||
197 | mfs->size = stbuf.st_size; | ||
198 | mfs->ptr = mmap (0, mfs->size, mfs->flags , MAP_SHARED, mfs->fd, 0); | ||
199 | if (mfs->ptr == MAP_FAILED) | ||
200 | err = errno; | ||
201 | } | ||
202 | else | ||
203 | err = errno; | ||
204 | } | ||
205 | if (err != 0) | ||
206 | { | ||
207 | mfs->ptr = NULL; | ||
208 | close (mfs->fd); | ||
209 | mfs->fd = -1; | ||
210 | } | ||
211 | else | ||
212 | { | ||
213 | if (psize) | ||
214 | *psize = stbuf.st_size; | ||
215 | } | ||
216 | return err; | ||
195 | } | 217 | } |
196 | 218 | ||
197 | static int | 219 | static int |
... | @@ -277,6 +299,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) | ... | @@ -277,6 +299,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags) |
277 | { | 299 | { |
278 | int err = errno; | 300 | int err = errno; |
279 | close (mfs->fd); | 301 | close (mfs->fd); |
302 | mfs->ptr = NULL; | ||
280 | return err; | 303 | return err; |
281 | } | 304 | } |
282 | mfs->flags = mflag; | 305 | mfs->flags = mflag; | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -28,6 +28,8 @@ | ... | @@ -28,6 +28,8 @@ |
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include <ctype.h> | 29 | #include <ctype.h> |
30 | 30 | ||
31 | #include "md5.h" | ||
32 | |||
31 | #include <misc.h> | 33 | #include <misc.h> |
32 | #include <message0.h> | 34 | #include <message0.h> |
33 | 35 | ||
... | @@ -155,6 +157,15 @@ message_get_owner (message_t msg) | ... | @@ -155,6 +157,15 @@ message_get_owner (message_t msg) |
155 | } | 157 | } |
156 | 158 | ||
157 | int | 159 | int |
160 | message_is_modified (message_t msg) | ||
161 | { | ||
162 | int mod = 0; | ||
163 | mod |= header_is_modified (msg->header); | ||
164 | mod |= attribute_is_modified (msg->attribute); | ||
165 | return mod; | ||
166 | } | ||
167 | |||
168 | int | ||
158 | message_set_mailbox (message_t msg, mailbox_t mailbox) | 169 | message_set_mailbox (message_t msg, mailbox_t mailbox) |
159 | { | 170 | { |
160 | if (msg == NULL) | 171 | if (msg == NULL) |
... | @@ -400,6 +411,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) | ... | @@ -400,6 +411,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner) |
400 | return 0; | 411 | return 0; |
401 | } | 412 | } |
402 | 413 | ||
414 | /* FIXME: not nonblocking safe. */ | ||
403 | int | 415 | int |
404 | message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | 416 | message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
405 | { | 417 | { |
... | @@ -411,16 +423,19 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -411,16 +423,19 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
411 | return EINVAL; | 423 | return EINVAL; |
412 | 424 | ||
413 | buffer[0] = '\0'; | 425 | buffer[0] = '\0'; |
426 | /* Try the function overload if error fallback. */ | ||
414 | if (msg->_get_uid) | 427 | if (msg->_get_uid) |
415 | return msg->_get_uid (msg, buffer, buflen, pwriten); | 428 | { |
429 | status = msg->_get_uid (msg, buffer, buflen, pwriten); | ||
430 | if (status == 0) | ||
431 | return status; | ||
432 | } | ||
416 | 433 | ||
417 | /* Be compatible with Qpopper ? qppoper saves the UIDL in "X-UIDL". | 434 | /* Be compatible with Qpopper ? qppoper saves the UIDL in "X-UIDL". |
418 | We use "Message-ID" as a fallback. Is this bad ? should we generate | 435 | We generate a chksum and save it in the header. */ |
419 | a chksum or do the same as Qpopper save it in the header. */ | ||
420 | message_get_header (msg, &header); | 436 | message_get_header (msg, &header); |
421 | if ((status = header_get_value (header, "X-UIDL", buffer, buflen, &n)) == 0 | 437 | status = header_get_value (header, "X-UIDL", buffer, buflen, &n); |
422 | || (status = header_get_value (header, "Message-ID", buffer, | 438 | if (status == 0 && n > 0) |
423 | buflen, &n)) == 0) | ||
424 | { | 439 | { |
425 | /* FIXME: Is header_get_value suppose to do this ? */ | 440 | /* FIXME: Is header_get_value suppose to do this ? */ |
426 | /* We need to collapse the header if it was mutiline. e points to the | 441 | /* We need to collapse the header if it was mutiline. e points to the |
... | @@ -437,6 +452,32 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) | ... | @@ -437,6 +452,32 @@ message_get_uid (message_t msg, char *buffer, size_t buflen, size_t *pwriten) |
437 | } | 452 | } |
438 | } | 453 | } |
439 | } | 454 | } |
455 | else | ||
456 | { | ||
457 | struct md5_ctx md5context; | ||
458 | stream_t stream = NULL; | ||
459 | char buf[1024]; | ||
460 | off_t offset = 0; | ||
461 | unsigned char md5digest[16]; | ||
462 | char *tmp; | ||
463 | n = 0; | ||
464 | message_get_stream (msg, &stream); | ||
465 | md5_init_ctx (&md5context); | ||
466 | while (stream_read (stream, buf, sizeof (buf), offset, &n) == 0 | ||
467 | && n > 0) | ||
468 | { | ||
469 | md5_process_bytes (buf, n, &md5context); | ||
470 | offset += n; | ||
471 | } | ||
472 | md5_finish_ctx (&md5context, md5digest); | ||
473 | tmp = buf; | ||
474 | for (n = 0; n < 16; n++, tmp += 2) | ||
475 | sprintf (tmp, "%02x", md5digest[n]); | ||
476 | *tmp = '\0'; | ||
477 | header_set_value (header, "X-UIDL", buf, 1); | ||
478 | buflen--; /* leave space for the NULL. */ | ||
479 | strncpy (buffer, buf, buflen)[buflen] = '\0'; | ||
480 | } | ||
440 | return status; | 481 | return status; |
441 | } | 482 | } |
442 | 483 | ... | ... |
1 | /* GNU mailutils - a suite of utilities for electronic mail | 1 | /* GNU mailutils - a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Library Public License as published by | 5 | it under the terms of the GNU General Library Public License as published by |
... | @@ -39,7 +39,7 @@ | ... | @@ -39,7 +39,7 @@ |
39 | * Need to prevent re-entry into mime lib, but allow non-blocking re-entry into lib. | 39 | * Need to prevent re-entry into mime lib, but allow non-blocking re-entry into lib. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | static int | 42 | static int |
43 | _mime_is_multipart_digest(mime_t mime) | 43 | _mime_is_multipart_digest(mime_t mime) |
44 | { | 44 | { |
45 | if ( mime->content_type ) | 45 | if ( mime->content_type ) |
... | @@ -47,7 +47,7 @@ _mime_is_multipart_digest(mime_t mime) | ... | @@ -47,7 +47,7 @@ _mime_is_multipart_digest(mime_t mime) |
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int | 50 | static int |
51 | _mime_append_part(mime_t mime, message_t msg, int offset, int len, int lines) | 51 | _mime_append_part(mime_t mime, message_t msg, int offset, int len, int lines) |
52 | { | 52 | { |
53 | struct _mime_part *mime_part, **part_arr; | 53 | struct _mime_part *mime_part, **part_arr; |
... | @@ -131,7 +131,7 @@ char *_strtrim(char *str); | ... | @@ -131,7 +131,7 @@ char *_strtrim(char *str); |
131 | || ((c) == '\\') || ((c) == '.') || ((c) == '[') \ | 131 | || ((c) == '\\') || ((c) == '.') || ((c) == '[') \ |
132 | || ((c) == ']') ) | 132 | || ((c) == ']') ) |
133 | 133 | ||
134 | static void | 134 | static void |
135 | _mime_munge_content_header(char *field_body ) | 135 | _mime_munge_content_header(char *field_body ) |
136 | { | 136 | { |
137 | char *p, *e, *str = field_body; | 137 | char *p, *e, *str = field_body; |
... | @@ -195,7 +195,7 @@ _mime_get_param(char *field_body, const char *param, int *len) | ... | @@ -195,7 +195,7 @@ _mime_get_param(char *field_body, const char *param, int *len) |
195 | return NULL; | 195 | return NULL; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int | 198 | static int |
199 | _mime_setup_buffers(mime_t mime) | 199 | _mime_setup_buffers(mime_t mime) |
200 | { | 200 | { |
201 | if ( mime->cur_buf == NULL && ( mime->cur_buf = malloc( mime->buf_size ) ) == NULL ) { | 201 | if ( mime->cur_buf == NULL && ( mime->cur_buf = malloc( mime->buf_size ) ) == NULL ) { |
... | @@ -208,7 +208,7 @@ _mime_setup_buffers(mime_t mime) | ... | @@ -208,7 +208,7 @@ _mime_setup_buffers(mime_t mime) |
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | 210 | ||
211 | static void | 211 | static void |
212 | _mime_append_header_line(mime_t mime) | 212 | _mime_append_header_line(mime_t mime) |
213 | { | 213 | { |
214 | if ( mime->header_length + mime->line_ndx > mime->header_buf_size) { | 214 | if ( mime->header_length + mime->line_ndx > mime->header_buf_size) { |
... | @@ -222,7 +222,7 @@ _mime_append_header_line(mime_t mime) | ... | @@ -222,7 +222,7 @@ _mime_append_header_line(mime_t mime) |
222 | mime->header_length += mime->line_ndx; | 222 | mime->header_length += mime->line_ndx; |
223 | } | 223 | } |
224 | 224 | ||
225 | static int | 225 | static int |
226 | _mime_parse_mpart_message(mime_t mime) | 226 | _mime_parse_mpart_message(mime_t mime) |
227 | { | 227 | { |
228 | char *cp, *cp2; | 228 | char *cp, *cp2; |
... | @@ -323,7 +323,7 @@ _mime_parse_mpart_message(mime_t mime) | ... | @@ -323,7 +323,7 @@ _mime_parse_mpart_message(mime_t mime) |
323 | 323 | ||
324 | /*------ Mime message functions for READING a multipart message -----*/ | 324 | /*------ Mime message functions for READING a multipart message -----*/ |
325 | 325 | ||
326 | static int | 326 | static int |
327 | _mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) | 327 | _mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) |
328 | { | 328 | { |
329 | body_t body = stream_get_owner(stream); | 329 | body_t body = stream_get_owner(stream); |
... | @@ -343,7 +343,7 @@ _mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t | ... | @@ -343,7 +343,7 @@ _mimepart_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t |
343 | return stream_read(mime_part->mime->stream, buf, read_len, mime_part->offset + off, nbytes ); | 343 | return stream_read(mime_part->mime->stream, buf, read_len, mime_part->offset + off, nbytes ); |
344 | } | 344 | } |
345 | 345 | ||
346 | static int | 346 | static int |
347 | _mimepart_body_fd(stream_t stream, int *fd) | 347 | _mimepart_body_fd(stream_t stream, int *fd) |
348 | { | 348 | { |
349 | body_t body = stream_get_owner(stream); | 349 | body_t body = stream_get_owner(stream); |
... | @@ -353,7 +353,7 @@ _mimepart_body_fd(stream_t stream, int *fd) | ... | @@ -353,7 +353,7 @@ _mimepart_body_fd(stream_t stream, int *fd) |
353 | return stream_get_fd(mime_part->mime->stream, fd); | 353 | return stream_get_fd(mime_part->mime->stream, fd); |
354 | } | 354 | } |
355 | 355 | ||
356 | static int | 356 | static int |
357 | _mimepart_body_size (body_t body, size_t *psize) | 357 | _mimepart_body_size (body_t body, size_t *psize) |
358 | { | 358 | { |
359 | message_t msg = body_get_owner(body); | 359 | message_t msg = body_get_owner(body); |
... | @@ -366,7 +366,7 @@ _mimepart_body_size (body_t body, size_t *psize) | ... | @@ -366,7 +366,7 @@ _mimepart_body_size (body_t body, size_t *psize) |
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | static int | 369 | static int |
370 | _mimepart_body_lines (body_t body, size_t *plines) | 370 | _mimepart_body_lines (body_t body, size_t *plines) |
371 | { | 371 | { |
372 | message_t msg = body_get_owner(body); | 372 | message_t msg = body_get_owner(body); |
... | @@ -380,14 +380,14 @@ _mimepart_body_lines (body_t body, size_t *plines) | ... | @@ -380,14 +380,14 @@ _mimepart_body_lines (body_t body, size_t *plines) |
380 | } | 380 | } |
381 | 381 | ||
382 | /*------ Mime message/header functions for CREATING multipart message -----*/ | 382 | /*------ Mime message/header functions for CREATING multipart message -----*/ |
383 | static int | 383 | static int |
384 | _mime_set_content_type(mime_t mime) | 384 | _mime_set_content_type(mime_t mime) |
385 | { | 385 | { |
386 | char content_type[256]; | 386 | char content_type[256]; |
387 | char boundary[128]; | 387 | char boundary[128]; |
388 | header_t hdr = NULL; | 388 | header_t hdr = NULL; |
389 | size_t size; | 389 | size_t size; |
390 | 390 | ||
391 | if ( mime->nmtp_parts > 1 ) { | 391 | if ( mime->nmtp_parts > 1 ) { |
392 | if ( mime->flags & MIME_ADDED_MULTIPART_CT ) | 392 | if ( mime->flags & MIME_ADDED_MULTIPART_CT ) |
393 | return 0; | 393 | return 0; |
... | @@ -421,7 +421,7 @@ _mime_set_content_type(mime_t mime) | ... | @@ -421,7 +421,7 @@ _mime_set_content_type(mime_t mime) |
421 | 421 | ||
422 | #define ADD_CHAR(buf, c, offset, buflen, nbytes) {*(buf)++ = c; (offset)++; (nbytes)++;if (--(buflen) == 0) return 0;} | 422 | #define ADD_CHAR(buf, c, offset, buflen, nbytes) {*(buf)++ = c; (offset)++; (nbytes)++;if (--(buflen) == 0) return 0;} |
423 | 423 | ||
424 | static int | 424 | static int |
425 | _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) | 425 | _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nbytes) |
426 | { | 426 | { |
427 | body_t body = stream_get_owner(stream); | 427 | body_t body = stream_get_owner(stream); |
... | @@ -470,7 +470,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb | ... | @@ -470,7 +470,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb |
470 | } | 470 | } |
471 | while(mime->postamble) { | 471 | while(mime->postamble) { |
472 | mime->postamble--; | 472 | mime->postamble--; |
473 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); | 473 | ADD_CHAR(buf, '-', mime->cur_offset, buflen, *nbytes); |
474 | } | 474 | } |
475 | mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY); | 475 | mime->flags &= ~(MIME_INSERT_BOUNDARY|MIME_ADDING_BOUNDARY); |
476 | mime->part_offset = 0; | 476 | mime->part_offset = 0; |
... | @@ -502,7 +502,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb | ... | @@ -502,7 +502,7 @@ _mime_body_read(stream_t stream, char *buf, size_t buflen, off_t off, size_t *nb |
502 | return ret; | 502 | return ret; |
503 | } | 503 | } |
504 | 504 | ||
505 | static int | 505 | static int |
506 | _mime_body_fd(stream_t stream, int *fd) | 506 | _mime_body_fd(stream_t stream, int *fd) |
507 | { | 507 | { |
508 | body_t body = stream_get_owner(stream); | 508 | body_t body = stream_get_owner(stream); |
... | @@ -516,7 +516,7 @@ _mime_body_fd(stream_t stream, int *fd) | ... | @@ -516,7 +516,7 @@ _mime_body_fd(stream_t stream, int *fd) |
516 | return stream_get_fd(msg_stream, fd); | 516 | return stream_get_fd(msg_stream, fd); |
517 | } | 517 | } |
518 | 518 | ||
519 | static int | 519 | static int |
520 | _mime_body_size (body_t body, size_t *psize) | 520 | _mime_body_size (body_t body, size_t *psize) |
521 | { | 521 | { |
522 | message_t msg = body_get_owner(body); | 522 | message_t msg = body_get_owner(body); |
... | @@ -541,7 +541,7 @@ _mime_body_size (body_t body, size_t *psize) | ... | @@ -541,7 +541,7 @@ _mime_body_size (body_t body, size_t *psize) |
541 | return 0; | 541 | return 0; |
542 | } | 542 | } |
543 | 543 | ||
544 | static int | 544 | static int |
545 | _mime_body_lines (body_t body, size_t *plines) | 545 | _mime_body_lines (body_t body, size_t *plines) |
546 | { | 546 | { |
547 | message_t msg = body_get_owner(body); | 547 | message_t msg = body_get_owner(body); |
... | @@ -563,7 +563,7 @@ _mime_body_lines (body_t body, size_t *plines) | ... | @@ -563,7 +563,7 @@ _mime_body_lines (body_t body, size_t *plines) |
563 | return 0; | 563 | return 0; |
564 | } | 564 | } |
565 | 565 | ||
566 | int | 566 | int |
567 | mime_create(mime_t *pmime, message_t msg, int flags) | 567 | mime_create(mime_t *pmime, message_t msg, int flags) |
568 | { | 568 | { |
569 | mime_t mime = NULL; | 569 | mime_t mime = NULL; |
... | @@ -611,7 +611,7 @@ mime_create(mime_t *pmime, message_t msg, int flags) | ... | @@ -611,7 +611,7 @@ mime_create(mime_t *pmime, message_t msg, int flags) |
611 | return ret; | 611 | return ret; |
612 | } | 612 | } |
613 | 613 | ||
614 | void | 614 | void |
615 | mime_destroy(mime_t *pmime) | 615 | mime_destroy(mime_t *pmime) |
616 | { | 616 | { |
617 | mime_t mime; | 617 | mime_t mime; |
... | @@ -648,8 +648,8 @@ mime_destroy(mime_t *pmime) | ... | @@ -648,8 +648,8 @@ mime_destroy(mime_t *pmime) |
648 | } | 648 | } |
649 | } | 649 | } |
650 | 650 | ||
651 | int | 651 | int |
652 | mime_get_part(mime_t mime, int part, message_t *msg) | 652 | mime_get_part(mime_t mime, size_t part, message_t *msg) |
653 | { | 653 | { |
654 | size_t nmtp_parts; | 654 | size_t nmtp_parts; |
655 | int ret = 0; | 655 | int ret = 0; |
... | @@ -681,7 +681,7 @@ mime_get_part(mime_t mime, int part, message_t *msg) | ... | @@ -681,7 +681,7 @@ mime_get_part(mime_t mime, int part, message_t *msg) |
681 | return ret; | 681 | return ret; |
682 | } | 682 | } |
683 | 683 | ||
684 | int | 684 | int |
685 | mime_get_num_parts(mime_t mime, size_t *nmtp_parts) | 685 | mime_get_num_parts(mime_t mime, size_t *nmtp_parts) |
686 | { | 686 | { |
687 | int ret = 0; | 687 | int ret = 0; |
... | @@ -698,11 +698,11 @@ mime_get_num_parts(mime_t mime, size_t *nmtp_parts) | ... | @@ -698,11 +698,11 @@ mime_get_num_parts(mime_t mime, size_t *nmtp_parts) |
698 | 698 | ||
699 | } | 699 | } |
700 | 700 | ||
701 | int | 701 | int |
702 | mime_add_part(mime_t mime, message_t msg) | 702 | mime_add_part(mime_t mime, message_t msg) |
703 | { | 703 | { |
704 | int ret; | 704 | int ret; |
705 | 705 | ||
706 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) | 706 | if ( mime == NULL || msg == NULL || ( mime->flags & MIME_NEW_MESSAGE ) == 0 ) |
707 | return EINVAL; | 707 | return EINVAL; |
708 | if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 ) | 708 | if ( ( ret = _mime_append_part(mime, msg, 0, 0, 0) ) == 0 ) |
... | @@ -710,7 +710,7 @@ mime_add_part(mime_t mime, message_t msg) | ... | @@ -710,7 +710,7 @@ mime_add_part(mime_t mime, message_t msg) |
710 | return ret; | 710 | return ret; |
711 | } | 711 | } |
712 | 712 | ||
713 | int | 713 | int |
714 | mime_get_message(mime_t mime, message_t *msg) | 714 | mime_get_message(mime_t mime, message_t *msg) |
715 | { | 715 | { |
716 | stream_t body_stream; | 716 | stream_t body_stream; |
... | @@ -749,7 +749,7 @@ mime_get_message(mime_t mime, message_t *msg) | ... | @@ -749,7 +749,7 @@ mime_get_message(mime_t mime, message_t *msg) |
749 | return ret; | 749 | return ret; |
750 | } | 750 | } |
751 | 751 | ||
752 | int | 752 | int |
753 | mime_is_multipart(mime_t mime) | 753 | mime_is_multipart(mime_t mime) |
754 | { | 754 | { |
755 | if ( mime->content_type ) | 755 | if ( mime->content_type ) | ... | ... |
-
Please register or sign in to post a comment