Commit 75cd3361 75cd3361ff84d6c8d5a77514e3fd87bb65e058b6 by Alain Magloire

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
1 parent 1227d1dd
...@@ -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)
......