+enum protocol {
+ PROTO_LOCAL = 1,
+ PROTO_SSH,
+ PROTO_GIT,
+};
+
+static enum protocol get_protocol(const char *name)
+{
+ if (!strcmp(name, "ssh"))
+ return PROTO_SSH;
+ if (!strcmp(name, "git"))
+ return PROTO_GIT;
+ 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);
+}
+
+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;
+ }
+ }
+
+ lookup_host(host, &addr);
+ ((struct sockaddr_in *)&addr)->sin_port = htons(port);
+
+ 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);
+ return 0;
+}
+