93 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| diff --git a/connect.c b/connect.c
 | |
| --- a/connect.c
 | |
| +++ b/connect.c
 | |
| @@ -96,42 +96,57 @@ static enum protocol get_protocol(const 
 | |
|  	die("I don't handle protocol '%s'", name);
 | |
|  }
 | |
|  
 | |
| -static void lookup_host(const char *host, struct sockaddr *in)
 | |
| -{
 | |
| -	struct addrinfo *res;
 | |
| -	int ret;
 | |
| -
 | |
| -	ret = getaddrinfo(host, NULL, NULL, &res);
 | |
| -	if (ret)
 | |
| -		die("Unable to look up %s (%s)", host, gai_strerror(ret));
 | |
| -	*in = *res->ai_addr;
 | |
| -	freeaddrinfo(res);
 | |
| -}
 | |
| +#define STR_(s)	# s
 | |
| +#define STR(s)	STR_(s)
 | |
|  
 | |
|  static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
 | |
|  {
 | |
| -	struct sockaddr addr;
 | |
| -	int port = DEFAULT_GIT_PORT, sockfd;
 | |
| -	char *colon;
 | |
| -
 | |
| -	colon = strchr(host, ':');
 | |
| -	if (colon) {
 | |
| -		char *end;
 | |
| -		unsigned long n = strtoul(colon+1, &end, 0);
 | |
| -		if (colon[1] && !*end) {
 | |
| -			*colon = 0;
 | |
| -			port = n;
 | |
| +	int sockfd = -1;
 | |
| +	char *colon, *end;
 | |
| +	char *port = STR(DEFAULT_GIT_PORT);
 | |
| +	struct addrinfo hints, *ai0, *ai;
 | |
| +	int gai;
 | |
| +
 | |
| +	if (host[0] == '[') {
 | |
| +		end = strchr(host + 1, ']');
 | |
| +		if (end) {
 | |
| +			*end = 0;
 | |
| +			end++;
 | |
| +			host++;
 | |
| +		} else
 | |
| +			end = host;
 | |
| +	} else
 | |
| +		end = host;
 | |
| +	colon = strchr(end, ':');
 | |
| +
 | |
| +	if (colon)
 | |
| +		port = colon + 1;
 | |
| +
 | |
| +	memset(&hints, 0, sizeof(hints));
 | |
| +	hints.ai_socktype = SOCK_STREAM;
 | |
| +	hints.ai_protocol = IPPROTO_TCP;
 | |
| +
 | |
| +	gai = getaddrinfo(host, port, &hints, &ai);
 | |
| +	if (gai)
 | |
| +		die("Unable to look up %s (%s)", host, gai_strerror(gai));
 | |
| +
 | |
| +	for (ai0 = ai; ai; ai = ai->ai_next) {
 | |
| +		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 | |
| +		if (sockfd < 0)
 | |
| +			continue;
 | |
| +		if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
 | |
| +			close(sockfd);
 | |
| +			sockfd = -1;
 | |
| +			continue;
 | |
|  		}
 | |
| +		break;
 | |
|  	}
 | |
|  
 | |
| -	lookup_host(host, &addr);
 | |
| -	((struct sockaddr_in *)&addr)->sin_port = htons(port);
 | |
| +	freeaddrinfo(ai0);
 | |
|  
 | |
| -	sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
 | |
|  	if (sockfd < 0)
 | |
|  		die("unable to create socket (%s)", strerror(errno));
 | |
| -	if (connect(sockfd, (void *)&addr, sizeof(addr)) < 0)
 | |
| -		die("unable to connect (%s)", strerror(errno));
 | |
| +
 | |
|  	fd[0] = sockfd;
 | |
|  	fd[1] = sockfd;
 | |
|  	packet_write(sockfd, "%s %s\n", prog, path);
 | |
| 
 | |
| -- 
 | |
| YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
 | |
| GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
 | |
| 
 |