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