Commit d1e34b1a d1e34b1a9662b7f76463604c6ec9b584d0bbe696 by Sergey Poznyakoff

Fix interaction with POP3 servers that do not support the CAPA command.

* libproto/pop/mbox.c (pop_open): Do not bail
out if the CAPA command returns -ERR. Assume
a pre-RFC2449 server.
* include/mailutils/pop3.h (mu_pop3_strresp)
(mu_pop3_sget_response,mu_pop3_aget_response)
(mu_pop3_get_response): New protos.
* libproto/pop/pop3_response.c (mu_pop3_response): Don't
make out a fake response in case of a I/O error.
(mu_pop3_strresp)
(mu_pop3_sget_response,mu_pop3_aget_response)
(mu_pop3_get_response): New functions.
1 parent 81bc65e6
...@@ -55,7 +55,7 @@ int mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest); ...@@ -55,7 +55,7 @@ int mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest);
55 55
56 int mu_pop3_stls (mu_pop3_t pop3); 56 int mu_pop3_stls (mu_pop3_t pop3);
57 57
58 /* It is the responsability of the caller to call mu_iterator_destroy() when 58 /* It is the responsibility of the caller to call mu_iterator_destroy() when
59 done with the iterator. The items returned by the iterator are of type 59 done with the iterator. The items returned by the iterator are of type
60 "const char *", no processing is done on the item except the removal of 60 "const char *", no processing is done on the item except the removal of
61 the trailing newline. */ 61 the trailing newline. */
...@@ -82,7 +82,7 @@ int mu_pop3_pass (mu_pop3_t pop3, const char *pass); ...@@ -82,7 +82,7 @@ int mu_pop3_pass (mu_pop3_t pop3, const char *pass);
82 82
83 int mu_pop3_quit (mu_pop3_t pop3); 83 int mu_pop3_quit (mu_pop3_t pop3);
84 84
85 /* A stream is returned with the multi-line answer. It is the responsability 85 /* A stream is returned with the multi-line answer. It is the responsibility
86 of the caller to call mu_stream_destroy() to dipose of the stream. */ 86 of the caller to call mu_stream_destroy() to dipose of the stream. */
87 int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno, 87 int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno,
88 mu_stream_t *pstream); 88 mu_stream_t *pstream);
...@@ -91,12 +91,12 @@ int mu_pop3_rset (mu_pop3_t pop3); ...@@ -91,12 +91,12 @@ int mu_pop3_rset (mu_pop3_t pop3);
91 91
92 int mu_pop3_stat (mu_pop3_t pop3, size_t *count, mu_off_t *octets); 92 int mu_pop3_stat (mu_pop3_t pop3, size_t *count, mu_off_t *octets);
93 93
94 /* A stream is returned with the multi-line answer. It is the responsability 94 /* A stream is returned with the multi-line answer. It is the responsibility
95 of the caller to call mu_stream_destroy() to dipose of the stream. */ 95 of the caller to call mu_stream_destroy() to dipose of the stream. */
96 int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno, 96 int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno,
97 unsigned int lines, mu_stream_t *pstream); 97 unsigned int lines, mu_stream_t *pstream);
98 98
99 /* The uidl is malloc'ed and returned in puidl; it is the responsability of 99 /* The uidl is malloc'ed and returned in puidl; it is the responsibility of
100 the caller to free() the uild when done. */ 100 the caller to free() the uild when done. */
101 int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, char **puidl); 101 int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, char **puidl);
102 102
...@@ -116,7 +116,11 @@ int mu_pop3_user (mu_pop3_t pop3, const char *user); ...@@ -116,7 +116,11 @@ int mu_pop3_user (mu_pop3_t pop3, const char *user);
116 the message could be retrieved, but it is up to the caller to do the 116 the message could be retrieved, but it is up to the caller to do the
117 parsing. */ 117 parsing. */
118 int mu_pop3_response (mu_pop3_t pop3, size_t *nread); 118 int mu_pop3_response (mu_pop3_t pop3, size_t *nread);
119 119 const char *mu_pop3_strresp (mu_pop3_t pop3);
120 int mu_pop3_sget_response (mu_pop3_t pop3, const char **sptr);
121 int mu_pop3_aget_response (mu_pop3_t pop3, char **sptr);
122 int mu_pop3_get_response (mu_pop3_t pop3, char *buf, size_t len, size_t *plen);
123
120 int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...) 124 int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...)
121 MU_PRINTFLIKE(2,3); 125 MU_PRINTFLIKE(2,3);
122 126
......
...@@ -179,8 +179,15 @@ pop_open (mu_mailbox_t mbox, int flags) ...@@ -179,8 +179,15 @@ pop_open (mu_mailbox_t mbox, int flags)
179 break; 179 break;
180 180
181 status = mu_pop3_capa (mpd->pop3, 1, NULL); 181 status = mu_pop3_capa (mpd->pop3, 1, NULL);
182 if (status) 182 if (status == MU_ERR_REPLY)
183 break; 183 {
184 mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
185 ("server rejected the CAPA command: %s",
186 mu_pop3_strresp (mpd->pop3)));
187 /* try to continue anyway */
188 }
189 else if (status)
190 return status;
184 191
185 #ifdef WITH_TLS 192 #ifdef WITH_TLS
186 if (!mpd->pops && 193 if (!mpd->pops &&
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
25 #include <mailutils/cctype.h> 25 #include <mailutils/cctype.h>
26 #include <mailutils/cstr.h> 26 #include <mailutils/cstr.h>
27 #include <mailutils/sys/pop3.h> 27 #include <mailutils/sys/pop3.h>
28 28 #include <mailutils/util.h>
29 #define POP3_DEFERR "-ERR POP3 IO ERROR"
30 29
31 /* If we did not grap the ack already, call pop3_readline() but handle 30 /* If we did not grap the ack already, call pop3_readline() but handle
32 Nonblocking also. */ 31 Nonblocking also. */
...@@ -48,21 +47,6 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread) ...@@ -48,21 +47,6 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
48 n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE); 47 n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE);
49 MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack. */ 48 MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack. */
50 } 49 }
51 else
52 {
53 /* Provide them with an error. */
54 if (pop3->acksize < sizeof (POP3_DEFERR))
55 {
56 char *p = realloc (pop3->ackbuf, sizeof (POP3_DEFERR));
57 if (p)
58 {
59 pop3->ackbuf = p;
60 pop3->acksize = sizeof (POP3_DEFERR);
61 }
62 }
63 if (pop3->ackbuf)
64 strncpy (pop3->ackbuf, POP3_DEFERR, pop3->acksize);
65 }
66 } 50 }
67 else if (pop3->ackbuf) 51 else if (pop3->ackbuf)
68 n = strlen (pop3->ackbuf); 52 n = strlen (pop3->ackbuf);
...@@ -78,3 +62,57 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread) ...@@ -78,3 +62,57 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
78 *pnread = n; 62 *pnread = n;
79 return status; 63 return status;
80 } 64 }
65
66 const char *
67 mu_pop3_strresp (mu_pop3_t pop3)
68 {
69 if (pop3 == NULL)
70 return NULL;
71 if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
72 return NULL;
73 return pop3->ackbuf;
74 }
75
76 int
77 mu_pop3_sget_response (mu_pop3_t pop3, const char **sptr)
78 {
79 if (pop3 == NULL)
80 return EINVAL;
81 if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
82 return MU_ERR_NOENT;
83 *sptr = pop3->ackbuf;
84 return 0;
85 }
86
87 int
88 mu_pop3_aget_response (mu_pop3_t pop3, char **sptr)
89 {
90 char *p;
91
92 if (pop3 == NULL)
93 return EINVAL;
94 if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
95 return MU_ERR_NOENT;
96 p = strdup (pop3->ackbuf);
97 if (!p)
98 return ENOMEM;
99 *sptr = p;
100 return 0;
101 }
102
103 int
104 mu_pop3_get_response (mu_pop3_t pop3, char *buf, size_t len, size_t *plen)
105 {
106 size_t size;
107
108 if (pop3 == NULL)
109 return EINVAL;
110 if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
111 return MU_ERR_NOENT;
112
113 if (buf)
114 size = mu_cpystr (buf, pop3->ackbuf, len);
115 if (plen)
116 *plen = size;
117 return 0;
118 }
......