daemon: add helper function named_sock_setup
[gitweb.git] / daemon.c
index a90ab10505a3694de83a0ffd8fc472518f12cf2b..c666cedde734c7c2f8074c33c052a4dd33951efb 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -141,15 +141,14 @@ static char *path_ok(char *directory)
        }
        else if (interpolated_path && saw_extended_args) {
                struct strbuf expanded_path = STRBUF_INIT;
-               struct strbuf_expand_dict_entry dict[] = {
-                       { "H", hostname },
-                       { "CH", canon_hostname },
-                       { "IP", ip_address },
-                       { "P", tcp_port },
-                       { "D", directory },
-                       { NULL }
-               };
-
+               struct strbuf_expand_dict_entry dict[6];
+
+               dict[0].placeholder = "H"; dict[0].value = hostname;
+               dict[1].placeholder = "CH"; dict[1].value = canon_hostname;
+               dict[2].placeholder = "IP"; dict[2].value = ip_address;
+               dict[3].placeholder = "P"; dict[3].value = tcp_port;
+               dict[4].placeholder = "D"; dict[4].value = directory;
+               dict[5].placeholder = NULL; dict[5].value = NULL;
                if (*dir != '/') {
                        /* Allow only absolute */
                        logerror("'%s': Non-absolute path denied (interpolated-path active)", dir);
@@ -343,7 +342,9 @@ static int upload_pack(void)
 {
        /* Timeout as string */
        char timeout_buf[64];
-       const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
+       const char *argv[] = { "upload-pack", "--strict", NULL, ".", NULL };
+
+       argv[2] = timeout_buf;
 
        snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
        return run_service_command(argv);
@@ -733,11 +734,17 @@ static int set_reuse_addr(int sockfd)
                          &on, sizeof(on));
 }
 
+struct socketlist {
+       int *list;
+       size_t nr;
+       size_t alloc;
+};
+
 #ifndef NO_IPV6
 
-static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
+static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
 {
-       int socknum = 0, *socklist = NULL;
+       int socknum = 0;
        int maxfd = -1;
        char pbuf[NI_MAXSERV];
        struct addrinfo hints, *ai0, *ai;
@@ -752,8 +759,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
        hints.ai_flags = AI_PASSIVE;
 
        gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
-       if (gai)
-               die("getaddrinfo() failed: %s", gai_strerror(gai));
+       if (gai) {
+               logerror("getaddrinfo() for %s failed: %s", listen_addr, gai_strerror(gai));
+               return 0;
+       }
 
        for (ai = ai0; ai; ai = ai->ai_next) {
                int sockfd;
@@ -794,8 +803,9 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
                if (flags >= 0)
                        fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 
-               socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
-               socklist[socknum++] = sockfd;
+               ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
+               socklist->list[socklist->nr++] = sockfd;
+               socknum++;
 
                if (maxfd < sockfd)
                        maxfd = sockfd;
@@ -803,13 +813,12 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 
        freeaddrinfo(ai0);
 
-       *socklist_p = socklist;
        return socknum;
 }
 
 #else /* NO_IPV6 */
 
-static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
+static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
 {
        struct sockaddr_in sin;
        int sockfd;
@@ -850,22 +859,27 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
        if (flags >= 0)
                fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 
-       *socklist_p = xmalloc(sizeof(int));
-       **socklist_p = sockfd;
+       ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
+       socklist->list[socklist->nr++] = sockfd;
        return 1;
 }
 
 #endif
 
-static int service_loop(int socknum, int *socklist)
+static void socksetup(char *listen_addr, int listen_port, struct socketlist *socklist)
+{
+       setup_named_sock(listen_addr, listen_port, socklist);
+}
+
+static int service_loop(struct socketlist *socklist)
 {
        struct pollfd *pfd;
        int i;
 
-       pfd = xcalloc(socknum, sizeof(struct pollfd));
+       pfd = xcalloc(socklist->nr, sizeof(struct pollfd));
 
-       for (i = 0; i < socknum; i++) {
-               pfd[i].fd = socklist[i];
+       for (i = 0; i < socklist->nr; i++) {
+               pfd[i].fd = socklist->list[i];
                pfd[i].events = POLLIN;
        }
 
@@ -876,7 +890,7 @@ static int service_loop(int socknum, int *socklist)
 
                check_dead_children();
 
-               if (poll(pfd, socknum, -1) < 0) {
+               if (poll(pfd, socklist->nr, -1) < 0) {
                        if (errno != EINTR) {
                                logerror("Poll failed, resuming: %s",
                                      strerror(errno));
@@ -885,7 +899,7 @@ static int service_loop(int socknum, int *socklist)
                        continue;
                }
 
-               for (i = 0; i < socknum; i++) {
+               for (i = 0; i < socklist->nr; i++) {
                        if (pfd[i].revents & POLLIN) {
                                struct sockaddr_storage ss;
                                unsigned int sslen = sizeof(ss);
@@ -947,10 +961,10 @@ static void store_pid(const char *path)
 
 static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
 {
-       int socknum, *socklist;
+       struct socketlist socklist = { NULL, 0, 0 };
 
-       socknum = socksetup(listen_addr, listen_port, &socklist);
-       if (socknum == 0)
+       socksetup(listen_addr, listen_port, &socklist);
+       if (socklist.nr == 0)
                die("unable to allocate any listen sockets on host %s port %u",
                    listen_addr, listen_port);
 
@@ -959,7 +973,7 @@ static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t
             setuid(pass->pw_uid)))
                die("cannot drop privileges");
 
-       return service_loop(socknum, socklist);
+       return service_loop(&socklist);
 }
 
 int main(int argc, char **argv)