Subject: Re: need testers
To: Michael <macallan18@earthlink.net>
From: Nathan J. Williams <nathanw@wasabisystems.com>
List: port-macppc
Date: 12/19/2004 16:33:01
--=-=-=

Michael <macallan18@earthlink.net> writes:

> > I would expect / hope that there was something like a list command in
> > OF that allowed to navigate the OF-tree.

Or, when running netbsd, you can compile and run the attached.

        - Nathan


--=-=-=
Content-Type: application/x-sh
Content-Disposition: attachment; filename=walkopenfirm.shar
Content-Description: program to dump OF tree

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	walkopenfirm/Makefile
#	walkopenfirm/walkopenfirm.c
#
echo x - walkopenfirm/Makefile
sed 's/^X//' >walkopenfirm/Makefile << 'END-of-walkopenfirm/Makefile'
X
XPROG=   walkopenfirm
XSRCS=   walkopenfirm.c
X
XWARNS=2
X
XNOMAN=
X
X.include <bsd.prog.mk>
END-of-walkopenfirm/Makefile
echo x - walkopenfirm/walkopenfirm.c
sed 's/^X//' >walkopenfirm/walkopenfirm.c << 'END-of-walkopenfirm/walkopenfirm.c'
X
X#include <ctype.h>
X#include <err.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <limits.h>
X#include <unistd.h>
X
X#include <sys/ioctl.h>
X#include <dev/ofw/openfirmio.h>
X
X#define OFWPATH "/dev/openfirm"
X
X#define BUFSIZE 16384
X
Xstatic void usage(void);
Xvoid walkdev(int fd, char *name);
Xvoid walknode(int fd, int nodeid, int level);
Xvoid printprop(struct ofiocdesc *node, int level);
X
Xint
Xmain(int argc, char *argv[])
X{
X	int ofwfd;
X	char startnode[256];
X	int ch;
X	extern char *optarg;
X	extern int optind;
X
X	strcpy(startnode, "/");
X	while((ch = getopt(argc, argv, "n:")) != -1)
X		switch (ch) {
X		case 'n':
X			strcpy(startnode, optarg);
X			break;
X		case '?':
X		default: 
X			usage();
X		}
X	
X	argc += optind;
X	argv -= optind;
X
X	ofwfd = open(OFWPATH, O_RDONLY, 0);
X	if (ofwfd == -1)
X		err(EXIT_FAILURE, "Couldn't open %s", OFWPATH);
X
X	walkdev(ofwfd, startnode);
X
X	close(ofwfd);
X
X	return 0;
X
X}
X
Xvoid
Xwalkdev(int fd, char *name)
X{
X	struct ofiocdesc node;
X	int ret;
X
X	node.of_nodeid = 0;
X	node.of_name = name;
X	node.of_namelen = strlen(name);
X
X	ret = ioctl(fd, OFIOCFINDDEVICE, &node);
X	if (ret == -1)
X		err(EXIT_FAILURE, "Couldn't find start node %s", name);
X	
X	walknode(fd, node.of_nodeid, 0);
X	
X}
X
Xvoid
Xwalknode(int fd, int nodeid, int level)
X{
X	struct ofiocdesc ofc;
X	char buf1[BUFSIZE], buf2[BUFSIZE];
X	char *swap;
X	int childnodeid;
X	int ret;
X
X	ofc.of_namelen = BUFSIZE;
X	ofc.of_name = buf1;
X	ofc.of_buf = buf2;
X
X
X	while (nodeid != 0) {
X		/* Get information about the node */
X		ofc.of_nodeid = nodeid;
X		strcpy(ofc.of_name, "name");
X		ofc.of_namelen = strlen(ofc.of_name);
X
X		ofc.of_buflen = BUFSIZE;
X		ret = ioctl(fd, OFIOCGET, &ofc);
X		if (ret == -1)
X			err(EXIT_FAILURE, "Couldn't get name of %x", nodeid);
X		printf("%*sNode %s (%8x)\n", 
X		    level, "", ofc.of_buf, nodeid);
X
X		/* Get all the properties */
X		ofc.of_buflen = BUFSIZE;
X		while (ioctl(fd, OFIOCNEXTPROP, &ofc) == 0) {
X			ofc.of_buf[ofc.of_buflen] = '\0';
X			printf("%*s  Property %-30s\n", level, "", 
X			    ofc.of_buf);
X			swap = ofc.of_name;
X			ofc.of_name = ofc.of_buf;
X			ofc.of_namelen = ofc.of_buflen;
X			ofc.of_buf = swap;
X			ofc.of_buflen = BUFSIZE;
X			
X			ret = ioctl(fd, OFIOCGET, &ofc);
X			if (ret == -1)
X				err(EXIT_FAILURE, "Couldn't get value "
X				    "of property %s", ofc.of_name);
X			printprop(&ofc, level);
X					
X			ofc.of_buflen = BUFSIZE;
X		}
X		if (errno != ENOENT)
X			err(EXIT_FAILURE, "Error getting next property");
X
X		/* Find the child pointer and walk it */
X		childnodeid = nodeid;
X		ret = ioctl(fd, OFIOCGETCHILD, &childnodeid);
X		if (ret == -1)
X			err(EXIT_FAILURE, "Couldn't get child of %x", nodeid);
X
X		if (childnodeid != 0)
X			walknode(fd, childnodeid, level + 2);
X
X		/* Find the next sibling */
X		ret = ioctl(fd, OFIOCGETNEXT, &nodeid);
X		if (ret == -1)
X			err(EXIT_FAILURE, "Couldn't get sibling of %x", 
X			    nodeid);
X	}
X
X}
X
Xvoid
Xprintprop(struct ofiocdesc *node, int level)
X{
X	int i, j;
X	char strbuf[17];
X
X	strbuf[16] = '\0';
X	for (i = 0; i < node->of_buflen; i += 16) {
X		printf("%*s", level + 2, "");
X		for (j = 0; j < 16; j++) {
X			if ((j % 4) == 0)
X				printf(" ");
X			if (i + j < node->of_buflen) {
X				printf("%02x", node->of_buf[i+j]);
X				strbuf[j] = isprint(node->of_buf[i+j]) ?
X				    node->of_buf[i+j] : '.';
X			} else {
X				printf("  ");
X				strbuf[j] = ' ';
X			}
X
X		}
X		printf(" %s\n", strbuf);
X	}
X}
X
X
Xstatic void
Xusage(void)
X{
X	fprintf(stderr, "usage: walkopenfirm [-n startnode]\n");
X	exit(1);
X}
X
END-of-walkopenfirm/walkopenfirm.c
exit


--=-=-=--