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:
		
							parent
							
								
									c78465cae2
								
							
						
					
					
						commit
						01cdccc241
					
				
					 2 changed files with 12 additions and 8 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue