From bbe514683a43e81cab1d5ccc0436b9aaf984294b Mon Sep 17 00:00:00 2001
From: Denis Vlasenko <vda.linux@googlemail.com>
Date: Wed, 10 Jan 2007 20:19:56 +0000
Subject: a bit more IPv6-ization work syslogd: converted to use it (in -R
 host:port)

---
 include/libbb.h    | 23 ++++++++++++++++++++---
 libbb/xconnect.c   | 31 ++++++++++---------------------
 sysklogd/syslogd.c | 25 ++++++++-----------------
 3 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 16f092f60..62d5fcee4 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -298,12 +298,29 @@ extern int setsockopt_reuseaddr(int fd);
 extern int setsockopt_broadcast(int fd);
 /* Create server TCP socket bound to bindaddr:port. bindaddr can be NULL,
  * numeric IP ("N.N.N.N") or numeric IPv6 address,
- * and can have ":PORT" suffix. If no suffix trere, second argument is used */
+ * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
+ * If there is no suffix, port argument is used */
 extern int create_and_bind_stream_or_die(const char *bindaddr, int port);
 /* Create client TCP socket connected to peer:port. Peer cannot be NULL.
  * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname,
- * and can have ":PORT" suffix. If no suffix trere, second argument is used */
-extern int create_and_connect_stream_or_die(const char *peer, int def_port);
+ * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
+ * If there is no suffix, port argument is used */
+extern int create_and_connect_stream_or_die(const char *peer, int port);
+typedef struct len_and_sockaddr {
+	int len;
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in sin;
+#if ENABLE_FEATURE_IPV6
+		struct sockaddr_in6 sin6;
+#endif
+	};
+} len_and_sockaddr;
+/* Return malloc'ed len_and_sockaddr with socket address of host:port
+ * Currently will return IPv4 or IPv6 sockaddrs only
+ * (depending on host), but in theory nothing prevents e.g.
+ * UNIX socket address being returned, IPX sockaddr etc... */
+extern len_and_sockaddr* host2sockaddr(const char *host, int port);
 
 
 extern char *xstrdup(const char *s);
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index 93c3cd5c6..6e85322cf 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -83,25 +83,13 @@ int xconnect_tcp_v4(struct sockaddr_in *s_addr)
 /* "New" networking API */
 
 
-/* So far we do not expose struct and helpers to libbb */
-typedef struct len_and_sockaddr {
-	int len;
-	union {
-		struct sockaddr sa;
-		struct sockaddr_in sin;
-#if ENABLE_FEATURE_IPV6
-		struct sockaddr_in6 sin6;
-#endif
-	};
-} len_and_sockaddr;
 //extern int xsocket_stream_ip4or6(sa_family_t *fp);
-//extern len_and_sockaddr* host2sockaddr(const char *host, int def_port);
 //extern len_and_sockaddr* dotted2sockaddr(const char *dotted, int def_port);
 
 /* peer: "1.2.3.4[:port]", "www.google.com[:port]"
- * def_port: if neither of above specifies port #
+ * port: if neither of above specifies port #
  */
-static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_flags)
+static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags)
 {
 	int rc;
 	len_and_sockaddr *r; // = NULL;
@@ -126,12 +114,13 @@ static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_fla
 		}
 	}
 	if (cp) {
-		host = safe_strncpy(alloca(cp - host + 1), host, cp - host);
+		int sz = cp - host + 1;
+		host = safe_strncpy(alloca(sz), host, sz);
 		if (ENABLE_FEATURE_IPV6 && *cp != ':')
 			cp++; /* skip ']' */
 		cp++; /* skip ':' */
 	} else {
-		utoa_to_buf(def_port, service, sizeof(service));
+		utoa_to_buf(port, service, sizeof(service));
 		cp = service;
 	}
 
@@ -154,14 +143,14 @@ static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_fla
 	return r;
 }
 
-static len_and_sockaddr* host2sockaddr(const char *host, int def_port)
+len_and_sockaddr* host2sockaddr(const char *host, int port)
 {
-	return str2sockaddr(host, def_port, 0);
+	return str2sockaddr(host, port, 0);
 }
 
-static len_and_sockaddr* dotted2sockaddr(const char *host, int def_port)
+static len_and_sockaddr* dotted2sockaddr(const char *host, int port)
 {
-	return str2sockaddr(host, def_port, NI_NUMERICHOST);
+	return str2sockaddr(host, port, NI_NUMERICHOST);
 }
 
 static int xsocket_stream_ip4or6(len_and_sockaddr *lsa)
@@ -185,7 +174,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port)
 	int fd;
 	len_and_sockaddr *lsa;
 
-	if (bindaddr) {
+	if (bindaddr && bindaddr[0]) {
 		lsa = dotted2sockaddr(bindaddr, port);
 		/* currently NULL check is in str2sockaddr */
 		//if (!lsa)
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index aa7d516d6..405282796 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -53,7 +53,7 @@ static smallint isRegular;
 #include <netinet/in.h>
 /* udp socket for logging to remote host */
 static int remoteFD = -1;
-static struct sockaddr_in remoteAddr;
+static len_and_sockaddr* remoteAddr;
 #endif
 
 /* We are using bb_common_bufsiz1 for buffering: */
@@ -464,7 +464,7 @@ static void do_syslogd(void) ATTRIBUTE_NORETURN;
 static void do_syslogd(void)
 {
 	struct sockaddr_un sunx;
-	socklen_t addrLength;
+	socklen_t addr_len;
 	int sock_fd;
 	fd_set fds;
 
@@ -491,8 +491,8 @@ static void do_syslogd(void)
 	sunx.sun_family = AF_UNIX;
 	strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
 	sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
-	addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
-	xbind(sock_fd, (struct sockaddr *) &sunx, addrLength);
+	addr_len = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
+	xbind(sock_fd, (struct sockaddr *) &sunx, addr_len);
 
 	if (chmod(dev_log_name, 0666) < 0) {
 		bb_perror_msg_and_die("cannot set permission on %s", dev_log_name);
@@ -524,15 +524,14 @@ static void do_syslogd(void)
 #if ENABLE_FEATURE_REMOTE_LOG
 			/* We are not modifying log messages in any way before send */
 			/* Remote site cannot trust _us_ anyway and need to do validation again */
-			if (option_mask32 & OPT_remotelog) {
+			if (remoteAddr) {
 				if (-1 == remoteFD) {
-					remoteFD = socket(AF_INET, SOCK_DGRAM, 0);
+					remoteFD = socket(remoteAddr->sa.sa_family, SOCK_DGRAM, 0);
 				}
 				if (-1 != remoteFD) {
 					/* send message to remote logger, ignore possible error */
 					sendto(remoteFD, RECVBUF, i, MSG_DONTWAIT,
-						(struct sockaddr *) &remoteAddr,
-						sizeof(remoteAddr));
+						&remoteAddr->sa, remoteAddr->len);
 				}
 			}
 #endif
@@ -565,15 +564,7 @@ int syslogd_main(int argc, char **argv)
 #endif
 #if ENABLE_FEATURE_REMOTE_LOG
 	if (option_mask32 & OPT_remotelog) { // -R
-		int port = 514;
-		p = strchr(opt_R, ':');
-		if (p) {
-			*p++ = '\0';
-			port = xatou16(p);
-		}
-		/* FIXME: looks ip4-specific. need to do better */
-		bb_lookup_host(&remoteAddr, opt_R);
-		remoteAddr.sin_port = bb_lookup_port(port, "udp", port);
+		remoteAddr = host2sockaddr(opt_R, 514);
 	}
 	//if (option_mask32 & OPT_locallog) // -L
 #endif
-- 
cgit v1.2.3