According to rfc2060 the minimum timeout is 30 minutes. But
it is not unusual to see server with a shorter timeout. When the timeout occurs, the server sends a BYE. To catch this all functions in folder_imap.c and mbx_imap.c use a proloque folder_open() or imap_messages_count to check if the server timedout and reconnect. This is not bullet proof since the "* BYE" will be act upon on the second request, the first is where we catch "* BYE". On mailbox2 this behaviour will be disable/enable with a property and make more reliable, so client set the property "AUTORECONNECT". * mailbox/folder_imap.c: Prologue to must functions calling folder_open(). * mailbox/mbx_imap.c: Proloque to must functions calling folder_open() or imap_messages_count. (section_name): Buglet passed the wrong argument to sizeof(). For debugging purposes, to see the traffic * mailbox/folder_imap.c: Print to stderr the command sent to the IMAP server. #define DEBUG_SHOW_COMMAND 1 Print to stderr the responses received from the IMAP server. #define DEBUG_SHOW_RESPONSE 1 Print to stderr the literal/quoted string received from the IMAP server. #define DEBUG_SHOW_DATA 1
Showing
2 changed files
with
123 additions
and
39 deletions
... | @@ -38,6 +38,14 @@ | ... | @@ -38,6 +38,14 @@ |
38 | #include <imap0.h> | 38 | #include <imap0.h> |
39 | #include <mailutils/error.h> | 39 | #include <mailutils/error.h> |
40 | 40 | ||
41 | /* For dbg purposes set to one to see different level of traffic. */ | ||
42 | /* Print to stderr the command sent to the IMAP server. */ | ||
43 | #define DEBUG_SHOW_COMMAND 0 | ||
44 | /* Print to stderr the responses received from the IMAP server. */ | ||
45 | #define DEBUG_SHOW_RESPONSE 0 | ||
46 | /* Print to stderr the literal/quoted string received from the IMAP server. */ | ||
47 | #define DEBUG_SHOW_DATA 0 | ||
48 | |||
41 | /* Variable use for the registrar. */ | 49 | /* Variable use for the registrar. */ |
42 | static struct _record _imap_record = | 50 | static struct _record _imap_record = |
43 | { | 51 | { |
... | @@ -262,7 +270,7 @@ folder_imap_open (folder_t folder, int flags) | ... | @@ -262,7 +270,7 @@ folder_imap_open (folder_t folder, int flags) |
262 | in IMAP. We start with 255, which is quite reasonnable and grow | 270 | in IMAP. We start with 255, which is quite reasonnable and grow |
263 | as we go along. */ | 271 | as we go along. */ |
264 | f_imap->buflen = 255; | 272 | f_imap->buflen = 255; |
265 | f_imap->buffer = calloc (f_imap->buflen + 1, sizeof (char)); | 273 | f_imap->buffer = calloc (f_imap->buflen + 1, 1); |
266 | if (f_imap->buffer == NULL) | 274 | if (f_imap->buffer == NULL) |
267 | { | 275 | { |
268 | CHECK_ERROR (f_imap, ENOMEM); | 276 | CHECK_ERROR (f_imap, ENOMEM); |
... | @@ -463,6 +471,11 @@ folder_imap_delete (folder_t folder, const char *name) | ... | @@ -463,6 +471,11 @@ folder_imap_delete (folder_t folder, const char *name) |
463 | 471 | ||
464 | if (name == NULL) | 472 | if (name == NULL) |
465 | return EINVAL; | 473 | return EINVAL; |
474 | |||
475 | status = folder_open (folder, folder->flags); | ||
476 | if (status != 0) | ||
477 | return status; | ||
478 | |||
466 | switch (f_imap->state) | 479 | switch (f_imap->state) |
467 | { | 480 | { |
468 | case IMAP_NO_STATE: | 481 | case IMAP_NO_STATE: |
... | @@ -505,6 +518,10 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, | ... | @@ -505,6 +518,10 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, |
505 | if (pflist == NULL) | 518 | if (pflist == NULL) |
506 | return EINVAL; | 519 | return EINVAL; |
507 | 520 | ||
521 | status = folder_open (folder, folder->flags); | ||
522 | if (status != 0) | ||
523 | return status; | ||
524 | |||
508 | if (ref == NULL) | 525 | if (ref == NULL) |
509 | ref = ""; | 526 | ref = ""; |
510 | if (name == NULL) | 527 | if (name == NULL) |
... | @@ -541,7 +558,7 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, | ... | @@ -541,7 +558,7 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, |
541 | const char *s = strchr (p, '/'); | 558 | const char *s = strchr (p, '/'); |
542 | if (s) | 559 | if (s) |
543 | { | 560 | { |
544 | node[nodelen] = calloc (s - p + 1, sizeof (char)); | 561 | node[nodelen] = calloc (s - p + 1, 1); |
545 | if (node[nodelen]) | 562 | if (node[nodelen]) |
546 | memcpy (node[nodelen], p, s - p); | 563 | memcpy (node[nodelen], p, s - p); |
547 | p = s; | 564 | p = s; |
... | @@ -651,6 +668,10 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, | ... | @@ -651,6 +668,10 @@ folder_imap_lsub (folder_t folder, const char *ref, const char *name, |
651 | if (pflist == NULL) | 668 | if (pflist == NULL) |
652 | return EINVAL; | 669 | return EINVAL; |
653 | 670 | ||
671 | status = folder_open (folder, folder->flags); | ||
672 | if (status != 0) | ||
673 | return status; | ||
674 | |||
654 | if (ref == NULL) ref = ""; | 675 | if (ref == NULL) ref = ""; |
655 | if (name == NULL) name = ""; | 676 | if (name == NULL) name = ""; |
656 | 677 | ||
... | @@ -719,6 +740,10 @@ folder_imap_rename (folder_t folder, const char *oldpath, const char *newpath) | ... | @@ -719,6 +740,10 @@ folder_imap_rename (folder_t folder, const char *oldpath, const char *newpath) |
719 | if (oldpath == NULL || newpath == NULL) | 740 | if (oldpath == NULL || newpath == NULL) |
720 | return EINVAL; | 741 | return EINVAL; |
721 | 742 | ||
743 | status = folder_open (folder, folder->flags); | ||
744 | if (status != 0) | ||
745 | return status; | ||
746 | |||
722 | switch (f_imap->state) | 747 | switch (f_imap->state) |
723 | { | 748 | { |
724 | case IMAP_NO_STATE: | 749 | case IMAP_NO_STATE: |
... | @@ -751,6 +776,10 @@ folder_imap_subscribe (folder_t folder, const char *name) | ... | @@ -751,6 +776,10 @@ folder_imap_subscribe (folder_t folder, const char *name) |
751 | f_imap_t f_imap = folder->data; | 776 | f_imap_t f_imap = folder->data; |
752 | int status = 0; | 777 | int status = 0; |
753 | 778 | ||
779 | status = folder_open (folder, folder->flags); | ||
780 | if (status != 0) | ||
781 | return status; | ||
782 | |||
754 | if (name == NULL) | 783 | if (name == NULL) |
755 | return EINVAL; | 784 | return EINVAL; |
756 | switch (f_imap->state) | 785 | switch (f_imap->state) |
... | @@ -785,6 +814,10 @@ folder_imap_unsubscribe (folder_t folder, const char *name) | ... | @@ -785,6 +814,10 @@ folder_imap_unsubscribe (folder_t folder, const char *name) |
785 | f_imap_t f_imap = folder->data; | 814 | f_imap_t f_imap = folder->data; |
786 | int status = 0; | 815 | int status = 0; |
787 | 816 | ||
817 | status = folder_open (folder, folder->flags); | ||
818 | if (status != 0) | ||
819 | return status; | ||
820 | |||
788 | if (name == NULL) | 821 | if (name == NULL) |
789 | return EINVAL; | 822 | return EINVAL; |
790 | switch (f_imap->state) | 823 | switch (f_imap->state) |
... | @@ -827,7 +860,8 @@ imap_literal_string (f_imap_t f_imap, char **ptr) | ... | @@ -827,7 +860,8 @@ imap_literal_string (f_imap_t f_imap, char **ptr) |
827 | for (len0 = len = total = 0; total < f_imap->string.nleft; total += (len + 1)) | 860 | for (len0 = len = total = 0; total < f_imap->string.nleft; total += (len + 1)) |
828 | { | 861 | { |
829 | status = imap_readline (f_imap); | 862 | status = imap_readline (f_imap); |
830 | /*fprintf (stderr, "%d: %s", strlen (f_imap->buffer), f_imap->buffer);*/ | 863 | if (DEBUG_SHOW_DATA) |
864 | fprintf (stderr, "%s", f_imap->buffer); | ||
831 | if (status != 0) | 865 | if (status != 0) |
832 | { | 866 | { |
833 | /* Return what we got so far. */ | 867 | /* Return what we got so far. */ |
... | @@ -919,6 +953,8 @@ imap_quoted_string (f_imap_t f_imap, char **ptr) | ... | @@ -919,6 +953,8 @@ imap_quoted_string (f_imap_t f_imap, char **ptr) |
919 | f_imap->string.offset += len; | 953 | f_imap->string.offset += len; |
920 | if (**ptr == '"') | 954 | if (**ptr == '"') |
921 | (*ptr)++; | 955 | (*ptr)++; |
956 | if (DEBUG_SHOW_DATA) | ||
957 | fprintf (stderr, "%.*s", len, bquote); | ||
922 | return 0; | 958 | return 0; |
923 | } | 959 | } |
924 | 960 | ||
... | @@ -1030,7 +1066,7 @@ imap_list (f_imap_t f_imap) | ... | @@ -1030,7 +1066,7 @@ imap_list (f_imap_t f_imap) |
1030 | if (s) | 1066 | if (s) |
1031 | { | 1067 | { |
1032 | size_t n = strtoul (s + 1, NULL, 10); | 1068 | size_t n = strtoul (s + 1, NULL, 10); |
1033 | lr->name = calloc (n + 1, sizeof (char)); | 1069 | lr->name = calloc (n + 1, 1); |
1034 | f_imap->ptr = f_imap->buffer; | 1070 | f_imap->ptr = f_imap->buffer; |
1035 | imap_readline (f_imap); | 1071 | imap_readline (f_imap); |
1036 | memcpy (lr->name, f_imap->buffer, n); | 1072 | memcpy (lr->name, f_imap->buffer, n); |
... | @@ -1060,7 +1096,7 @@ section_name (msg_imap_t msg_imap) | ... | @@ -1060,7 +1096,7 @@ section_name (msg_imap_t msg_imap) |
1060 | char *tmp; | 1096 | char *tmp; |
1061 | char part[64]; | 1097 | char part[64]; |
1062 | size_t partlen; | 1098 | size_t partlen; |
1063 | snprintf (part, sizeof (partlen), "%u", msg_imap->part); | 1099 | snprintf (part, sizeof part, "%u", msg_imap->part); |
1064 | partlen = strlen (part); | 1100 | partlen = strlen (part); |
1065 | tmp = realloc (section, sectionlen + partlen + 2); | 1101 | tmp = realloc (section, sectionlen + partlen + 2); |
1066 | if (tmp == NULL) | 1102 | if (tmp == NULL) |
... | @@ -1397,7 +1433,7 @@ static int | ... | @@ -1397,7 +1433,7 @@ static int |
1397 | imap_uid (f_imap_t f_imap, char **ptr) | 1433 | imap_uid (f_imap_t f_imap, char **ptr) |
1398 | { | 1434 | { |
1399 | char token[128]; | 1435 | char token[128]; |
1400 | imap_token (token, sizeof (token), ptr); | 1436 | imap_token (token, sizeof token, ptr); |
1401 | if (f_imap->string.msg_imap) | 1437 | if (f_imap->string.msg_imap) |
1402 | f_imap->string.msg_imap->uid = strtoul (token, NULL, 10); | 1438 | f_imap->string.msg_imap->uid = strtoul (token, NULL, 10); |
1403 | return 0; | 1439 | return 0; |
... | @@ -1417,7 +1453,7 @@ static int | ... | @@ -1417,7 +1453,7 @@ static int |
1417 | imap_rfc822_size (f_imap_t f_imap, char **ptr) | 1453 | imap_rfc822_size (f_imap_t f_imap, char **ptr) |
1418 | { | 1454 | { |
1419 | char token[128]; | 1455 | char token[128]; |
1420 | imap_token (token, sizeof (token), ptr); | 1456 | imap_token (token, sizeof token, ptr); |
1421 | if (f_imap->string.msg_imap) | 1457 | if (f_imap->string.msg_imap) |
1422 | f_imap->string.msg_imap->message_size = strtoul (token, NULL, 10); | 1458 | f_imap->string.msg_imap->message_size = strtoul (token, NULL, 10); |
1423 | return 0; | 1459 | return 0; |
... | @@ -1477,12 +1513,12 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1477,12 +1513,12 @@ imap_fetch (f_imap_t f_imap) |
1477 | sp = f_imap->buffer; | 1513 | sp = f_imap->buffer; |
1478 | 1514 | ||
1479 | /* Skip untag '*'. */ | 1515 | /* Skip untag '*'. */ |
1480 | imap_token (token, sizeof (token), &sp); | 1516 | imap_token (token, sizeof token, &sp); |
1481 | /* Get msgno. */ | 1517 | /* Get msgno. */ |
1482 | imap_token (token, sizeof (token), &sp); | 1518 | imap_token (token, sizeof token, &sp); |
1483 | msgno = strtol (token, NULL, 10); | 1519 | msgno = strtol (token, NULL, 10); |
1484 | /* Skip FETCH . */ | 1520 | /* Skip FETCH . */ |
1485 | imap_token (token, sizeof (token), &sp); | 1521 | imap_token (token, sizeof token, &sp); |
1486 | 1522 | ||
1487 | /* It is actually possible, but higly unlikely that we do not have the | 1523 | /* It is actually possible, but higly unlikely that we do not have the |
1488 | message yet, for example a "FETCH (FLAGS (\Recent))" notification | 1524 | message yet, for example a "FETCH (FLAGS (\Recent))" notification |
... | @@ -1508,7 +1544,7 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1508,7 +1544,7 @@ imap_fetch (f_imap_t f_imap) |
1508 | while (*sp && *sp != ')') | 1544 | while (*sp && *sp != ')') |
1509 | { | 1545 | { |
1510 | /* Get the token. */ | 1546 | /* Get the token. */ |
1511 | imap_token (token, sizeof (token), &sp); | 1547 | imap_token (token, sizeof token, &sp); |
1512 | 1548 | ||
1513 | if (strncmp (token, "FLAGS", 5) == 0) | 1549 | if (strncmp (token, "FLAGS", 5) == 0) |
1514 | { | 1550 | { |
... | @@ -1534,7 +1570,7 @@ imap_fetch (f_imap_t f_imap) | ... | @@ -1534,7 +1570,7 @@ imap_fetch (f_imap_t f_imap) |
1534 | if (*sp == '.') | 1570 | if (*sp == '.') |
1535 | { | 1571 | { |
1536 | sp++; | 1572 | sp++; |
1537 | imap_token (token, sizeof (token), &sp); | 1573 | imap_token (token, sizeof token, &sp); |
1538 | if (strcasecmp (token, "SIZE") == 0) | 1574 | if (strcasecmp (token, "SIZE") == 0) |
1539 | { | 1575 | { |
1540 | status = imap_rfc822_size (f_imap, &sp); | 1576 | status = imap_rfc822_size (f_imap, &sp); |
... | @@ -1589,6 +1625,9 @@ imap_expunge (f_imap_t f_imap, unsigned msgno) | ... | @@ -1589,6 +1625,9 @@ imap_expunge (f_imap_t f_imap, unsigned msgno) |
1589 | } | 1625 | } |
1590 | 1626 | ||
1591 | 1627 | ||
1628 | /* This function will advance ptr to the next character that IMAP | ||
1629 | recognise as special: " .()[]<>" and put the result in buf which | ||
1630 | is of size len. */ | ||
1592 | static int | 1631 | static int |
1593 | imap_token (char *buf, size_t len, char **ptr) | 1632 | imap_token (char *buf, size_t len, char **ptr) |
1594 | { | 1633 | { |
... | @@ -1649,6 +1688,9 @@ imap_writeline (f_imap_t f_imap, const char *format, ...) | ... | @@ -1649,6 +1688,9 @@ imap_writeline (f_imap_t f_imap, const char *format, ...) |
1649 | while (!done); | 1688 | while (!done); |
1650 | va_end(ap); | 1689 | va_end(ap); |
1651 | f_imap->ptr = f_imap->buffer + len; | 1690 | f_imap->ptr = f_imap->buffer + len; |
1691 | |||
1692 | if (DEBUG_SHOW_COMMAND) | ||
1693 | fprintf (stderr, "%s", f_imap->buffer); | ||
1652 | return 0; | 1694 | return 0; |
1653 | } | 1695 | } |
1654 | 1696 | ||
... | @@ -1801,10 +1843,9 @@ imap_parse (f_imap_t f_imap) | ... | @@ -1801,10 +1843,9 @@ imap_parse (f_imap_t f_imap) |
1801 | { | 1843 | { |
1802 | break; | 1844 | break; |
1803 | } | 1845 | } |
1804 | #if 0 | ||
1805 | /* Comment out to see all reading traffic. */ | 1846 | /* Comment out to see all reading traffic. */ |
1847 | if (DEBUG_SHOW_RESPONSE) | ||
1806 | mu_error ("\t\t%s", f_imap->buffer); | 1848 | mu_error ("\t\t%s", f_imap->buffer); |
1807 | #endif | ||
1808 | 1849 | ||
1809 | /* We do not want to step over f_imap->buffer since it can be use | 1850 | /* We do not want to step over f_imap->buffer since it can be use |
1810 | further down the chain. */ | 1851 | further down the chain. */ | ... | ... |
... | @@ -503,14 +503,11 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) | ... | @@ -503,14 +503,11 @@ imap_messages_count (mailbox_t mailbox, size_t *pnum) |
503 | int status = 0; | 503 | int status = 0; |
504 | 504 | ||
505 | /* FIXME: It is debatable if we should reconnect when the connection | 505 | /* FIXME: It is debatable if we should reconnect when the connection |
506 | timeout or die. For timeout client should ping i.e. send | 506 | timeout or die. Probably for timeout client should ping i.e. send |
507 | a NOOP via imap_is_updated() function to keep the connection alive. */ | 507 | a NOOP via imap_is_updated() function to keep the connection alive. */ |
508 | if (!f_imap->isopen) | ||
509 | { | ||
510 | status = folder_open (mailbox->folder, mailbox->flags); | 508 | status = folder_open (mailbox->folder, mailbox->flags); |
511 | if (status != 0) | 509 | if (status != 0) |
512 | return status; | 510 | return status; |
513 | } | ||
514 | 511 | ||
515 | /* Are we already selected ? */ | 512 | /* Are we already selected ? */ |
516 | if (m_imap == (f_imap->selected)) | 513 | if (m_imap == (f_imap->selected)) |
... | @@ -760,6 +757,14 @@ imap_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -760,6 +757,14 @@ imap_append_message (mailbox_t mailbox, message_t msg) |
760 | m_imap_t m_imap = mailbox->data; | 757 | m_imap_t m_imap = mailbox->data; |
761 | f_imap_t f_imap = m_imap->f_imap; | 758 | f_imap_t f_imap = m_imap->f_imap; |
762 | 759 | ||
760 | |||
761 | /* FIXME: It is debatable if we should reconnect when the connection | ||
762 | timeout or die. For timeout client should ping i.e. send | ||
763 | a NOOP via imap_is_updated() function to keep the connection alive. */ | ||
764 | status = folder_open (mailbox->folder, mailbox->flags); | ||
765 | if (status != 0) | ||
766 | return status; | ||
767 | |||
763 | /* FIXME: Can we append to self. */ | 768 | /* FIXME: Can we append to self. */ |
764 | 769 | ||
765 | /* Check to see if we are selected. If the message was not modified | 770 | /* Check to see if we are selected. If the message was not modified |
... | @@ -905,6 +910,13 @@ imap_copy_message (mailbox_t mailbox, message_t msg) | ... | @@ -905,6 +910,13 @@ imap_copy_message (mailbox_t mailbox, message_t msg) |
905 | msg_imap_t msg_imap = message_get_owner (msg); | 910 | msg_imap_t msg_imap = message_get_owner (msg); |
906 | int status = 0; | 911 | int status = 0; |
907 | 912 | ||
913 | /* FIXME: It is debatable if we should reconnect when the connection | ||
914 | timeout or die. For timeout client should ping i.e. send | ||
915 | a NOOP via imap_is_updated() function to keep the connection alive. */ | ||
916 | status = folder_open (mailbox->folder, mailbox->flags); | ||
917 | if (status != 0) | ||
918 | return status; | ||
919 | |||
908 | switch (f_imap->state) | 920 | switch (f_imap->state) |
909 | { | 921 | { |
910 | case IMAP_NO_STATE: | 922 | case IMAP_NO_STATE: |
... | @@ -974,13 +986,14 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, | ... | @@ -974,13 +986,14 @@ imap_message_read (stream_t stream, char *buffer, size_t buflen, |
974 | if (offset == 0) | 986 | if (offset == 0) |
975 | msg_imap->message_lines = 0; | 987 | msg_imap->message_lines = 0; |
976 | 988 | ||
989 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
990 | if (status != 0) | ||
991 | return status; | ||
992 | |||
977 | /* Select first. */ | 993 | /* Select first. */ |
978 | if (f_imap->state == IMAP_NO_STATE) | 994 | if (f_imap->state == IMAP_NO_STATE) |
979 | { | 995 | { |
980 | char *section = NULL; | 996 | char *section = NULL; |
981 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
982 | if (status != 0) | ||
983 | return status; | ||
984 | 997 | ||
985 | if (msg_imap->part) | 998 | if (msg_imap->part) |
986 | section = section_name (msg_imap); | 999 | section = section_name (msg_imap); |
... | @@ -1034,7 +1047,6 @@ imap_submessage_size (msg_imap_t msg_imap, size_t *psize) | ... | @@ -1034,7 +1047,6 @@ imap_submessage_size (msg_imap_t msg_imap, size_t *psize) |
1034 | size_t i, size; | 1047 | size_t i, size; |
1035 | for (size = i = 0; i < msg_imap->num_parts; i++, size = 0) | 1048 | for (size = i = 0; i < msg_imap->num_parts; i++, size = 0) |
1036 | { | 1049 | { |
1037 | |||
1038 | if (msg_imap->parts[i]) | 1050 | if (msg_imap->parts[i]) |
1039 | imap_submessage_size (msg_imap->parts[i], &size); | 1051 | imap_submessage_size (msg_imap->parts[i], &size); |
1040 | *psize += size; | 1052 | *psize += size; |
... | @@ -1055,6 +1067,10 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -1055,6 +1067,10 @@ imap_message_size (message_t msg, size_t *psize) |
1055 | f_imap_t f_imap = m_imap->f_imap; | 1067 | f_imap_t f_imap = m_imap->f_imap; |
1056 | int status = 0;; | 1068 | int status = 0;; |
1057 | 1069 | ||
1070 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1071 | if (status != 0) | ||
1072 | return status; | ||
1073 | |||
1058 | /* If there is a parent it means it is a sub message, IMAP does not give | 1074 | /* If there is a parent it means it is a sub message, IMAP does not give |
1059 | the full size of mime messages, so the message_size retrieved from | 1075 | the full size of mime messages, so the message_size retrieved from |
1060 | doing a bodystructure represents rather the body_size. */ | 1076 | doing a bodystructure represents rather the body_size. */ |
... | @@ -1066,9 +1082,6 @@ imap_message_size (message_t msg, size_t *psize) | ... | @@ -1066,9 +1082,6 @@ imap_message_size (message_t msg, size_t *psize) |
1066 | /* Select first. */ | 1082 | /* Select first. */ |
1067 | if (f_imap->state == IMAP_NO_STATE) | 1083 | if (f_imap->state == IMAP_NO_STATE) |
1068 | { | 1084 | { |
1069 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1070 | if (status != 0) | ||
1071 | return status; | ||
1072 | /* We strip the \r, but the offset/size on the imap server is with | 1085 | /* We strip the \r, but the offset/size on the imap server is with |
1073 | that octet so add it in the offset, since it's the number of | 1086 | that octet so add it in the offset, since it's the number of |
1074 | lines. */ | 1087 | lines. */ |
... | @@ -1100,7 +1113,12 @@ imap_message_uid (message_t msg, size_t *puid) | ... | @@ -1100,7 +1113,12 @@ imap_message_uid (message_t msg, size_t *puid) |
1100 | 1113 | ||
1101 | if (puid) | 1114 | if (puid) |
1102 | return 0; | 1115 | return 0; |
1116 | |||
1103 | /* Select first. */ | 1117 | /* Select first. */ |
1118 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1119 | if (status != 0) | ||
1120 | return status; | ||
1121 | |||
1104 | if (f_imap->state == IMAP_NO_STATE) | 1122 | if (f_imap->state == IMAP_NO_STATE) |
1105 | { | 1123 | { |
1106 | if (msg_imap->uid) | 1124 | if (msg_imap->uid) |
... | @@ -1108,9 +1126,6 @@ imap_message_uid (message_t msg, size_t *puid) | ... | @@ -1108,9 +1126,6 @@ imap_message_uid (message_t msg, size_t *puid) |
1108 | *puid = msg_imap->uid; | 1126 | *puid = msg_imap->uid; |
1109 | return 0; | 1127 | return 0; |
1110 | } | 1128 | } |
1111 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1112 | if (status != 0) | ||
1113 | return status; | ||
1114 | status = imap_writeline (f_imap, "g%d FETCH %d UID\r\n", | 1129 | status = imap_writeline (f_imap, "g%d FETCH %d UID\r\n", |
1115 | f_imap->seq++, msg_imap->num); | 1130 | f_imap->seq++, msg_imap->num); |
1116 | CHECK_ERROR (f_imap, status); | 1131 | CHECK_ERROR (f_imap, status); |
... | @@ -1142,6 +1157,10 @@ imap_is_multipart (message_t msg, int *ismulti) | ... | @@ -1142,6 +1157,10 @@ imap_is_multipart (message_t msg, int *ismulti) |
1142 | int status; | 1157 | int status; |
1143 | 1158 | ||
1144 | /* Select first. */ | 1159 | /* Select first. */ |
1160 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1161 | if (status != 0) | ||
1162 | return status; | ||
1163 | |||
1145 | if (f_imap->state == IMAP_NO_STATE) | 1164 | if (f_imap->state == IMAP_NO_STATE) |
1146 | { | 1165 | { |
1147 | if (msg_imap->num_parts || msg_imap->part) | 1166 | if (msg_imap->num_parts || msg_imap->part) |
... | @@ -1150,9 +1169,6 @@ imap_is_multipart (message_t msg, int *ismulti) | ... | @@ -1150,9 +1169,6 @@ imap_is_multipart (message_t msg, int *ismulti) |
1150 | *ismulti = (msg_imap->num_parts > 1); | 1169 | *ismulti = (msg_imap->num_parts > 1); |
1151 | return 0; | 1170 | return 0; |
1152 | } | 1171 | } |
1153 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1154 | if (status != 0) | ||
1155 | return status; | ||
1156 | status = imap_writeline (f_imap, | 1172 | status = imap_writeline (f_imap, |
1157 | "g%d FETCH %d BODYSTRUCTURE\r\n", | 1173 | "g%d FETCH %d BODYSTRUCTURE\r\n", |
1158 | f_imap->seq++, msg_imap->num); | 1174 | f_imap->seq++, msg_imap->num); |
... | @@ -1284,14 +1300,14 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, | ... | @@ -1284,14 +1300,14 @@ imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, |
1284 | /* reserve as much space as we need for internal-date */ | 1300 | /* reserve as much space as we need for internal-date */ |
1285 | int status; | 1301 | int status; |
1286 | 1302 | ||
1287 | if (msg_imap->internal_date == NULL) | ||
1288 | { | ||
1289 | if (f_imap->state == IMAP_NO_STATE) | ||
1290 | { | ||
1291 | /* Select first. */ | 1303 | /* Select first. */ |
1292 | status = imap_messages_count (m_imap->mailbox, NULL); | 1304 | status = imap_messages_count (m_imap->mailbox, NULL); |
1293 | if (status != 0) | 1305 | if (status != 0) |
1294 | return status; | 1306 | return status; |
1307 | if (msg_imap->internal_date == NULL) | ||
1308 | { | ||
1309 | if (f_imap->state == IMAP_NO_STATE) | ||
1310 | { | ||
1295 | status = imap_writeline (f_imap, | 1311 | status = imap_writeline (f_imap, |
1296 | "g%d FETCH %d INTERNALDATE\r\n", | 1312 | "g%d FETCH %d INTERNALDATE\r\n", |
1297 | f_imap->seq++, msg_imap->num); | 1313 | f_imap->seq++, msg_imap->num); |
... | @@ -1359,6 +1375,11 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) | ... | @@ -1359,6 +1375,11 @@ imap_attr_get_flags (attribute_t attribute, int *pflags) |
1359 | f_imap_t f_imap = m_imap->f_imap; | 1375 | f_imap_t f_imap = m_imap->f_imap; |
1360 | int status = 0; | 1376 | int status = 0; |
1361 | 1377 | ||
1378 | /* Select first. */ | ||
1379 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1380 | if (status != 0) | ||
1381 | return status; | ||
1382 | |||
1362 | /* Did we retrieve it alread ? */ | 1383 | /* Did we retrieve it alread ? */ |
1363 | if (msg_imap->flags != 0) | 1384 | if (msg_imap->flags != 0) |
1364 | { | 1385 | { |
... | @@ -1393,6 +1414,11 @@ imap_attr_set_flags (attribute_t attribute, int flag) | ... | @@ -1393,6 +1414,11 @@ imap_attr_set_flags (attribute_t attribute, int flag) |
1393 | f_imap_t f_imap = m_imap->f_imap; | 1414 | f_imap_t f_imap = m_imap->f_imap; |
1394 | int status = 0; | 1415 | int status = 0; |
1395 | 1416 | ||
1417 | /* Select first. */ | ||
1418 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1419 | if (status != 0) | ||
1420 | return status; | ||
1421 | |||
1396 | /* If already set don't bother. */ | 1422 | /* If already set don't bother. */ |
1397 | if (msg_imap->flags & flag) | 1423 | if (msg_imap->flags & flag) |
1398 | return 0; | 1424 | return 0; |
... | @@ -1439,6 +1465,11 @@ imap_attr_unset_flags (attribute_t attribute, int flag) | ... | @@ -1439,6 +1465,11 @@ imap_attr_unset_flags (attribute_t attribute, int flag) |
1439 | f_imap_t f_imap = m_imap->f_imap; | 1465 | f_imap_t f_imap = m_imap->f_imap; |
1440 | int status = 0; | 1466 | int status = 0; |
1441 | 1467 | ||
1468 | /* Select first. */ | ||
1469 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1470 | if (status != 0) | ||
1471 | return status; | ||
1472 | |||
1442 | /* The delete FLAG is not pass yet but only on the expunge. */ | 1473 | /* The delete FLAG is not pass yet but only on the expunge. */ |
1443 | if (flag & MU_ATTRIBUTE_DELETED) | 1474 | if (flag & MU_ATTRIBUTE_DELETED) |
1444 | { | 1475 | { |
... | @@ -1485,6 +1516,11 @@ imap_header_get_value (header_t header, const char *field, char * buffer, | ... | @@ -1485,6 +1516,11 @@ imap_header_get_value (header_t header, const char *field, char * buffer, |
1485 | size_t len = 0; | 1516 | size_t len = 0; |
1486 | char *value; | 1517 | char *value; |
1487 | 1518 | ||
1519 | /* Select first. */ | ||
1520 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1521 | if (status != 0) | ||
1522 | return status; | ||
1523 | |||
1488 | /* Hack, if buffer == NULL they want to know how big is the field value, | 1524 | /* Hack, if buffer == NULL they want to know how big is the field value, |
1489 | Unfortunately IMAP does not say, so we take a guess hoping that the | 1525 | Unfortunately IMAP does not say, so we take a guess hoping that the |
1490 | value will not be over 1024. */ | 1526 | value will not be over 1024. */ |
... | @@ -1560,6 +1596,11 @@ imap_header_get_fvalue (header_t header, const char *field, char * buffer, | ... | @@ -1560,6 +1596,11 @@ imap_header_get_fvalue (header_t header, const char *field, char * buffer, |
1560 | size_t len = 0; | 1596 | size_t len = 0; |
1561 | char *value; | 1597 | char *value; |
1562 | 1598 | ||
1599 | /* Select first. */ | ||
1600 | status = imap_messages_count (m_imap->mailbox, NULL); | ||
1601 | if (status != 0) | ||
1602 | return status; | ||
1603 | |||
1563 | /* Do we all ready have the headers. */ | 1604 | /* Do we all ready have the headers. */ |
1564 | if (msg_imap->fheader) | 1605 | if (msg_imap->fheader) |
1565 | return header_get_value (msg_imap->fheader, field, buffer, buflen, plen); | 1606 | return header_get_value (msg_imap->fheader, field, buffer, buflen, plen); |
... | @@ -1626,11 +1667,12 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, | ... | @@ -1626,11 +1667,12 @@ imap_header_read (header_t header, char *buffer, size_t buflen, off_t offset, |
1626 | msg_imap->header_lines = 0; | 1667 | msg_imap->header_lines = 0; |
1627 | 1668 | ||
1628 | /* Select first. */ | 1669 | /* Select first. */ |
1629 | if (f_imap->state == IMAP_NO_STATE) | ||
1630 | { | ||
1631 | status = imap_messages_count (m_imap->mailbox, NULL); | 1670 | status = imap_messages_count (m_imap->mailbox, NULL); |
1632 | if (status != 0) | 1671 | if (status != 0) |
1633 | return status; | 1672 | return status; |
1673 | |||
1674 | if (f_imap->state == IMAP_NO_STATE) | ||
1675 | { | ||
1634 | /* We strip the \r, but the offset/size on the imap server is with that | 1676 | /* We strip the \r, but the offset/size on the imap server is with that |
1635 | octet so add it in the offset, since it's the number of lines. */ | 1677 | octet so add it in the offset, since it's the number of lines. */ |
1636 | if (msg_imap->part) | 1678 | if (msg_imap->part) |
... | @@ -1734,11 +1776,12 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, | ... | @@ -1734,11 +1776,12 @@ imap_body_read (stream_t stream, char *buffer, size_t buflen, off_t offset, |
1734 | } | 1776 | } |
1735 | 1777 | ||
1736 | /* Select first. */ | 1778 | /* Select first. */ |
1737 | if (f_imap->state == IMAP_NO_STATE) | ||
1738 | { | ||
1739 | status = imap_messages_count (m_imap->mailbox, NULL); | 1779 | status = imap_messages_count (m_imap->mailbox, NULL); |
1740 | if (status != 0) | 1780 | if (status != 0) |
1741 | return status; | 1781 | return status; |
1782 | |||
1783 | if (f_imap->state == IMAP_NO_STATE) | ||
1784 | { | ||
1742 | /* We strip the \r, but the offset/size on the imap server is with the | 1785 | /* We strip the \r, but the offset/size on the imap server is with the |
1743 | octet, so add it since it's the number of lines. */ | 1786 | octet, so add it since it's the number of lines. */ |
1744 | if (msg_imap->part) | 1787 | if (msg_imap->part) | ... | ... |
-
Please register or sign in to post a comment