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.
Showing
3 changed files
with
73 additions
and
24 deletions
... | @@ -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 | } | ... | ... |
-
Please register or sign in to post a comment