Merge branch 'il/maint-colon-address'
authorJunio C Hamano <gitster@pobox.com>
Wed, 27 Jan 2010 22:56:42 +0000 (14:56 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Jan 2010 22:56:42 +0000 (14:56 -0800)
* il/maint-colon-address:
Allow use of []-wrapped addresses in git://
Support addresses with ':' in git-daemon

1  2 
connect.c
daemon.c
diff --combined connect.c
index 3a125621465a68a267d08f74d842238a078c51b2,5145d1620c2f58cd6904b5957cbf2e1785f9de37..20054e4d0fd4cf94288593726be179d07d19271c
+++ b/connect.c
@@@ -107,6 -107,27 +107,6 @@@ int server_supports(const char *feature
                strstr(server_capabilities, feature) != NULL;
  }
  
 -int get_ack(int fd, unsigned char *result_sha1)
 -{
 -      static char line[1000];
 -      int len = packet_read_line(fd, line, sizeof(line));
 -
 -      if (!len)
 -              die("git fetch-pack: expected ACK/NAK, got EOF");
 -      if (line[len-1] == '\n')
 -              line[--len] = 0;
 -      if (!strcmp(line, "NAK"))
 -              return 0;
 -      if (!prefixcmp(line, "ACK ")) {
 -              if (!get_sha1_hex(line+4, result_sha1)) {
 -                      if (strstr(line+45, "continue"))
 -                              return 2;
 -                      return 1;
 -              }
 -      }
 -      die("git fetch_pack: expected ACK/NAK, got '%s'", line);
 -}
 -
  int path_match(const char *path, int nr, char **match)
  {
        int i;
@@@ -502,12 -523,18 +502,18 @@@ struct child_process *git_connect(int f
                c = ':';
        }
  
+       /*
+        * Don't do destructive transforms with git:// as that
+        * protocol code does '[]' dewrapping of its own.
+        */
        if (host[0] == '[') {
                end = strchr(host + 1, ']');
                if (end) {
-                       *end = 0;
+                       if (protocol != PROTO_GIT) {
+                               *end = 0;
+                               host++;
+                       }
                        end++;
-                       host++;
                } else
                        end = host;
        } else
                        GIT_WORK_TREE_ENVIRONMENT,
                        GRAFT_ENVIRONMENT,
                        INDEX_ENVIRONMENT,
 +                      NO_REPLACE_OBJECTS_ENVIRONMENT,
                        NULL
                };
                conn->env = env;
 -              *arg++ = "sh";
 -              *arg++ = "-c";
 +              conn->use_shell = 1;
        }
        *arg++ = cmd.buf;
        *arg = NULL;
diff --combined daemon.c
index 360635eb1c14608b44568ce39d969eb8822e688d,d37f36e87022290e4489ebf07db56a3f0e14c8bb..6c2bd977131752e05d3ac545af0d977d6d7ca672
+++ b/daemon.c
@@@ -77,7 -77,6 +77,7 @@@ static void logreport(int priority, con
        }
  }
  
 +__attribute__((format (printf, 1, 2)))
  static void logerror(const char *err, ...)
  {
        va_list params;
@@@ -86,7 -85,6 +86,7 @@@
        va_end(params);
  }
  
 +__attribute__((format (printf, 1, 2)))
  static void loginfo(const char *err, ...)
  {
        va_list params;
@@@ -103,6 -101,53 +103,6 @@@ static void NORETURN daemon_die(const c
        exit(1);
  }
  
 -static int avoid_alias(char *p)
 -{
 -      int sl, ndot;
 -
 -      /*
 -       * This resurrects the belts and suspenders paranoia check by HPA
 -       * done in <435560F7.4080006@zytor.com> thread, now enter_repo()
 -       * does not do getcwd() based path canonicalizations.
 -       *
 -       * sl becomes true immediately after seeing '/' and continues to
 -       * be true as long as dots continue after that without intervening
 -       * non-dot character.
 -       */
 -      if (!p || (*p != '/' && *p != '~'))
 -              return -1;
 -      sl = 1; ndot = 0;
 -      p++;
 -
 -      while (1) {
 -              char ch = *p++;
 -              if (sl) {
 -                      if (ch == '.')
 -                              ndot++;
 -                      else if (ch == '/') {
 -                              if (ndot < 3)
 -                                      /* reject //, /./ and /../ */
 -                                      return -1;
 -                              ndot = 0;
 -                      }
 -                      else if (ch == 0) {
 -                              if (0 < ndot && ndot < 3)
 -                                      /* reject /.$ and /..$ */
 -                                      return -1;
 -                              return 0;
 -                      }
 -                      else
 -                              sl = ndot = 0;
 -              }
 -              else if (ch == 0)
 -                      return 0;
 -              else if (ch == '/') {
 -                      sl = 1;
 -                      ndot = 0;
 -              }
 -      }
 -}
 -
  static char *path_ok(char *directory)
  {
        static char rpath[PATH_MAX];
  
        dir = directory;
  
 -      if (avoid_alias(dir)) {
 +      if (daemon_avoid_alias(dir)) {
                logerror("'%s': aliased", dir);
                return NULL;
        }
                        { "IP", ip_address },
                        { "P", tcp_port },
                        { "D", directory },
 -                      { "%", "%" },
                        { NULL }
                };
  
@@@ -399,6 -445,33 +399,33 @@@ static char *xstrdup_tolower(const cha
        return dup;
  }
  
+ static void parse_host_and_port(char *hostport, char **host,
+       char **port)
+ {
+       if (*hostport == '[') {
+               char *end;
+               end = strchr(hostport, ']');
+               if (!end)
+                       die("Invalid reqeuest ('[' without ']')");
+               *end = '\0';
+               *host = hostport + 1;
+               if (!end[1])
+                       *port = NULL;
+               else if (end[1] == ':')
+                       *port = end + 2;
+               else
+                       die("Garbage after end of host part");
+       } else {
+               *host = hostport;
+               *port = strrchr(hostport, ':');
+               if (*port) {
+                       *port = '\0';
+                       ++*port;
+               }
+       }
+ }
  /*
   * Read the host as supplied by the client connection.
   */
@@@ -415,11 -488,10 +442,10 @@@ static void parse_host_arg(char *extra_
                        vallen = strlen(val) + 1;
                        if (*val) {
                                /* Split <host>:<port> at colon. */
-                               char *host = val;
-                               char *port = strrchr(host, ':');
+                               char *host;
+                               char *port;
+                               parse_host_and_port(val, &host, &port);
                                if (port) {
-                                       *port = 0;
-                                       port++;
                                        free(tcp_port);
                                        tcp_port = xstrdup(port);
                                }
@@@ -561,24 -633,6 +587,24 @@@ static int execute(struct sockaddr *add
        return -1;
  }
  
 +static int addrcmp(const struct sockaddr_storage *s1,
 +    const struct sockaddr_storage *s2)
 +{
 +      if (s1->ss_family != s2->ss_family)
 +              return s1->ss_family - s2->ss_family;
 +      if (s1->ss_family == AF_INET)
 +              return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
 +                  &((struct sockaddr_in *)s2)->sin_addr,
 +                  sizeof(struct in_addr));
 +#ifndef NO_IPV6
 +      if (s1->ss_family == AF_INET6)
 +              return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
 +                  &((struct sockaddr_in6 *)s2)->sin6_addr,
 +                  sizeof(struct in6_addr));
 +#endif
 +      return 0;
 +}
 +
  static int max_connections = 32;
  
  static unsigned int live_children;
@@@ -593,12 -647,17 +619,12 @@@ static void add_child(pid_t pid, struc
  {
        struct child *newborn, **cradle;
  
 -      /*
 -       * This must be xcalloc() -- we'll compare the whole sockaddr_storage
 -       * but individual address may be shorter.
 -       */
        newborn = xcalloc(1, sizeof(*newborn));
        live_children++;
        newborn->pid = pid;
        memcpy(&newborn->address, addr, addrlen);
        for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
 -              if (!memcmp(&(*cradle)->address, &newborn->address,
 -                          sizeof(newborn->address)))
 +              if (!addrcmp(&(*cradle)->address, &newborn->address))
                        break;
        newborn->next = *cradle;
        *cradle = newborn;
@@@ -631,7 -690,8 +657,7 @@@ static void kill_some_child(void
                return;
  
        for (; (next = blanket->next); blanket = next)
 -              if (!memcmp(&blanket->address, &next->address,
 -                          sizeof(next->address))) {
 +              if (!addrcmp(&blanket->address, &next->address)) {
                        kill(blanket->pid, SIGTERM);
                        break;
                }