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); +}