Code

Merge branch 'dm/add-i-edit-abort'
[git.git] / daemon.c
index 64f60c431ba1f566a1b292111ae819d49ddc35f0..13401f1baf57dc87a7a95bd778f4e1becbdbe323 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -57,7 +57,6 @@ static char *hostname;
 static char *canon_hostname;
 static char *ip_address;
 static char *tcp_port;
-static char *directory;
 
 static void logreport(int priority, const char *err, va_list params)
 {
@@ -147,11 +146,10 @@ static int avoid_alias(char *p)
        }
 }
 
-static char *path_ok(void)
+static char *path_ok(char *directory)
 {
        static char rpath[PATH_MAX];
        static char interp_path[PATH_MAX];
-       int retried_path = 0;
        char *path;
        char *dir;
 
@@ -220,25 +218,18 @@ static char *path_ok(void)
                dir = rpath;
        }
 
-       do {
-               path = enter_repo(dir, strict_paths);
-               if (path)
-                       break;
-
+       path = enter_repo(dir, strict_paths);
+       if (!path && base_path && base_path_relaxed) {
                /*
                 * if we fail and base_path_relaxed is enabled, try without
                 * prefixing the base path
                 */
-               if (base_path && base_path_relaxed && !retried_path) {
-                       dir = directory;
-                       retried_path = 1;
-                       continue;
-               }
-               break;
-       } while (1);
+               dir = directory;
+               path = enter_repo(dir, strict_paths);
+       }
 
        if (!path) {
-               logerror("'%s': unable to chdir or not a git archive", dir);
+               logerror("'%s' does not appear to be a git repository", dir);
                return NULL;
        }
 
@@ -296,12 +287,12 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
        return 0;
 }
 
-static int run_service(struct daemon_service *service)
+static int run_service(char *dir, struct daemon_service *service)
 {
        const char *path;
        int enabled = service->enabled;
 
-       loginfo("Request %s for '%s'", service->name, directory);
+       loginfo("Request %s for '%s'", service->name, dir);
 
        if (!enabled && !service->overridable) {
                logerror("'%s': service not enabled.", service->name);
@@ -309,7 +300,7 @@ static int run_service(struct daemon_service *service)
                return -1;
        }
 
-       if (!(path = path_ok()))
+       if (!(path = path_ok(dir)))
                return -1;
 
        /*
@@ -406,6 +397,14 @@ static void make_service_overridable(const char *name, int ena)
        die("No such service %s", name);
 }
 
+static char *xstrdup_tolower(const char *str)
+{
+       char *p, *dup = xstrdup(str);
+       for (p = dup; *p; p++)
+               *p = tolower(*p);
+       return dup;
+}
+
 /*
  * Separate the "extra args" information as supplied by the client connection.
  */
@@ -431,33 +430,19 @@ static void parse_extra_args(char *extra_args, int buflen)
                                        tcp_port = xstrdup(port);
                                }
                                free(hostname);
-                               hostname = xstrdup(host);
+                               hostname = xstrdup_tolower(host);
                        }
 
                        /* On to the next one */
                        extra_args = val + vallen;
                }
        }
-}
-
-static void fill_in_extra_table_entries(void)
-{
-       char *hp;
-
-       /*
-        * Replace literal host with lowercase-ized hostname.
-        */
-       hp = hostname;
-       if (!hp)
-               return;
-       for ( ; *hp; hp++)
-               *hp = tolower(*hp);
 
        /*
         * Locate canonical hostname and its IP address.
         */
+       if (hostname) {
 #ifndef NO_IPV6
-       {
                struct addrinfo hints;
                struct addrinfo *ai, *ai0;
                int gai;
@@ -481,9 +466,7 @@ static void fill_in_extra_table_entries(void)
                        }
                        freeaddrinfo(ai0);
                }
-       }
 #else
-       {
                struct hostent *hent;
                struct sockaddr_in sa;
                char **ap;
@@ -504,8 +487,8 @@ static void fill_in_extra_table_entries(void)
                canon_hostname = xstrdup(hent->h_name);
                free(ip_address);
                ip_address = xstrdup(addrbuf);
-       }
 #endif
+       }
 }
 
 
@@ -559,13 +542,10 @@ static int execute(struct sockaddr *addr)
        free(canon_hostname);
        free(ip_address);
        free(tcp_port);
-       free(directory);
-       hostname = canon_hostname = ip_address = tcp_port = directory = NULL;
+       hostname = canon_hostname = ip_address = tcp_port = NULL;
 
-       if (len != pktlen) {
+       if (len != pktlen)
                parse_extra_args(line + len + 1, pktlen - len - 1);
-               fill_in_extra_table_entries();
-       }
 
        for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
                struct daemon_service *s = &(daemon_service[i]);
@@ -577,9 +557,7 @@ static int execute(struct sockaddr *addr)
                         * Note: The directory here is probably context sensitive,
                         * and might depend on the actual service being performed.
                         */
-                       free(directory);
-                       directory = xstrdup(line + namelen + 5);
-                       return run_service(s);
+                       return run_service(line + namelen + 5, s);
                }
        }
 
@@ -738,7 +716,7 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 
        gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
        if (gai)
-               die("getaddrinfo() failed: %s\n", gai_strerror(gai));
+               die("getaddrinfo() failed: %s", gai_strerror(gai));
 
        for (ai = ai0; ai; ai = ai->ai_next) {
                int sockfd;
@@ -959,16 +937,14 @@ int main(int argc, char **argv)
        gid_t gid = 0;
        int i;
 
+       git_extract_argv0_path(argv[0]);
+
        for (i = 1; i < argc; i++) {
                char *arg = argv[i];
 
                if (!prefixcmp(arg, "--listen=")) {
-                   char *p = arg + 9;
-                   char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1);
-                   while (*p)
-                       *ph++ = tolower(*p++);
-                   *ph = 0;
-                   continue;
+                       listen_addr = xstrdup_tolower(arg + 9);
+                       continue;
                }
                if (!prefixcmp(arg, "--port=")) {
                        char *end;
@@ -1128,7 +1104,9 @@ int main(int argc, char **argv)
                struct sockaddr *peer = (struct sockaddr *)&ss;
                socklen_t slen = sizeof(ss);
 
-               freopen("/dev/null", "w", stderr);
+               if (!freopen("/dev/null", "w", stderr))
+                       die("failed to redirect stderr to /dev/null: %s",
+                           strerror(errno));
 
                if (getpeername(0, peer, &slen))
                        peer = NULL;