summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 918e723)
raw | patch | inline | side by side (parent: 918e723)
author | Peter Anvin <hpa@tazenda.sc.orionmulti.com> | |
Thu, 29 Sep 2005 00:26:44 +0000 (17:26 -0700) | ||
committer | Peter Anvin <hpa@tazenda.sc.orionmulti.com> | |
Thu, 29 Sep 2005 00:26:44 +0000 (17:26 -0700) |
Makefile | patch | blob | history | |
connect.c | patch | blob | history | |
daemon.c | patch | blob | history |
diff --git a/Makefile b/Makefile
index be5c0a860599b16264ab95abd75f51776116aafc..2183903965cb67e614e654accfd996d7bae5b1b7 100644 (file)
--- a/Makefile
+++ b/Makefile
LIB_OBJS += compat/strcasestr.o
endif
ifdef NO_IPV6
- DEFINES += -DNO_IPV6
+ DEFINES += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in
endif
ifdef PPC_SHA1
diff --git a/connect.c b/connect.c
index 39d320ce280f4448b52865cc5386acc2099744c7..b157cf1cc718bbd7b8f4598b2dcb3a7ba92bb8e3 100644 (file)
--- a/connect.c
+++ b/connect.c
memset(&sa, 0, sizeof sa);
sa.sin_family = he->h_addrtype;
- sa.sin_port = nport;
+ sa.sin_port = htons(nport);
memcpy(&sa.sin_addr, ap, he->h_length);
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
diff --git a/daemon.c b/daemon.c
index a369ce527eb4bd36528ce53da1048618d2373341..79e72e0bddc47c755b69886b9a97acc04896efe9 100644 (file)
--- a/daemon.c
+++ b/daemon.c
#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>
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;
strcat(buf, "]");
port = sin6_addr->sin6_port;
+#endif
}
loginfo("Connection from %s:%d", addrbuf, port);
}
}
-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));
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);
}
}
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:
}
}
+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;
if (inetd_mode) {
fclose(stderr); //FIXME: workaround
return execute();
+ } else {
+ return serve(port);
}
-
- return serve(port);
}