t / t5100 / patch0004on commit Merge branch 'tq/git-ssh-command' (09d60d7)
   1diff --git a/connect.c b/connect.c
   2--- a/connect.c
   3+++ b/connect.c
   4@@ -96,42 +96,57 @@ static enum protocol get_protocol(const 
   5        die("I don't handle protocol '%s'", name);
   6 }
   7 
   8-static void lookup_host(const char *host, struct sockaddr *in)
   9-{
  10-       struct addrinfo *res;
  11-       int ret;
  12-
  13-       ret = getaddrinfo(host, NULL, NULL, &res);
  14-       if (ret)
  15-               die("Unable to look up %s (%s)", host, gai_strerror(ret));
  16-       *in = *res->ai_addr;
  17-       freeaddrinfo(res);
  18-}
  19+#define STR_(s)        # s
  20+#define STR(s) STR_(s)
  21 
  22 static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
  23 {
  24-       struct sockaddr addr;
  25-       int port = DEFAULT_GIT_PORT, sockfd;
  26-       char *colon;
  27-
  28-       colon = strchr(host, ':');
  29-       if (colon) {
  30-               char *end;
  31-               unsigned long n = strtoul(colon+1, &end, 0);
  32-               if (colon[1] && !*end) {
  33-                       *colon = 0;
  34-                       port = n;
  35+       int sockfd = -1;
  36+       char *colon, *end;
  37+       char *port = STR(DEFAULT_GIT_PORT);
  38+       struct addrinfo hints, *ai0, *ai;
  39+       int gai;
  40+
  41+       if (host[0] == '[') {
  42+               end = strchr(host + 1, ']');
  43+               if (end) {
  44+                       *end = 0;
  45+                       end++;
  46+                       host++;
  47+               } else
  48+                       end = host;
  49+       } else
  50+               end = host;
  51+       colon = strchr(end, ':');
  52+
  53+       if (colon)
  54+               port = colon + 1;
  55+
  56+       memset(&hints, 0, sizeof(hints));
  57+       hints.ai_socktype = SOCK_STREAM;
  58+       hints.ai_protocol = IPPROTO_TCP;
  59+
  60+       gai = getaddrinfo(host, port, &hints, &ai);
  61+       if (gai)
  62+               die("Unable to look up %s (%s)", host, gai_strerror(gai));
  63+
  64+       for (ai0 = ai; ai; ai = ai->ai_next) {
  65+               sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  66+               if (sockfd < 0)
  67+                       continue;
  68+               if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
  69+                       close(sockfd);
  70+                       sockfd = -1;
  71+                       continue;
  72                }
  73+               break;
  74        }
  75 
  76-       lookup_host(host, &addr);
  77-       ((struct sockaddr_in *)&addr)->sin_port = htons(port);
  78+       freeaddrinfo(ai0);
  79 
  80-       sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
  81        if (sockfd < 0)
  82                die("unable to create socket (%s)", strerror(errno));
  83-       if (connect(sockfd, (void *)&addr, sizeof(addr)) < 0)
  84-               die("unable to connect (%s)", strerror(errno));
  85+
  86        fd[0] = sockfd;
  87        fd[1] = sockfd;
  88        packet_write(sockfd, "%s %s\n", prog, path);
  89
  90-- 
  91YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@linux-ipv6.org>
  92GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
  93