|
|
|
@ -1,9 +1,11 @@
@@ -1,9 +1,11 @@
|
|
|
|
|
#include "cache.h" |
|
|
|
|
#include "pkt-line.h" |
|
|
|
|
#include <alloca.h> |
|
|
|
|
#include <signal.h> |
|
|
|
|
#include <sys/wait.h> |
|
|
|
|
#include <sys/socket.h> |
|
|
|
|
#include <sys/time.h> |
|
|
|
|
#include <sys/poll.h> |
|
|
|
|
#include <netdb.h> |
|
|
|
|
#include <netinet/in.h> |
|
|
|
|
#include <arpa/inet.h> |
|
|
|
@ -328,6 +330,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
@@ -328,6 +330,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
|
|
|
|
inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf)); |
|
|
|
|
port = sin_addr->sin_port; |
|
|
|
|
|
|
|
|
|
#ifndef NO_IPV6 |
|
|
|
|
} else if (addr->sa_family == AF_INET6) { |
|
|
|
|
struct sockaddr_in6 *sin6_addr = (void *) addr; |
|
|
|
|
|
|
|
|
@ -337,6 +340,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
@@ -337,6 +340,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
|
|
|
|
strcat(buf, "]"); |
|
|
|
|
|
|
|
|
|
port = sin6_addr->sin6_port; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
loginfo("Connection from %s:%d", addrbuf, port); |
|
|
|
|
|
|
|
|
@ -369,16 +373,17 @@ static void child_handler(int signo)
@@ -369,16 +373,17 @@ static void child_handler(int signo)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int serve(int port) |
|
|
|
|
#ifndef NO_IPV6 |
|
|
|
|
|
|
|
|
|
static int socksetup(int port, int **socklist_p) |
|
|
|
|
{ |
|
|
|
|
struct addrinfo hints, *ai0, *ai; |
|
|
|
|
int gai; |
|
|
|
|
int socknum = 0, *socklist = NULL; |
|
|
|
|
int maxfd = -1; |
|
|
|
|
fd_set fds_init, fds; |
|
|
|
|
char pbuf[NI_MAXSERV]; |
|
|
|
|
|
|
|
|
|
signal(SIGCHLD, child_handler); |
|
|
|
|
struct addrinfo hints, *ai0, *ai; |
|
|
|
|
int gai; |
|
|
|
|
|
|
|
|
|
sprintf(pbuf, "%d", port); |
|
|
|
|
memset(&hints, 0, sizeof(hints)); |
|
|
|
@ -438,16 +443,59 @@ static int serve(int port)
@@ -438,16 +443,59 @@ static int serve(int port)
|
|
|
|
|
|
|
|
|
|
freeaddrinfo(ai0); |
|
|
|
|
|
|
|
|
|
if (socknum == 0) |
|
|
|
|
die("unable to allocate any listen sockets on port %u", port); |
|
|
|
|
*socklist_p = socklist; |
|
|
|
|
return socknum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else /* NO_IPV6 */ |
|
|
|
|
|
|
|
|
|
static int socksetup(int port, int **socklist_p) |
|
|
|
|
{ |
|
|
|
|
struct sockaddr_in sin; |
|
|
|
|
int sockfd; |
|
|
|
|
|
|
|
|
|
sockfd = socket(AF_INET, SOCK_STREAM, 0); |
|
|
|
|
if (sockfd < 0) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
memset(&sin, 0, sizeof sin); |
|
|
|
|
sin.sin_family = AF_INET; |
|
|
|
|
sin.sin_addr.s_addr = htonl(INADDR_ANY); |
|
|
|
|
sin.sin_port = htons(port); |
|
|
|
|
|
|
|
|
|
if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { |
|
|
|
|
close(sockfd); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*socklist_p = malloc(sizeof(int)); |
|
|
|
|
if ( !*socklist_p ) |
|
|
|
|
die("memory allocation failed: %s", strerror(errno)); |
|
|
|
|
**socklist_p = sockfd; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static int service_loop(int socknum, int *socklist) |
|
|
|
|
{ |
|
|
|
|
struct pollfd *pfd; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
pfd = calloc(socknum, sizeof(struct pollfd)); |
|
|
|
|
if (!pfd) |
|
|
|
|
die("memory allocation failed: %s", strerror(errno)); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < socknum; i++) { |
|
|
|
|
pfd[i].fd = socklist[i]; |
|
|
|
|
pfd[i].events = POLLIN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
int i; |
|
|
|
|
fds = fds_init; |
|
|
|
|
|
|
|
|
|
if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 0) { |
|
|
|
|
|
|
|
|
|
if (poll(pfd, socknum, 0) < 0) { |
|
|
|
|
if (errno != EINTR) { |
|
|
|
|
error("select failed, resuming: %s", |
|
|
|
|
error("poll failed, resuming: %s", |
|
|
|
|
strerror(errno)); |
|
|
|
|
sleep(1); |
|
|
|
|
} |
|
|
|
@ -455,12 +503,10 @@ static int serve(int port)
@@ -455,12 +503,10 @@ static int serve(int port)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (i = 0; i < socknum; i++) { |
|
|
|
|
int sockfd = socklist[i]; |
|
|
|
|
|
|
|
|
|
if (FD_ISSET(sockfd, &fds)) { |
|
|
|
|
if (pfd[i].revents & POLLIN) { |
|
|
|
|
struct sockaddr_storage ss; |
|
|
|
|
int sslen = sizeof(ss); |
|
|
|
|
int incoming = accept(sockfd, (struct sockaddr *)&ss, &sslen); |
|
|
|
|
int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen); |
|
|
|
|
if (incoming < 0) { |
|
|
|
|
switch (errno) { |
|
|
|
|
case EAGAIN: |
|
|
|
@ -477,6 +523,19 @@ static int serve(int port)
@@ -477,6 +523,19 @@ static int serve(int port)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int serve(int port) |
|
|
|
|
{ |
|
|
|
|
int socknum, *socklist; |
|
|
|
|
|
|
|
|
|
signal(SIGCHLD, child_handler); |
|
|
|
|
|
|
|
|
|
socknum = socksetup(port, &socklist); |
|
|
|
|
if (socknum == 0) |
|
|
|
|
die("unable to allocate any listen sockets on port %u", port); |
|
|
|
|
|
|
|
|
|
return service_loop(socknum, socklist); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv) |
|
|
|
|
{ |
|
|
|
|
int port = DEFAULT_GIT_PORT; |
|
|
|
@ -526,7 +585,7 @@ int main(int argc, char **argv)
@@ -526,7 +585,7 @@ int main(int argc, char **argv)
|
|
|
|
|
if (inetd_mode) { |
|
|
|
|
fclose(stderr); //FIXME: workaround |
|
|
|
|
return execute(); |
|
|
|
|
} else { |
|
|
|
|
return serve(port); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return serve(port); |
|
|
|
|
} |
|
|
|
|