wmbiff: handle EAGAIN or GNUTLS_E_AGAIN

From Debian bug #917467, reported by Nye Liu <nyet@nyet.org> [1]:

If gnutls_read() or read() report EAGAIN, tlscomm_expect() fails:

wmbiff/nyet  comm: wrote a000 CAPABILITY
wmbiff/nyet  comm: imap.***.***:993: expecting: * CAPABILITY
wmbiff/nyet  comm: imap.***.***:993: gnutls error reading: Resource temporarily unavailable, try again.
wmbiff/nyet  imap4: unable to query capability stringwmbiff/nyet  comm: wrote a002 LOGOUT
wmbiff/nyet  comm: imap.***.***:993: closing.

[1] https://bugs.debian.org/917467
This commit is contained in:
Torrance, Douglas 2019-02-13 02:18:43 +00:00 committed by Carlos R. Mafra
parent c78465cae2
commit 01cdccc241
2 changed files with 12 additions and 8 deletions

View file

@ -258,7 +258,7 @@ FILE *imap_open(Pop3 pc)
encrypted session. */ encrypted session. */
tlscomm_printf(scs, "a000 CAPABILITY\r\n"); tlscomm_printf(scs, "a000 CAPABILITY\r\n");
if (tlscomm_expect(scs, "* CAPABILITY", capabilities, BUF_SIZE) == 0) { if (tlscomm_expect(scs, "* CAPABILITY", capabilities, BUF_SIZE) == 0) {
IMAP_DM(pc, DEBUG_ERROR, "unable to query capability string"); IMAP_DM(pc, DEBUG_ERROR, "unable to query capability string\n");
goto communication_failure; goto communication_failure;
} }

View file

@ -229,10 +229,12 @@ tlscomm_expect(struct connection_state *scs,
#ifdef USE_GNUTLS #ifdef USE_GNUTLS
if (scs->tls_state) { if (scs->tls_state) {
/* BUF_SIZE - 1 leaves room for trailing \0 */ /* BUF_SIZE - 1 leaves room for trailing \0 */
thisreadbytes = do {
gnutls_read(scs->tls_state, thisreadbytes =
&scs->unprocessed[buffered_bytes], gnutls_read(scs->tls_state,
BUF_SIZE - 1 - buffered_bytes); &scs->unprocessed[buffered_bytes],
BUF_SIZE - 1 - buffered_bytes);
} while (thisreadbytes == GNUTLS_E_AGAIN);
if (thisreadbytes < 0) { if (thisreadbytes < 0) {
handle_gnutls_read_error(thisreadbytes, scs); handle_gnutls_read_error(thisreadbytes, scs);
return 0; return 0;
@ -240,9 +242,11 @@ tlscomm_expect(struct connection_state *scs,
} else } else
#endif #endif
{ {
thisreadbytes = do {
read(scs->sd, &scs->unprocessed[buffered_bytes], thisreadbytes =
BUF_SIZE - 1 - buffered_bytes); read(scs->sd, &scs->unprocessed[buffered_bytes],
BUF_SIZE - 1 - buffered_bytes);
} while (thisreadbytes == EAGAIN);
if (thisreadbytes < 0) { if (thisreadbytes < 0) {
TDM(DEBUG_ERROR, "%s: error reading: %s\n", TDM(DEBUG_ERROR, "%s: error reading: %s\n",
scs->name, strerror(errno)); scs->name, strerror(errno));