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);
int mu_pop3_stls (mu_pop3_t pop3);
/* It is the responsability of the caller to call mu_iterator_destroy() when
/* It is the responsibility of the caller to call mu_iterator_destroy() when
done with the iterator. The items returned by the iterator are of type
"const char *", no processing is done on the item except the removal of
the trailing newline. */
......@@ -82,7 +82,7 @@ int mu_pop3_pass (mu_pop3_t pop3, const char *pass);
int mu_pop3_quit (mu_pop3_t pop3);
/* A stream is returned with the multi-line answer. It is the responsability
/* A stream is returned with the multi-line answer. It is the responsibility
of the caller to call mu_stream_destroy() to dipose of the stream. */
int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno,
mu_stream_t *pstream);
......@@ -91,12 +91,12 @@ int mu_pop3_rset (mu_pop3_t pop3);
int mu_pop3_stat (mu_pop3_t pop3, size_t *count, mu_off_t *octets);
/* A stream is returned with the multi-line answer. It is the responsability
/* A stream is returned with the multi-line answer. It is the responsibility
of the caller to call mu_stream_destroy() to dipose of the stream. */
int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno,
unsigned int lines, mu_stream_t *pstream);
/* The uidl is malloc'ed and returned in puidl; it is the responsability of
/* The uidl is malloc'ed and returned in puidl; it is the responsibility of
the caller to free() the uild when done. */
int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, char **puidl);
......@@ -116,6 +116,10 @@ int mu_pop3_user (mu_pop3_t pop3, const char *user);
the message could be retrieved, but it is up to the caller to do the
parsing. */
int mu_pop3_response (mu_pop3_t pop3, size_t *nread);
const char *mu_pop3_strresp (mu_pop3_t pop3);
int mu_pop3_sget_response (mu_pop3_t pop3, const char **sptr);
int mu_pop3_aget_response (mu_pop3_t pop3, char **sptr);
int mu_pop3_get_response (mu_pop3_t pop3, char *buf, size_t len, size_t *plen);
int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...)
MU_PRINTFLIKE(2,3);
......
......@@ -179,8 +179,15 @@ pop_open (mu_mailbox_t mbox, int flags)
break;
status = mu_pop3_capa (mpd->pop3, 1, NULL);
if (status)
break;
if (status == MU_ERR_REPLY)
{
mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
("server rejected the CAPA command: %s",
mu_pop3_strresp (mpd->pop3)));
/* try to continue anyway */
}
else if (status)
return status;
#ifdef WITH_TLS
if (!mpd->pops &&
......
......@@ -25,8 +25,7 @@
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
#include <mailutils/sys/pop3.h>
#define POP3_DEFERR "-ERR POP3 IO ERROR"
#include <mailutils/util.h>
/* If we did not grap the ack already, call pop3_readline() but handle
Nonblocking also. */
......@@ -48,21 +47,6 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE);
MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack. */
}
else
{
/* Provide them with an error. */
if (pop3->acksize < sizeof (POP3_DEFERR))
{
char *p = realloc (pop3->ackbuf, sizeof (POP3_DEFERR));
if (p)
{
pop3->ackbuf = p;
pop3->acksize = sizeof (POP3_DEFERR);
}
}
if (pop3->ackbuf)
strncpy (pop3->ackbuf, POP3_DEFERR, pop3->acksize);
}
}
else if (pop3->ackbuf)
n = strlen (pop3->ackbuf);
......@@ -78,3 +62,57 @@ mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
*pnread = n;
return status;
}
const char *
mu_pop3_strresp (mu_pop3_t pop3)
{
if (pop3 == NULL)
return NULL;
if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
return NULL;
return pop3->ackbuf;
}
int
mu_pop3_sget_response (mu_pop3_t pop3, const char **sptr)
{
if (pop3 == NULL)
return EINVAL;
if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
return MU_ERR_NOENT;
*sptr = pop3->ackbuf;
return 0;
}
int
mu_pop3_aget_response (mu_pop3_t pop3, char **sptr)
{
char *p;
if (pop3 == NULL)
return EINVAL;
if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
return MU_ERR_NOENT;
p = strdup (pop3->ackbuf);
if (!p)
return ENOMEM;
*sptr = p;
return 0;
}
int
mu_pop3_get_response (mu_pop3_t pop3, char *buf, size_t len, size_t *plen)
{
size_t size;
if (pop3 == NULL)
return EINVAL;
if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
return MU_ERR_NOENT;
if (buf)
size = mu_cpystr (buf, pop3->ackbuf, len);
if (plen)
*plen = size;
return 0;
}
......