return -1;
}
-static int execute(void)
+static int execute(struct sockaddr *addr)
{
static char line[1000];
- int len;
+ int pktlen, len;
+
+ if (addr) {
+ char addrbuf[256] = "";
+ int port = -1;
+
+ if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *sin_addr = (void *) addr;
+ inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
+ port = sin_addr->sin_port;
+#ifndef NO_IPV6
+ } else if (addr && addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin6_addr = (void *) addr;
+
+ char *buf = addrbuf;
+ *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
+ inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
+ strcat(buf, "]");
+
+ port = sin6_addr->sin6_port;
+#endif
+ }
+ loginfo("Connection from %s:%d", addrbuf, port);
+ }
alarm(init_timeout ? init_timeout : timeout);
- len = packet_read_line(0, line, sizeof(line));
+ pktlen = packet_read_line(0, line, sizeof(line));
alarm(0);
+ len = strlen(line);
+ if (pktlen != len)
+ loginfo("Extended attributes (%d bytes) exist <%.*s>",
+ (int) pktlen - len,
+ (int) pktlen - len, line + len + 1);
if (len && line[len-1] == '\n')
line[--len] = 0;
static void handle(int incoming, struct sockaddr *addr, int addrlen)
{
pid_t pid = fork();
- char addrbuf[256] = "";
- int port = -1;
if (pid) {
unsigned idx;
dup2(incoming, 1);
close(incoming);
- if (addr->sa_family == AF_INET) {
- struct sockaddr_in *sin_addr = (void *) addr;
- 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;
-
- char *buf = addrbuf;
- *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
- inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
- strcat(buf, "]");
-
- port = sin6_addr->sin6_port;
-#endif
- }
- loginfo("Connection from %s:%d", addrbuf, port);
-
- exit(execute());
+ exit(execute(addr));
}
static void child_handler(int signo)
if (set_reuse_addr(sockfd)) {
close(sockfd);
- return 0; /* not fatal */
+ continue;
}
if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
int inetd_mode = 0;
int i;
+ /* Without this we cannot rely on waitpid() to tell
+ * what happened to our children.
+ */
+ signal(SIGCHLD, SIG_DFL);
+
for (i = 1; i < argc; i++) {
char *arg = argv[i];
}
if (inetd_mode) {
- fclose(stderr); //FIXME: workaround
- return execute();
+ struct sockaddr_storage ss;
+ struct sockaddr *peer = (struct sockaddr *)&ss;
+ socklen_t slen = sizeof(ss);
+
+ freopen("/dev/null", "w", stderr);
+
+ if (getpeername(0, peer, &slen))
+ peer = NULL;
+
+ return execute(peer);
}
return serve(port);