Commit ed3641cb ed3641cbe562fcb9c2eb9abeac8ed53587aaa018 by Sam Roberts

folder_imap_create() - removed, code now in mailbox_imap_open().

imap_mailbox_name_match() - new function, uses strcasecmp() for INBOX,
  since INBOX is itself in any case combination, and fnmatch() otherwise.
imap_list() - mailbox name (an ASTRING) wasn't being unquoted.
folder_imap_list() - always failed to match it's name arg against the
  mailbox name (imap_list needed to unquote the name, and the name
  comparison needed to treat INBOX specially).
1 parent f8fb0dab
...@@ -73,7 +73,6 @@ char *strtok_r __P ((char *, const char *, char **)); ...@@ -73,7 +73,6 @@ char *strtok_r __P ((char *, const char *, char **));
73 73
74 /* Concrete folder_t IMAP implementation. */ 74 /* Concrete folder_t IMAP implementation. */
75 static int folder_imap_open __P ((folder_t, int)); 75 static int folder_imap_open __P ((folder_t, int));
76 static int folder_imap_create __P ((folder_t));
77 static int folder_imap_close __P ((folder_t)); 76 static int folder_imap_close __P ((folder_t));
78 static void folder_imap_destroy __P ((folder_t)); 77 static void folder_imap_destroy __P ((folder_t));
79 static int folder_imap_delete __P ((folder_t, const char *)); 78 static int folder_imap_delete __P ((folder_t, const char *));
...@@ -112,6 +111,7 @@ static int imap_search __P ((f_imap_t)); ...@@ -112,6 +111,7 @@ static int imap_search __P ((f_imap_t));
112 static int imap_literal_string __P ((f_imap_t, char **)); 111 static int imap_literal_string __P ((f_imap_t, char **));
113 static int imap_string __P ((f_imap_t, char **)); 112 static int imap_string __P ((f_imap_t, char **));
114 static int imap_quoted_string __P ((f_imap_t, char **)); 113 static int imap_quoted_string __P ((f_imap_t, char **));
114 static int imap_mailbox_name_match __P ((const char* pattern, const char* mailbox));
115 115
116 static int imap_token __P ((char *, size_t, char **)); 116 static int imap_token __P ((char *, size_t, char **));
117 117
...@@ -246,9 +246,11 @@ authenticate_imap_login (authority_t auth) ...@@ -246,9 +246,11 @@ authenticate_imap_login (authority_t auth)
246 CHECK_ERROR_CLOSE (folder, f_imap, EINVAL); 246 CHECK_ERROR_CLOSE (folder, f_imap, EINVAL);
247 } 247 }
248 status = imap_writeline (f_imap, "g%u LOGIN %s %s\r\n", 248 status = imap_writeline (f_imap, "g%u LOGIN %s %s\r\n",
249 f_imap->seq++, f_imap->user, f_imap->passwd); 249 f_imap->seq, f_imap->user, f_imap->passwd);
250 CHECK_ERROR_CLOSE(folder, f_imap, status); 250 CHECK_ERROR_CLOSE(folder, f_imap, status);
251 FOLDER_DEBUG1 (folder, MU_DEBUG_PROT, "LOGIN %s *\n", f_imap->user); 251 FOLDER_DEBUG2 (folder, MU_DEBUG_PROT, "g%u LOGIN %s *\n",
252 f_imap->seq, f_imap->user);
253 f_imap->seq++;
252 free (f_imap->user); 254 free (f_imap->user);
253 f_imap->user = NULL; 255 f_imap->user = NULL;
254 /* We have to nuke the passwd. */ 256 /* We have to nuke the passwd. */
...@@ -403,8 +405,6 @@ folder_imap_open (folder_t folder, int flags) ...@@ -403,8 +405,6 @@ folder_imap_open (folder_t folder, int flags)
403 if (f_imap->isopen) 405 if (f_imap->isopen)
404 { 406 {
405 monitor_unlock (folder->monitor); 407 monitor_unlock (folder->monitor);
406 if (flags & MU_STREAM_CREAT)
407 status = folder_imap_create (folder);
408 return 0; 408 return 0;
409 } 409 }
410 monitor_unlock (folder->monitor); 410 monitor_unlock (folder->monitor);
...@@ -508,14 +508,10 @@ folder_imap_open (folder_t folder, int flags) ...@@ -508,14 +508,10 @@ folder_imap_open (folder_t folder, int flags)
508 monitor_wrlock (folder->monitor); 508 monitor_wrlock (folder->monitor);
509 f_imap->isopen++; 509 f_imap->isopen++;
510 monitor_unlock (folder->monitor); 510 monitor_unlock (folder->monitor);
511 if (flags & MU_STREAM_CREAT)
512 {
513 status = folder_imap_create (folder);
514 CHECK_EAGAIN (f_imap, status);
515 }
516 return 0; 511 return 0;
517 } 512 }
518 513
514
519 /* Shutdown the connection. */ 515 /* Shutdown the connection. */
520 static int 516 static int
521 folder_imap_close (folder_t folder) 517 folder_imap_close (folder_t folder)
...@@ -562,51 +558,6 @@ folder_imap_close (folder_t folder) ...@@ -562,51 +558,6 @@ folder_imap_close (folder_t folder)
562 return 0; 558 return 0;
563 } 559 }
564 560
565 /* Create a folder/mailbox. */
566 static int
567 folder_imap_create (folder_t folder)
568 {
569 f_imap_t f_imap = folder->data;
570 int status = 0;
571
572 switch (f_imap->state)
573 {
574 case IMAP_NO_STATE:
575 {
576 char *path;
577 size_t len;
578 url_get_path (folder->url, NULL, 0, &len);
579 if (len == 0)
580 return 0;
581 path = calloc (len + 1, sizeof (*path));
582 if (path == NULL)
583 return ENOMEM;
584 url_get_path (folder->url, path, len + 1, NULL);
585 status = imap_writeline (f_imap, "g%u CREATE %s\r\n", f_imap->seq++,
586 path);
587 free (path);
588 CHECK_ERROR (f_imap, status);
589 FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
590 f_imap->state = IMAP_CREATE;
591 }
592
593 case IMAP_CREATE:
594 status = imap_send (f_imap);
595 CHECK_EAGAIN (f_imap, status);
596 f_imap->state = IMAP_CREATE_ACK;
597
598 case IMAP_CREATE_ACK:
599 status = imap_parse (f_imap);
600 CHECK_EAGAIN (f_imap, status);
601 FOLDER_DEBUG0 (folder, MU_DEBUG_PROT, f_imap->buffer);
602
603 default:
604 break;
605 }
606 f_imap->state = IMAP_NO_STATE;
607 return status;
608 }
609
610 /* Remove a mailbox. */ 561 /* Remove a mailbox. */
611 static int 562 static int
612 folder_imap_delete (folder_t folder, const char *name) 563 folder_imap_delete (folder_t folder, const char *name)
...@@ -779,9 +730,12 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, ...@@ -779,9 +730,12 @@ folder_imap_list (folder_t folder, const char *ref, const char *name,
779 for (i = 0; i < num; i++) 730 for (i = 0; i < num; i++)
780 { 731 {
781 struct list_response *lr = f_imap->flist.element[i]; 732 struct list_response *lr = f_imap->flist.element[i];
782 /* printf ("%s --> %s\n", lr->name, name); */ 733 if (imap_mailbox_name_match (name, lr->name) == 0)
783 if (fnmatch (name, lr->name, 0) == 0)
784 { 734 {
735 /*
736 FOLDER_DEBUG2(folder, MU_DEBUG_TRACE,
737 "fnmatch against %s: %s - match!\n", name, lr->name);
738 */
785 plist[i] = calloc (1, sizeof (**plist)); 739 plist[i] = calloc (1, sizeof (**plist));
786 if (plist[i] == NULL 740 if (plist[i] == NULL
787 || (plist[i]->name = strdup (lr->name)) == NULL) 741 || (plist[i]->name = strdup (lr->name)) == NULL)
...@@ -792,6 +746,11 @@ folder_imap_list (folder_t folder, const char *ref, const char *name, ...@@ -792,6 +746,11 @@ folder_imap_list (folder_t folder, const char *ref, const char *name,
792 plist[i]->separator = lr->separator; 746 plist[i]->separator = lr->separator;
793 j++; 747 j++;
794 } 748 }
749 /*
750 else
751 FOLDER_DEBUG2(folder, MU_DEBUG_TRACE,
752 "fnmatch against %s: %s - no match!\n", name, lr->name);
753 */
795 } 754 }
796 } 755 }
797 pflist->element = plist; 756 pflist->element = plist;
...@@ -1152,6 +1111,7 @@ imap_list (f_imap_t f_imap) ...@@ -1152,6 +1111,7 @@ imap_list (f_imap_t f_imap)
1152 char *buffer; 1111 char *buffer;
1153 struct list_response **plr; 1112 struct list_response **plr;
1154 struct list_response *lr; 1113 struct list_response *lr;
1114 int status = 0;
1155 1115
1156 buffer = alloca (len); 1116 buffer = alloca (len);
1157 memcpy (buffer, f_imap->buffer, len); 1117 memcpy (buffer, f_imap->buffer, len);
...@@ -1212,17 +1172,33 @@ imap_list (f_imap_t f_imap) ...@@ -1212,17 +1172,33 @@ imap_list (f_imap_t f_imap)
1212 { 1172 {
1213 size_t n = strtoul (s + 1, NULL, 10); 1173 size_t n = strtoul (s + 1, NULL, 10);
1214 lr->name = calloc (n + 1, 1); 1174 lr->name = calloc (n + 1, 1);
1215 f_imap->ptr = f_imap->buffer; 1175 if (!lr->name)
1216 imap_readline (f_imap); 1176 status = ENOMEM;
1217 memcpy (lr->name, f_imap->buffer, n); 1177 else
1218 lr->name[n] = '\0'; 1178 {
1179 f_imap->ptr = f_imap->buffer;
1180 imap_readline (f_imap);
1181 memcpy (lr->name, f_imap->buffer, n);
1182 }
1183 }
1184 else if ((status = imap_string (f_imap, &tok)) == 0)
1185 {
1186 size_t sz = 0;
1187
1188 stream_size (f_imap->string.stream, &sz);
1189 lr->name = calloc (sz + 1, 1);
1190 if (!lr->name)
1191 status = ENOMEM;
1192 else
1193 stream_read (f_imap->string.stream, lr->name, sz, 0, NULL);
1194 stream_truncate (f_imap->string.stream, 0);
1195 f_imap->string.offset = 0;
1196 f_imap->string.nleft = 0;
1197
1219 } 1198 }
1220 else
1221 lr->name = strdup (tok);
1222 } 1199 }
1223 return 0; 1200 return status;
1224 } 1201 }
1225
1226 /* Helping function to figure out the section name of the message: for example 1202 /* Helping function to figure out the section name of the message: for example
1227 a 2 part message with the first part being sub in two will be: 1203 a 2 part message with the first part being sub in two will be:
1228 {1}, {1,1} {1,2} The first subpart of the message and its sub parts 1204 {1}, {1,1} {1,2} The first subpart of the message and its sub parts
...@@ -1518,7 +1494,7 @@ imap_body (f_imap_t f_imap, char **ptr) ...@@ -1518,7 +1494,7 @@ imap_body (f_imap_t f_imap, char **ptr)
1518 /* strupper. */ 1494 /* strupper. */
1519 for (; *p; p++) if (isupper((unsigned)*p)) *p = toupper ((unsigned)*p); 1495 for (; *p; p++) if (isupper((unsigned)*p)) *p = toupper ((unsigned)*p);
1520 /* Set the string type to update the correct line count. */ 1496 /* Set the string type to update the correct line count. */
1521 //if (!strstr (section, "FIELD")) 1497 /*if (!strstr (section, "FIELD"))*/
1522 { 1498 {
1523 if (strstr (section, "MIME") || (strstr (section, "HEADER"))) 1499 if (strstr (section, "MIME") || (strstr (section, "HEADER")))
1524 { 1500 {
...@@ -1805,6 +1781,20 @@ imap_token (char *buf, size_t len, char **ptr) ...@@ -1805,6 +1781,20 @@ imap_token (char *buf, size_t len, char **ptr)
1805 return *ptr - start;; 1781 return *ptr - start;;
1806 } 1782 }
1807 1783
1784 /* Checks to see if a mailbox name matches a pattern, treating
1785 INBOX case insensitively, as required (INBOX is a special
1786 name no matter what the case is).
1787 */
1788 static int
1789 imap_mailbox_name_match(const char* pattern, const char* mailbox)
1790 {
1791 if(strcasecmp(pattern, "inbox") == 0)
1792 {
1793 return strcasecmp(pattern, mailbox);
1794 }
1795 return fnmatch(pattern, mailbox, 0);
1796 }
1797
1808 /* C99 says that a conforming implementations of snprintf () should return the 1798 /* C99 says that a conforming implementations of snprintf () should return the
1809 number of char that would have been call but many GNU/Linux && BSD 1799 number of char that would have been call but many GNU/Linux && BSD
1810 implementations return -1 on error. Worse QnX/Neutrino actually does not 1800 implementations return -1 on error. Worse QnX/Neutrino actually does not
...@@ -1977,6 +1967,7 @@ imap_parse (f_imap_t f_imap) ...@@ -1977,6 +1967,7 @@ imap_parse (f_imap_t f_imap)
1977 int status = 0; 1967 int status = 0;
1978 char empty[2]; 1968 char empty[2];
1979 char *buffer = NULL; 1969 char *buffer = NULL;
1970 folder_t folder = f_imap->folder;
1980 1971
1981 /* We use that moronic hack to not check null for the tockenize strings. */ 1972 /* We use that moronic hack to not check null for the tockenize strings. */
1982 empty[0] = '\0'; 1973 empty[0] = '\0';
...@@ -2019,6 +2010,8 @@ imap_parse (f_imap_t f_imap) ...@@ -2019,6 +2010,8 @@ imap_parse (f_imap_t f_imap)
2019 /* Is the response untagged ? */ 2010 /* Is the response untagged ? */
2020 if (tag && tag[0] == '*') 2011 if (tag && tag[0] == '*')
2021 { 2012 {
2013 FOLDER_DEBUG2(folder, MU_DEBUG_PROT, "* %s %s\n",
2014 response, remainder);
2022 /* Is it a Status Response. */ 2015 /* Is it a Status Response. */
2023 if (strcasecmp (response, "OK") == 0) 2016 if (strcasecmp (response, "OK") == 0)
2024 { 2017 {
......