socsvn commit: r270817 - soc2014/zkorchev/freebsd_head/usr.bin/sockstat

zkorchev at FreeBSD.org zkorchev at FreeBSD.org
Mon Jul 14 10:16:12 UTC 2014


Author: zkorchev
Date: Mon Jul 14 10:16:11 2014
New Revision: 270817
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=270817

Log:
  libsol support for sockstat

Modified:
  soc2014/zkorchev/freebsd_head/usr.bin/sockstat/Makefile
  soc2014/zkorchev/freebsd_head/usr.bin/sockstat/sockstat.c

Modified: soc2014/zkorchev/freebsd_head/usr.bin/sockstat/Makefile
==============================================================================
--- soc2014/zkorchev/freebsd_head/usr.bin/sockstat/Makefile	Mon Jul 14 10:15:44 2014	(r270816)
+++ soc2014/zkorchev/freebsd_head/usr.bin/sockstat/Makefile	Mon Jul 14 10:16:11 2014	(r270817)
@@ -2,4 +2,7 @@
 
 PROG=		sockstat
 
+LDADD+=	-lsol
+CFLAGS+=-DSOL_ON -I/usr/local/include
+
 .include <bsd.prog.mk>

Modified: soc2014/zkorchev/freebsd_head/usr.bin/sockstat/sockstat.c
==============================================================================
--- soc2014/zkorchev/freebsd_head/usr.bin/sockstat/sockstat.c	Mon Jul 14 10:15:44 2014	(r270816)
+++ soc2014/zkorchev/freebsd_head/usr.bin/sockstat/sockstat.c	Mon Jul 14 10:16:11 2014	(r270817)
@@ -58,6 +58,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#if defined(SOL_ON)
+# include <sol.h>
+#endif
 
 static int	 opt_4;		/* Show IPv4 sockets */
 static int	 opt_6;		/* Show IPv6 sockets */
@@ -68,6 +71,11 @@
 static int	 opt_u;		/* Show Unix domain sockets */
 static int	 opt_v;		/* Verbose mode */
 
+#if defined(SOL_ON)
+static struct sol_stream sol_stream;
+#endif
+static int sol_format;
+
 /*
  * Default protocols to use if no -P was defined.
  */
@@ -519,14 +527,36 @@
 	case AF_UNIX:
 		sun = (struct sockaddr_un *)ss;
 		off = (int)((char *)&sun->sun_path - (char *)sun);
-		return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
+#if defined(SOL_ON)
+		if (sol_format)
+			return sol_string(&sol_stream, sun->sun_path, strlen(sun->sun_path));
+		else
+#endif
+			return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
 	}
 	if (addrstr[0] == '\0')
 		inet_ntop(af, addr, addrstr, sizeof addrstr);
-	if (port == 0)
-		return xprintf("%s:*", addrstr);
+#if defined(SOL_ON)
+	if (sol_format)
+	{
+		char buf[INET6_ADDRSTRLEN + 1 + 20 + 1];
+		size_t len;
+
+		if (port == 0)
+			len = sprintf(buf, "%s:*", addrstr);
+		else
+			len = sprintf(buf, "%s:%d", addrstr, port);
+		sol_string(&sol_stream, buf, len);
+		return len;
+	}
 	else
-		return xprintf("%s:%d", addrstr, port);
+#endif
+	{
+		if (port == 0)
+			return xprintf("%s:*", addrstr);
+		else
+			return xprintf("%s:%d", addrstr, port);
+	}
 }
 
 static const char *
@@ -601,6 +631,64 @@
 	void *p;
 	int hash;
 
+#if defined(SOL_ON)
+	if (sol_format) {
+		char version[2], *c = version;
+
+		SOL_MAP_KEYL(&sol_stream, "protocol");
+		sol_string(&sol_stream, s->protoname, strlen(s->protoname));
+
+		if (s->vflag & INP_IPV4)
+			*c++ = '4';
+		if (s->vflag & INP_IPV6)
+			*c++ = '6';
+		if (c > version) {
+			SOL_MAP_KEYL(&sol_stream, "version");
+			sol_string(&sol_stream, version, c - version);
+		}
+		switch (s->family) {
+		case AF_INET:
+		case AF_INET6:
+			SOL_MAP_KEYL(&sol_stream, "local");
+			printaddr(s->family, &s->laddr);
+			SOL_MAP_KEYL(&sol_stream, "foreign");
+			printaddr(s->family, &s->faddr);
+			break;
+		case AF_UNIX:
+			/* server */
+			if (s->laddr.ss_len > 0) {
+				SOL_MAP_KEYL(&sol_stream, "server");
+				pos += printaddr(s->family, &s->laddr);
+				break;
+			}
+			/* client */
+			p = *(void **)&s->faddr;
+			if (p == NULL) {
+				SOL_MAP_KEYL(&sol_stream, "connected");
+				sol_boolean(&sol_stream, 0);
+				break;
+			}
+			SOL_MAP_KEYL(&sol_stream, "->");
+			for (hash = 0; hash < HASHSIZE; ++hash) {
+				for (s = sockhash[hash]; s != NULL; s = s->next)
+					if (s->pcb == p)
+						break;
+				if (s != NULL)
+					break;
+			}
+			if (s == NULL || s->laddr.ss_len == 0)
+				sol_string(&sol_stream, "??", 2);
+			else
+				printaddr(s->family, &s->laddr);
+			break;
+		default:
+			abort();
+		}
+
+		return;
+	}
+#endif
+
 	while (pos < 29)
 		pos += xprintf(" ");
 	pos += xprintf("%s", s->protoname);
@@ -659,9 +747,15 @@
 	struct sock *s;
 	int hash, n, pos;
 
-	printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s\n",
-	    "USER", "COMMAND", "PID", "FD", "PROTO",
-	    "LOCAL ADDRESS", "FOREIGN ADDRESS");
+#if defined(SOL_ON)
+	sol_format = sol_init(&sol_stream);
+	if (sol_format)
+		sol_array_start(&sol_stream);
+	else
+#endif
+		printf("%-8s %-10s %-5s %-2s %-6s %-21s %-21s\n",
+			"USER", "COMMAND", "PID", "FD", "PROTO",
+			"LOCAL ADDRESS", "FOREIGN ADDRESS");
 	setpassent(1);
 	for (xf = xfiles, n = 0; n < nxfiles; ++n, ++xf) {
 		if (xf->xf_data == NULL)
@@ -678,35 +772,87 @@
 			continue;
 		s->shown = 1;
 		pos = 0;
-		if ((pwd = getpwuid(xf->xf_uid)) == NULL)
-			pos += xprintf("%lu ", (u_long)xf->xf_uid);
+
+#if defined(SOL_ON)
+		if (sol_format)
+		{
+			const char *cmd = getprocname(xf->xf_pid);
+
+			sol_map_start(&sol_stream);
+			if ((pwd = getpwuid(xf->xf_uid)) == NULL) {
+				SOL_MAP_KEYL(&sol_stream, "uid");
+				sol_integer(&sol_stream, xf->xf_uid);
+			}
+			else {
+				SOL_MAP_KEYL(&sol_stream, "user");
+				sol_string(&sol_stream, pwd->pw_name, strlen(pwd->pw_name));
+			}
+			SOL_MAP_KEYL(&sol_stream, "cmd");
+			sol_string(&sol_stream, cmd, strlen(cmd));
+			SOL_MAP_KEYL(&sol_stream, "pid");
+			sol_integer(&sol_stream, xf->xf_pid);
+			SOL_MAP_KEYL(&sol_stream, "fd");
+			sol_integer(&sol_stream, xf->xf_fd);
+			displaysock(s, pos);
+			sol_map_end(&sol_stream);
+		}
 		else
-			pos += xprintf("%s ", pwd->pw_name);
-		while (pos < 9)
-			pos += xprintf(" ");
-		pos += xprintf("%.10s", getprocname(xf->xf_pid));
-		while (pos < 20)
-			pos += xprintf(" ");
-		pos += xprintf("%lu ", (u_long)xf->xf_pid);
-		while (pos < 26)
-			pos += xprintf(" ");
-		pos += xprintf("%d ", xf->xf_fd);
-		displaysock(s, pos);
+#endif
+		{
+			if ((pwd = getpwuid(xf->xf_uid)) == NULL)
+				pos += xprintf("%lu ", (u_long)xf->xf_uid);
+			else
+				pos += xprintf("%s ", pwd->pw_name);
+			while (pos < 9)
+				pos += xprintf(" ");
+			pos += xprintf("%.10s", getprocname(xf->xf_pid));
+			while (pos < 20)
+				pos += xprintf(" ");
+			pos += xprintf("%lu ", (u_long)xf->xf_pid);
+			while (pos < 26)
+				pos += xprintf(" ");
+			pos += xprintf("%d ", xf->xf_fd);
+			displaysock(s, pos);
+		}
 	}
-	if (opt_j >= 0)
+	if (opt_j >= 0) {
+#if defined(SOL_ON)
+		if (sol_format) {
+			sol_array_end(&sol_stream);
+			sol_term(&sol_stream);
+		}
+#endif
 		return;
+	}
 	for (hash = 0; hash < HASHSIZE; hash++) {
 		for (s = sockhash[hash]; s != NULL; s = s->next) {
 			if (s->shown)
 				continue;
 			if (!check_ports(s))
 				continue;
-			pos = 0;
-			pos += xprintf("%-8s %-10s %-5s %-2s ",
-			    "?", "?", "?", "?");
+#if defined(SOL_ON)
+			if (sol_format)
+				sol_map_start(&sol_stream);
+			else
+#endif
+			{
+				pos = 0;
+				pos += xprintf("%-8s %-10s %-5s %-2s ",
+					"?", "?", "?", "?");
+			}
 			displaysock(s, pos);
+#if defined(SOL_ON)
+			if (sol_format) sol_map_end(&sol_stream);
+#endif
 		}
 	}
+
+#if defined(SOL_ON)
+	if (sol_format) {
+		sol_array_end(&sol_stream);
+		sol_term(&sol_stream);
+	}
+#endif
 }
 
 static int set_default_protos(void)


More information about the svn-soc-all mailing list