Module Name:    src
Committed By:   riz
Date:           Fri Aug 12 20:55:55 UTC 2011

Modified Files:
        src/sbin/drvctl [netbsd-5]: drvctl.8 drvctl.c

Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #1656):
        sbin/drvctl/drvctl.8: revision 1.11
        sbin/drvctl/drvctl.8: revision 1.12
        sbin/drvctl/drvctl.c: revision 1.11
        sbin/drvctl/drvctl.c: revision 1.12
add an optional argument to the -p flag that lets you extract specific
property values from the command-line:
  $ drvctl -p wd0 disk-info/geometry/cylinders-per-unit
  620181
  $ drvctl -p wd0 device-driver device-unit
  wd
  0
  $ drvctl -p wd0 nonexistent || echo "not found"
  not found
add the -t option that modifies -l behaviour to recursively scan for
child devices and print them in tree format:
$ drvctl -lt usb0
uhub0
  uhub6
    uhidev0
      ukbd0
        wskbd1
    uhidev1
      ums0
        wsmouse1
      uhid0
    ubt0


To generate a diff of this commit:
cvs rdiff -u -r1.5.10.2 -r1.5.10.3 src/sbin/drvctl/drvctl.8
cvs rdiff -u -r1.6.10.2 -r1.6.10.3 src/sbin/drvctl/drvctl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/drvctl/drvctl.8
diff -u src/sbin/drvctl/drvctl.8:1.5.10.2 src/sbin/drvctl/drvctl.8:1.5.10.3
--- src/sbin/drvctl/drvctl.8:1.5.10.2	Sat Jun  6 21:59:18 2009
+++ src/sbin/drvctl/drvctl.8	Fri Aug 12 20:55:55 2011
@@ -1,4 +1,4 @@
-.\" $NetBSD: drvctl.8,v 1.5.10.2 2009/06/06 21:59:18 bouyer Exp $
+.\" $NetBSD: drvctl.8,v 1.5.10.3 2011/08/12 20:55:55 riz Exp $
 .\"
 .\" Copyright (c) 2004
 .\" 	Matthias Drochner.  All rights reserved.
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 20, 2009
+.Dd August 7, 2011
 .Dt DRVCTL 8
 .Os
 .Sh NAME
@@ -40,12 +40,13 @@
 .Fl d
 .Ar device
 .Nm
-.Op Fl n
+.Op Fl nt
 .Fl l
 .Op Ar device
 .Nm
 .Fl p
 .Ar device
+.Op Ar property ...
 .Nm
 .Fl Q
 .Ar device
@@ -96,10 +97,13 @@
 .Fl l
 output.
 .It Fl p
-Get the properties for the device specified by the
+Get properties for the device specified by the
 .Ar device
 argument.
-The properties are displayed as an XML property list.
+If
+.Ar property
+is specified, the value of that property is printed, otherwise
+the properties are displayed as an XML property list.
 .It Fl Q
 Resume the ancestors of
 .Ar device ,
@@ -124,6 +128,10 @@
 and
 .Ar device
 itself.
+.It Fl t
+Print a tree of devices in
+.Fl l
+output.
 .El
 .Sh FILES
 .Pa /dev/drvctl

Index: src/sbin/drvctl/drvctl.c
diff -u src/sbin/drvctl/drvctl.c:1.6.10.2 src/sbin/drvctl/drvctl.c:1.6.10.3
--- src/sbin/drvctl/drvctl.c:1.6.10.2	Sat Jun  6 21:59:18 2009
+++ src/sbin/drvctl/drvctl.c	Fri Aug 12 20:55:55 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: drvctl.c,v 1.6.10.2 2009/06/06 21:59:18 bouyer Exp $ */
+/* $NetBSD: drvctl.c,v 1.6.10.3 2011/08/12 20:55:55 riz Exp $ */
 
 /*
  * Copyright (c) 2004
@@ -26,6 +26,7 @@
  * SUCH DAMAGE.
  */
 
+#include <inttypes.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,13 +37,15 @@
 #include <sys/ioctl.h>
 #include <sys/drvctlio.h>
 
-#define OPTS "QRSa:dlnpr"
+#define OPTS "QRSa:dlnprt"
 
 #define	OPEN_MODE(mode)							\
 	(((mode) == 'd' || (mode) == 'r') ? O_RDWR			\
 					  : O_RDONLY)
 
 static void usage(void);
+static void extract_property(prop_dictionary_t, const char *);
+static void list_children(int, char *, bool, bool, int);
 
 static void
 usage(void)
@@ -50,8 +53,8 @@
 
 	fprintf(stderr, "Usage: %s -r [-a attribute] busdevice [locator ...]\n"
 	    "       %s -d device\n"
-	    "       %s [-n] -l [device]\n"
-	    "       %s -p device\n"
+	    "       %s [-nt] -l [device]\n"
+	    "       %s -p device [prop]\n"
 	    "       %s -Q device\n"
 	    "       %s -R device\n"
 	    "       %s -S device\n",
@@ -63,16 +66,13 @@
 int
 main(int argc, char **argv)
 {
-	bool nflag = false;
+	bool nflag = false, tflag = false;
 	int c, mode;
 	char *attr = 0;
 	extern char *optarg;
 	extern int optind;
 	int fd, res;
-	size_t children;
 	struct devpmargs paa = {.devname = "", .flags = 0};
-	struct devlistargs laa = {.l_devname = "", .l_childname = NULL,
-				  .l_children = 0};
 	struct devdetachargs daa;
 	struct devrescanargs raa;
 	int *locs, i;
@@ -100,6 +100,9 @@
 		case 'n':
 			nflag = true;
 			break;
+		case 't':
+			tflag = nflag = true;
+			break;
 		case '?':
 		default:
 			usage();
@@ -139,31 +142,7 @@
 			err(3, "DRVDETACHDEV");
 		break;
 	case 'l':
-		if (argc == 0)
-			*laa.l_devname = '\0';
-		else
-			strlcpy(laa.l_devname, argv[0], sizeof(laa.l_devname));
-
-		if (ioctl(fd, DRVLISTDEV, &laa) == -1)
-			err(3, "DRVLISTDEV");
-
-		children = laa.l_children;
-
-		laa.l_childname = malloc(children * sizeof(laa.l_childname[0]));
-		if (laa.l_childname == NULL)
-			err(5, "DRVLISTDEV");
-		if (ioctl(fd, DRVLISTDEV, &laa) == -1)
-			err(3, "DRVLISTDEV");
-		if (laa.l_children > children)
-			err(6, "DRVLISTDEV: number of children grew");
-
-		for (i = 0; i < (int)laa.l_children; i++) {
-			if (!nflag) {
-				printf("%s ",
-				    (argc == 0) ? "root" : laa.l_devname);
-			}
-			printf("%s\n", laa.l_childname[i]);
-		}
+		list_children(fd, argc ? argv[0] : NULL, nflag, tflag, 0);
 		break;
 	case 'r':
 		memset(&raa, 0, sizeof(raa));
@@ -219,12 +198,17 @@
 			errx(3, "get-properties: failed to return result data");
 		}
 
-		xml = prop_dictionary_externalize(data_dict);
-		prop_object_release(results_dict);
+		if (argc == 1) {
+			xml = prop_dictionary_externalize(data_dict);
+			printf("Properties for device `%s':\n%s",
+			       argv[0], xml);
+			free(xml);
+		} else {
+			for (i = 1; i < argc; i++)
+				extract_property(data_dict, argv[i]);
+		}
 
-		printf("Properties for device `%s':\n%s",
-		       argv[0], xml);
-		free(xml);
+		prop_object_release(results_dict);
 		break;
 	default:
 		errx(4, "unknown command");
@@ -232,3 +216,96 @@
 
 	return (0);
 }
+
+static void
+extract_property(prop_dictionary_t dict, const char *prop)
+{
+	char *s, *p, *cur, *ep = NULL, *xml;
+	prop_object_t obj;
+
+	s = strdup(prop);
+	p = strtok_r(s, "/", &ep);
+	while (p) {
+		cur = p;
+		p = strtok_r(NULL, "/", &ep);
+		if (p) {
+			if (prop_dictionary_get_dict(dict, cur, &dict) == false)
+				exit(EXIT_FAILURE);
+		} else {
+			obj = prop_dictionary_get(dict, cur);
+			if (obj == NULL)
+				exit(EXIT_FAILURE);
+			switch (prop_object_type(obj)) {
+			case PROP_TYPE_BOOL:
+				printf("%s\n",
+				    prop_bool_true(obj) ? "true" : "false");
+				break;
+			case PROP_TYPE_NUMBER:
+				printf("%" PRId64 "\n",
+				    prop_number_integer_value(obj));
+				break;
+			case PROP_TYPE_STRING:
+				printf("%s\n",
+				    prop_string_cstring_nocopy(obj));
+				break;
+			case PROP_TYPE_DICTIONARY:
+				xml = prop_dictionary_externalize(obj);
+				printf("%s", xml);
+				free(xml);
+				break;
+			default:
+				fprintf(stderr, "unhandled type %d\n",
+				    prop_object_type(obj));
+				exit(EXIT_FAILURE);
+			}
+		}
+	}
+
+	free(s);
+}
+
+static void
+list_children(int fd, char *dvname, bool nflag, bool tflag, int depth)
+{
+	struct devlistargs laa = {.l_devname = "", .l_childname = NULL,
+				  .l_children = 0};
+	size_t children;
+	int i, n;
+
+	if (dvname == NULL) {
+		if (depth > 0)
+			return;
+		*laa.l_devname = '\0';
+	} else {
+		strlcpy(laa.l_devname, dvname, sizeof(laa.l_devname));
+	}
+
+	if (ioctl(fd, DRVLISTDEV, &laa) == -1)
+		err(3, "DRVLISTDEV");
+
+	children = laa.l_children;
+
+	laa.l_childname = malloc(children * sizeof(laa.l_childname[0]));
+	if (laa.l_childname == NULL)
+		err(5, "DRVLISTDEV");
+	if (ioctl(fd, DRVLISTDEV, &laa) == -1)
+		err(3, "DRVLISTDEV");
+	if (laa.l_children > children)
+		err(6, "DRVLISTDEV: number of children grew");
+
+	for (i = 0; i < (int)laa.l_children; i++) {
+		for (n = 0; n < depth; n++)
+			printf("  ");
+		if (!nflag) {
+			printf("%s ",
+			    (dvname == NULL) ? "root" : laa.l_devname);
+		}
+		printf("%s\n", laa.l_childname[i]);
+		if (tflag) {
+			list_children(fd, laa.l_childname[i], nflag,
+			    tflag, depth + 1);
+		}
+	}
+
+	free(laa.l_childname);
+}

Reply via email to