Update draft release notes to 1.6.6 before merging topics for -rc1
[gitweb.git] / daemon.c
index 0c2f32635ae38a979ada2c7968f8a3c535931c9e..5783e2401108adb1fef6943ef80bd78dbc76ecad 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1,6 +1,8 @@
 #include "cache.h"
 #include "pkt-line.h"
 #include "exec_cmd.h"
+#include "run-command.h"
+#include "strbuf.h"
 
 #include <syslog.h>
 
@@ -75,6 +77,7 @@ static void logreport(int priority, const char *err, va_list params)
        }
 }
 
+__attribute__((format (printf, 1, 2)))
 static void logerror(const char *err, ...)
 {
        va_list params;
@@ -83,6 +86,7 @@ static void logerror(const char *err, ...)
        va_end(params);
 }
 
+__attribute__((format (printf, 1, 2)))
 static void loginfo(const char *err, ...)
 {
        va_list params;
@@ -99,53 +103,6 @@ static void NORETURN daemon_die(const char *err, va_list params)
        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];
@@ -155,7 +112,7 @@ static char *path_ok(char *directory)
 
        dir = directory;
 
-       if (avoid_alias(dir)) {
+       if (daemon_avoid_alias(dir)) {
                logerror("'%s': aliased", dir);
                return NULL;
        }
@@ -343,28 +300,66 @@ static int run_service(char *dir, struct daemon_service *service)
        return service->fn();
 }
 
+static void copy_to_log(int fd)
+{
+       struct strbuf line = STRBUF_INIT;
+       FILE *fp;
+
+       fp = fdopen(fd, "r");
+       if (fp == NULL) {
+               logerror("fdopen of error channel failed");
+               close(fd);
+               return;
+       }
+
+       while (strbuf_getline(&line, fp, '\n') != EOF) {
+               logerror("%s", line.buf);
+               strbuf_setlen(&line, 0);
+       }
+
+       strbuf_release(&line);
+       fclose(fp);
+}
+
+static int run_service_command(const char **argv)
+{
+       struct child_process cld;
+
+       memset(&cld, 0, sizeof(cld));
+       cld.argv = argv;
+       cld.git_cmd = 1;
+       cld.err = -1;
+       if (start_command(&cld))
+               return -1;
+
+       close(0);
+       close(1);
+
+       copy_to_log(cld.err);
+
+       return finish_command(&cld);
+}
+
 static int upload_pack(void)
 {
        /* Timeout as string */
        char timeout_buf[64];
+       const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
 
        snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
-
-       /* git-upload-pack only ever reads stuff, so this is safe */
-       execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
-       return -1;
+       return run_service_command(argv);
 }
 
 static int upload_archive(void)
 {
-       execl_git_cmd("upload-archive", ".", NULL);
-       return -1;
+       static const char *argv[] = { "upload-archive", ".", NULL };
+       return run_service_command(argv);
 }
 
 static int receive_pack(void)
 {
-       execl_git_cmd("receive-pack", ".", NULL);
-       return -1;
+       static const char *argv[] = { "receive-pack", ".", NULL };
+       return run_service_command(argv);
 }
 
 static struct daemon_service daemon_service[] = {
@@ -453,7 +448,7 @@ static void parse_host_arg(char *extra_args, int buflen)
                memset(&hints, 0, sizeof(hints));
                hints.ai_flags = AI_CANONNAME;
 
-               gai = getaddrinfo(hostname, 0, &hints, &ai);
+               gai = getaddrinfo(hostname, NULL, &hints, &ai);
                if (!gai) {
                        struct sockaddr_in *sin_addr = (void *)ai->ai_addr;