From 767419072cd4dfb52541b7fe2715bbb01bc8d561 Mon Sep 17 00:00:00 2001
From: Olivier Matz <zer0@droids-corp.org>
Date: Fri, 24 Dec 2010 13:54:19 +0100
Subject: [PATCH] cmdline (merge-intel): compilation under baremetal
 environment

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 src/lib/cmdline.c                 |   3 -
 src/lib/cmdline_parse_etheraddr.c |  34 ++++-
 src/lib/cmdline_parse_ipaddr.c    | 216 +++++++++++++++++++++++++++++-
 src/lib/cmdline_rdline.c          |   2 +-
 src/lib/cmdline_socket.c          |  35 ++---
 src/lib/cmdline_socket.h          |   7 +-
 6 files changed, 267 insertions(+), 30 deletions(-)

diff --git a/src/lib/cmdline.c b/src/lib/cmdline.c
index 5e7f009..6b2421c 100644
--- a/src/lib/cmdline.c
+++ b/src/lib/cmdline.c
@@ -67,10 +67,7 @@
 #include <inttypes.h>
 #include <fcntl.h>
 
-#include <sys/socket.h>
 #include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 
 #include "cmdline_parse.h"
 #include "cmdline_rdline.h"
diff --git a/src/lib/cmdline_parse_etheraddr.c b/src/lib/cmdline_parse_etheraddr.c
index cc2a4f4..d718081 100644
--- a/src/lib/cmdline_parse_etheraddr.c
+++ b/src/lib/cmdline_parse_etheraddr.c
@@ -65,11 +65,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/types.h>
-#include <sys/socket.h>
 #include <net/ethernet.h>
-#ifdef __linux__
-#include <netinet/ether.h>
-#endif
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_etheraddr.h"
@@ -84,6 +80,34 @@ struct cmdline_token_ops cmdline_token_etheraddr_ops = {
 
 #define ETHER_ADDRSTRLEN 18
 
+#ifdef __linux__
+#define ea_oct ether_addr_octet
+#else
+#define ea_oct octet
+#endif
+
+static struct ether_addr *
+my_ether_aton(const char *a)
+{
+	int i;
+	static struct ether_addr ether_addr;
+	unsigned int o0, o1, o2, o3, o4, o5;
+
+	i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
+
+	if (i != ETHER_ADDR_LEN)
+		return NULL;
+
+	ether_addr.ea_oct[0] = o0;
+	ether_addr.ea_oct[1] = o1;
+	ether_addr.ea_oct[2] = o2;
+	ether_addr.ea_oct[3] = o3;
+	ether_addr.ea_oct[4] = o4;
+	ether_addr.ea_oct[5] = o5;
+
+	return (struct ether_addr *)&ether_addr;
+}
+
 int
 cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 			const char *buf, void *res)
@@ -105,7 +129,7 @@ cmdline_parse_etheraddr(__attribute__((unused)) cmdline_parse_token_hdr_t *tk,
 
 	snprintf(ether_str, token_len+1, "%s", buf);
 
-	tmp = ether_aton(ether_str);
+	tmp = my_ether_aton(ether_str);
 	if (tmp == NULL)
 		return -1;
 
diff --git a/src/lib/cmdline_parse_ipaddr.c b/src/lib/cmdline_parse_ipaddr.c
index 2fe0155..2ffbf0c 100644
--- a/src/lib/cmdline_parse_ipaddr.c
+++ b/src/lib/cmdline_parse_ipaddr.c
@@ -59,6 +59,26 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * For inet_ntop() functions:
+ *
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -66,7 +86,9 @@
 #include <string.h>
 #include <errno.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
+#ifndef __linux__
+#include <net/socket.h>
+#endif
 
 #include "cmdline_parse.h"
 #include "cmdline_parse_ipaddr.h"
@@ -78,6 +100,194 @@ struct cmdline_token_ops cmdline_token_ipaddr_ops = {
 	.get_help = cmdline_get_help_ipaddr,
 };
 
+#define INADDRSZ 4
+#define IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, u_char *dst);
+static int inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *      convert from presentation format (which usually means ASCII printable)
+ *      to network format (which is usually some kind of binary format).
+ * return:
+ *      1 if the address was valid for the specified address family
+ *      0 if the address wasn't valid (`dst' is untouched in this case)
+ *      -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+my_inet_pton(int af, const char *src, void *dst)
+{
+	switch (af) {
+		case AF_INET:
+			return (inet_pton4(src, dst));
+		case AF_INET6:
+			return (inet_pton6(src, dst));
+		default:
+			errno = EAFNOSUPPORT;
+			return (-1);
+	}
+	/* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *      like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *      1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *      does not touch `dst' unless it's returning 1.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+	static const char digits[] = "0123456789";
+	int saw_digit, octets, ch;
+	u_char tmp[INADDRSZ], *tp;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr(digits, ch)) != NULL) {
+			u_int new = *tp * 10 + (pch - digits);
+
+			if (new > 255)
+				return (0);
+			if (! saw_digit) {
+				if (++octets > 4)
+					return (0);
+				saw_digit = 1;
+			}
+			*tp = new;
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return (0);
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return (0);
+	}
+	if (octets < 4)
+		return (0);
+
+	memcpy(dst, tmp, INADDRSZ);
+	return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *      convert presentation level address to network order binary form.
+ * return:
+ *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *      (1) does not touch `dst' unless it's returning 1.
+ *      (2) :: in a full address is silently ignored.
+ * credit:
+ *      inspired by Mark Andrews.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+	static const char xdigits_l[] = "0123456789abcdef",
+		xdigits_u[] = "0123456789ABCDEF";
+	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+	const char *xdigits, *curtok;
+	int ch, saw_xdigit, count_xdigit;
+	u_int val;
+
+	memset((tp = tmp), '\0', IN6ADDRSZ);
+	endp = tp + IN6ADDRSZ;
+	colonp = NULL;
+	/* Leading :: requires some special handling. */
+	if (*src == ':')
+		if (*++src != ':')
+			return (0);
+	curtok = src;
+	saw_xdigit = count_xdigit = 0;
+	val = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+			pch = strchr((xdigits = xdigits_u), ch);
+		if (pch != NULL) {
+			if (count_xdigit >= 4)
+				return (0);
+			val <<= 4;
+			val |= (pch - xdigits);
+			if (val > 0xffff)
+				return (0);
+			saw_xdigit = 1;
+			count_xdigit++;
+			continue;
+		}
+		if (ch == ':') {
+			curtok = src;
+			if (!saw_xdigit) {
+				if (colonp)
+					return (0);
+				colonp = tp;
+				continue;
+			} else if (*src == '\0') {
+				return (0);
+			}
+			if (tp + sizeof(int16_t) > endp)
+				return (0);
+			*tp++ = (u_char) (val >> 8) & 0xff;
+			*tp++ = (u_char) val & 0xff;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			val = 0;
+			continue;
+		}
+		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+		    inet_pton4(curtok, tp) > 0) {
+			tp += INADDRSZ;
+			saw_xdigit = 0;
+			count_xdigit = 0;
+			break;  /* '\0' was seen by inet_pton4(). */
+		}
+		return (0);
+	}
+	if (saw_xdigit) {
+		if (tp + sizeof(int16_t) > endp)
+			return (0);
+		*tp++ = (u_char) (val >> 8) & 0xff;
+		*tp++ = (u_char) val & 0xff;
+	}
+	if (colonp != NULL) {
+		/*
+		 * Since some memmove()'s erroneously fail to handle
+		 * overlapping regions, we'll do the shift by hand.
+		 */
+		const int n = tp - colonp;
+		int i;
+
+		for (i = 1; i <= n; i++) {
+			endp[- i] = colonp[n - i];
+			colonp[n - i] = 0;
+		}
+		tp = endp;
+	}
+	if (tp != endp)
+		return (0);
+	memcpy(dst, tmp, IN6ADDRSZ);
+	return (1);
+}
 
 int
 cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
@@ -120,12 +330,12 @@ cmdline_parse_ipaddr(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
 
 	/* convert the IP addr */
 	if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V4) &&
-	    inet_pton(AF_INET, ip_str, &ipaddr->addr.ipv4) == 1) {
+	    my_inet_pton(AF_INET, ip_str, &ipaddr->addr.ipv4) == 1) {
 		ipaddr->family = AF_INET;
 		return token_len;
 	}
 	if ((tk2->ipaddr_data.flags & CMDLINE_IPADDR_V6) &&
-	    inet_pton(AF_INET6, ip_str, &ipaddr->addr.ipv6) == 1) {
+	    my_inet_pton(AF_INET6, ip_str, &ipaddr->addr.ipv6) == 1) {
 		ipaddr->family = AF_INET6;
 		return token_len;
 	}
diff --git a/src/lib/cmdline_rdline.c b/src/lib/cmdline_rdline.c
index b1e961a..86d3a9c 100644
--- a/src/lib/cmdline_rdline.c
+++ b/src/lib/cmdline_rdline.c
@@ -460,7 +460,7 @@ rdline_char_in(struct rdline *rdl, char c)
 		return 0;
 	}
 
-	if (! isprint(c))
+	if (!isprint((int)c))
 		return 0;
 
 	/* standard chars */
diff --git a/src/lib/cmdline_socket.c b/src/lib/cmdline_socket.c
index 2e201f6..bba3847 100644
--- a/src/lib/cmdline_socket.c
+++ b/src/lib/cmdline_socket.c
@@ -67,10 +67,12 @@
 #include <inttypes.h>
 #include <fcntl.h>
 
+#ifndef CMDLINE_NO_SOCKET
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#endif
 
 #include "cmdline_parse.h"
 #include "cmdline_rdline.h"
@@ -78,6 +80,7 @@
 
 /**********************/
 
+#ifndef CMDLINE_NO_SOCKET
 int
 cmdline_tcpv4_listen(in_addr_t addr, uint16_t port)
 {
@@ -189,10 +192,22 @@ end:
 }
 
 struct cmdline *
-cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt)
+cmdline_accept(cmdline_parse_ctx_t *ctx, const char *prompt, int s)
 {
-	return (cmdline_new(ctx, prompt, 0, 1));
+	int s2;
+	struct sockaddr sin;
+	socklen_t sinlen;
+
+	sinlen = sizeof(struct sockaddr);
+
+	if ((s2 = accept(s, &sin, &sinlen)) < 0) {
+		dprintf("accept() failed\n");
+		return NULL;
+	}
+
+	return (cmdline_new(ctx, prompt, s2, s2));
 }
+#endif
 
 struct cmdline *
 cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
@@ -207,19 +222,7 @@ cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
 }
 
 struct cmdline *
-cmdline_accept(cmdline_parse_ctx_t *ctx, const char *prompt, int s)
+cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt)
 {
-	int s2;
-	struct sockaddr sin;
-	socklen_t sinlen;
-
-	sinlen = sizeof(struct sockaddr);
-
-	if ((s2 = accept(s, &sin, &sinlen)) < 0) {
-		dprintf("accept() failed\n");
-		return NULL;
-	}
-
-	return (cmdline_new(ctx, prompt, s2, s2));
+	return (cmdline_new(ctx, prompt, 0, 1));
 }
-
diff --git a/src/lib/cmdline_socket.h b/src/lib/cmdline_socket.h
index 0564086..5ef97ed 100644
--- a/src/lib/cmdline_socket.h
+++ b/src/lib/cmdline_socket.h
@@ -62,11 +62,14 @@
 #ifndef _CMDLINE_SOCKET_H_
 #define _CMDLINE_SOCKET_H_
 
+#ifndef CMDLINE_NO_SOCKET
 int cmdline_tcpv4_listen(in_addr_t addr, uint16_t port);
 int cmdline_tcpv6_listen(uint16_t port);
 int cmdline_unix_listen(char *filename);
-struct cmdline *cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt);
-struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path);
 struct cmdline *cmdline_accept(cmdline_parse_ctx_t *ctx, const char *prompt, int s);
+#endif
+
+struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path);
+struct cmdline *cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt);
 
 #endif /* _CMDLINE_SOCKET_H_ */
-- 
2.39.5