diff options
| author | Benjamin Kramer <benny.kra@googlemail.com> | 2009-05-25 21:13:54 +0200 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2009-05-26 22:22:47 -0700 | 
| commit | 94ad2437020038b022ce19b8b8b35f1cc86b16f6 (patch) | |
| tree | a80057d09489398f87fcb3afcb2865219867c98e /imap-send.c | |
| parent | 33fd7169ed6658e898b414a66aefaad16b404ec5 (diff) | |
imap-send: add support for IPv6
Add IPv6 support by implementing name resolution with the
protocol agnostic getaddrinfo(3) API. The old gethostbyname(3)
code is still available when git is compiled with NO_IPV6.
Signed-off-by: Benjamin Kramer <benny.kra@googlemail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'imap-send.c')
| -rw-r--r-- | imap-send.c | 54 | 
1 files changed, 51 insertions, 3 deletions
diff --git a/imap-send.c b/imap-send.c index 8154cb2116..e4c83b9d5b 100644 --- a/imap-send.c +++ b/imap-send.c @@ -982,9 +982,7 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)  	struct imap_store *ctx;  	struct imap *imap;  	char *arg, *rsp; -	struct hostent *he; -	struct sockaddr_in addr; -	int s, a[2], preauth; +	int s = -1, a[2], preauth;  	pid_t pid;  	ctx = xcalloc(sizeof(*ctx), 1); @@ -1021,6 +1019,51 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)  		imap_info("ok\n");  	} else { +#ifndef NO_IPV6 +		struct addrinfo hints, *ai0, *ai; +		int gai; +		char portstr[6]; + +		snprintf(portstr, sizeof(portstr), "%hu", srvc->port); + +		memset(&hints, 0, sizeof(hints)); +		hints.ai_socktype = SOCK_STREAM; +		hints.ai_protocol = IPPROTO_TCP; + +		imap_info("Resolving %s... ", srvc->host); +		gai = getaddrinfo(srvc->host, portstr, &hints, &ai); +		if (gai) { +			fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(gai)); +			goto bail; +		} +		imap_info("ok\n"); + +		for (ai0 = ai; ai; ai = ai->ai_next) { +			char addr[NI_MAXHOST]; + +			s = socket(ai->ai_family, ai->ai_socktype, +				   ai->ai_protocol); +			if (s < 0) +				continue; + +			getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, +				    sizeof(addr), NULL, 0, NI_NUMERICHOST); +			imap_info("Connecting to [%s]:%s... ", addr, portstr); + +			if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) { +				close(s); +				s = -1; +				perror("connect"); +				continue; +			} + +			break; +		} +		freeaddrinfo(ai0); +#else /* NO_IPV6 */ +		struct hostent *he; +		struct sockaddr_in addr; +  		memset(&addr, 0, sizeof(addr));  		addr.sin_port = htons(srvc->port);  		addr.sin_family = AF_INET; @@ -1040,7 +1083,12 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)  		imap_info("Connecting to %s:%hu... ", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));  		if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) {  			close(s); +			s = -1;  			perror("connect"); +		} +#endif +		if (s < 0) { +			fputs("Error: unable to connect to server.\n", stderr);  			goto bail;  		}  | 
