Git 1.7.9-rc0
[gitweb.git] / connect.c
index d2ce57f850fa6d0a6de04f6f714dec487ff9f1ed..2ea5c3c0fbedb89e4189d32a455f289398ce106b 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -22,7 +22,7 @@ static int check_ref(const char *name, int len, unsigned int flags)
        len -= 5;
 
        /* REF_NORMAL means that we don't want the magic fake tag refs */
-       if ((flags & REF_NORMAL) && check_ref_format(name) < 0)
+       if ((flags & REF_NORMAL) && check_refname_format(name, 0))
                return 0;
 
        /* REF_HEADS means that we want regular branch heads */
@@ -53,7 +53,6 @@ static void add_extra_have(struct extra_have_objects *extra, unsigned char *sha1
  * Read all the refs from the other end
  */
 struct ref **get_remote_heads(int in, struct ref **list,
-                             int nr_match, char **match,
                              unsigned int flags,
                              struct extra_have_objects *extra_have)
 {
@@ -92,8 +91,6 @@ struct ref **get_remote_heads(int in, struct ref **list,
 
                if (!check_ref(name, name_len, flags))
                        continue;
-               if (nr_match && !path_match(name, nr_match, match))
-                       continue;
                ref = alloc_ref(buffer + 41);
                hashcpy(ref->old_sha1, old_sha1);
                *list = ref;
@@ -108,27 +105,6 @@ int server_supports(const char *feature)
                strstr(server_capabilities, feature) != NULL;
 }
 
-int path_match(const char *path, int nr, char **match)
-{
-       int i;
-       int pathlen = strlen(path);
-
-       for (i = 0; i < nr; i++) {
-               char *s = match[i];
-               int len = strlen(s);
-
-               if (!len || len > pathlen)
-                       continue;
-               if (memcmp(path + pathlen - len, s, len))
-                       continue;
-               if (pathlen > len && path[pathlen - len - 1] != '/')
-                       continue;
-               *s = 0;
-               return (i + 1);
-       }
-       return 0;
-}
-
 enum protocol {
        PROTO_LOCAL = 1,
        PROTO_SSH,
@@ -175,6 +151,15 @@ static void get_host_and_port(char **host, const char **port)
        }
 }
 
+static void enable_keepalive(int sockfd)
+{
+       int ka = 1;
+
+       if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
+               fprintf(stderr, "unable to set SO_KEEPALIVE on socket: %s\n",
+                       strerror(errno));
+}
+
 #ifndef NO_IPV6
 
 static const char *ai_name(const struct addrinfo *ai)
@@ -239,6 +224,8 @@ static int git_tcp_connect_sock(char *host, int flags)
        if (sockfd < 0)
                die("unable to connect to %s:\n%s", host, error_message.buf);
 
+       enable_keepalive(sockfd);
+
        if (flags & CONNECT_VERBOSE)
                fprintf(stderr, "done.\n");
 
@@ -254,7 +241,8 @@ static int git_tcp_connect_sock(char *host, int flags)
  */
 static int git_tcp_connect_sock(char *host, int flags)
 {
-       int sockfd = -1, saved_errno = 0;
+       struct strbuf error_message = STRBUF_INIT;
+       int sockfd = -1;
        const char *port = STR(DEFAULT_GIT_PORT);
        char *ep;
        struct hostent *he;
@@ -284,25 +272,21 @@ static int git_tcp_connect_sock(char *host, int flags)
                fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
 
        for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
-               sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
-               if (sockfd < 0) {
-                       saved_errno = errno;
-                       continue;
-               }
-
                memset(&sa, 0, sizeof sa);
                sa.sin_family = he->h_addrtype;
                sa.sin_port = htons(nport);
                memcpy(&sa.sin_addr, *ap, he->h_length);
 
-               if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
-                       saved_errno = errno;
-                       fprintf(stderr, "%s[%d: %s]: errno=%s\n",
+               sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
+               if ((sockfd < 0) ||
+                   connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
+                       strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
                                host,
                                cnt,
                                inet_ntoa(*(struct in_addr *)&sa.sin_addr),
-                               strerror(saved_errno));
-                       close(sockfd);
+                               strerror(errno));
+                       if (0 <= sockfd)
+                               close(sockfd);
                        sockfd = -1;
                        continue;
                }
@@ -313,7 +297,9 @@ static int git_tcp_connect_sock(char *host, int flags)
        }
 
        if (sockfd < 0)
-               die("unable to connect a socket (%s)", strerror(saved_errno));
+               die("unable to connect to %s:\n%s", host, error_message.buf);
+
+       enable_keepalive(sockfd);
 
        if (flags & CONNECT_VERBOSE)
                fprintf(stderr, "done.\n");
@@ -622,47 +608,3 @@ int finish_connect(struct child_process *conn)
        free(conn);
        return code;
 }
-
-char *git_getpass(const char *prompt)
-{
-       const char *askpass;
-       struct child_process pass;
-       const char *args[3];
-       static struct strbuf buffer = STRBUF_INIT;
-
-       askpass = getenv("GIT_ASKPASS");
-       if (!askpass)
-               askpass = askpass_program;
-       if (!askpass)
-               askpass = getenv("SSH_ASKPASS");
-       if (!askpass || !(*askpass)) {
-               char *result = getpass(prompt);
-               if (!result)
-                       die_errno("Could not read password");
-               return result;
-       }
-
-       args[0] = askpass;
-       args[1] = prompt;
-       args[2] = NULL;
-
-       memset(&pass, 0, sizeof(pass));
-       pass.argv = args;
-       pass.out = -1;
-
-       if (start_command(&pass))
-               exit(1);
-
-       strbuf_reset(&buffer);
-       if (strbuf_read(&buffer, pass.out, 20) < 0)
-               die("failed to read password from %s\n", askpass);
-
-       close(pass.out);
-
-       if (finish_command(&pass))
-               exit(1);
-
-       strbuf_setlen(&buffer, strcspn(buffer.buf, "\r\n"));
-
-       return buffer.buf;
-}