diff options
author | tmm <tmm@FreeBSD.org> | 2003-06-11 18:44:26 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2003-06-11 18:44:26 +0000 |
commit | 87b6b51235f73d1a422fbc9521b668670ff171c1 (patch) | |
tree | 024461877e00fe38f6b1a325d955b7471ed377f9 /usr.sbin/ofwdump | |
parent | 58baf8f0d2d563719e0d22eddef66cad04bbeaca (diff) | |
download | FreeBSD-src-87b6b51235f73d1a422fbc9521b668670ff171c1.zip FreeBSD-src-87b6b51235f73d1a422fbc9521b668670ff171c1.tar.gz |
Autosize the property buffer instead of limiting it to 8192, and
exiting if a property happens to be larger.
Diffstat (limited to 'usr.sbin/ofwdump')
-rw-r--r-- | usr.sbin/ofwdump/ofw_util.c | 80 | ||||
-rw-r--r-- | usr.sbin/ofwdump/ofw_util.h | 3 |
2 files changed, 76 insertions, 7 deletions
diff --git a/usr.sbin/ofwdump/ofw_util.c b/usr.sbin/ofwdump/ofw_util.c index 7a13652..13842bd 100644 --- a/usr.sbin/ofwdump/ofw_util.c +++ b/usr.sbin/ofwdump/ofw_util.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <vis.h> @@ -49,7 +50,7 @@ __FBSDID("$FreeBSD$"); #define CHARSPERLINE 60 #define BYTESPERLINE (CHARSPERLINE / 3) -/* Maximum supported property size. */ +/* Default space reserved for properties. */ #define PROPBUFLEN 8192 #define OFW_IOCTL(fd, cmd, val) do { \ @@ -146,6 +147,16 @@ ofw_nextprop(int fd, phandle_t node, char *prev, char *buf, int buflen) return (d.of_buflen); } +static void * +ofw_malloc(int size) +{ + void *p; + + if ((p = malloc(size)) == NULL) + err(1, "malloc() failed"); + return (p); +} + int ofw_getprop(int fd, phandle_t node, const char *name, void *buf, int buflen) { @@ -160,6 +171,47 @@ ofw_getprop(int fd, phandle_t node, const char *name, void *buf, int buflen) return (d.of_buflen); } +int +ofw_getproplen(int fd, phandle_t node, const char *name) +{ + struct ofiocdesc d; + + d.of_nodeid = node; + d.of_namelen = strlen(name); + d.of_name = name; + OFW_IOCTL(fd, OFIOCGETPROPLEN, &d); + return (d.of_buflen); +} + +int +ofw_getprop_alloc(int fd, phandle_t node, const char *name, void **buf, + int *buflen, int reserve) +{ + struct ofiocdesc d; + int len, rv; + + do { + len = ofw_getproplen(fd, node, name); + if (len < 0) + return (len); + if (*buflen < len + reserve) { + if (*buf != NULL) + free(*buf); + *buflen = len + reserve + PROPBUFLEN; + *buf = ofw_malloc(*buflen); + } + d.of_nodeid = node; + d.of_namelen = strlen(name); + d.of_name = name; + d.of_buflen = *buflen - reserve; + d.of_buf = *buf; + rv = ioctl(fd, OFIOCGET, &d); + } while (rv == -1 && errno == ENOMEM); + if (rv == -1) + err(1, "ioctl(..., OFIOCGET, ...) failed"); + return (d.of_buflen); +} + static void ofw_indent(int level) { @@ -173,9 +225,10 @@ static void ofw_dump_properties(int fd, phandle_t n, int level, char *pmatch, int raw, int str) { - static char pbuf[PROPBUFLEN]; - static char visbuf[PROPBUFLEN * 4 + 1]; + static char *pbuf; + static char *visbuf; static char printbuf[CHARSPERLINE + 1]; + static int pblen, vblen; char prop[32]; int nlen, len, i, j, max, vlen; unsigned int b; @@ -184,7 +237,9 @@ ofw_dump_properties(int fd, phandle_t n, int level, char *pmatch, int raw, nlen = ofw_nextprop(fd, n, prop, prop, sizeof(prop))) { if (pmatch != NULL && strcmp(pmatch, prop) != 0) continue; - len = ofw_getprop(fd, n, prop, pbuf, sizeof(pbuf) - 1); + len = ofw_getprop_alloc(fd, n, prop, (void **)&pbuf, &pblen, 1); + if (len < 0) + continue; if (raw) write(STDOUT_FILENO, pbuf, len); else if (str) { @@ -210,6 +265,12 @@ ofw_dump_properties(int fd, phandle_t n, int level, char *pmatch, int raw, */ if (pbuf[len - 1] == '\0' && strlen(pbuf) == (unsigned)len - 1) { + if (vblen < (len - 1) * 4 + 1) { + if (visbuf != NULL) + free(visbuf); + vblen = (PROPBUFLEN + len) * 4 + 1; + visbuf = ofw_malloc(vblen); + } vlen = strvis(visbuf, pbuf, VIS_TAB | VIS_NL); for (i = 0; i < vlen; i += CHARSPERLINE) { ofw_indent(level * LVLINDENT + @@ -227,15 +288,20 @@ static void ofw_dump_node(int fd, phandle_t n, int level, int rec, int prop, char *pmatch, int raw, int str) { - static char nbuf[PROPBUFLEN]; + static char *nbuf; + static int nblen = 0; + int plen; phandle_t c; if (!(raw || str)) { ofw_indent(level * LVLINDENT); printf("Node %#lx", (unsigned long)n); - if (ofw_getprop(fd, n, "name", nbuf, sizeof(nbuf) - 1) > 0) + plen = ofw_getprop_alloc(fd, n, "name", (void **)&nbuf, + &nblen, 1); + if (plen > 0) { + nbuf[plen] = '\0'; printf(": %s\n", nbuf); - else + } else putchar('\n'); } if (prop) diff --git a/usr.sbin/ofwdump/ofw_util.h b/usr.sbin/ofwdump/ofw_util.h index 9c03ce6..c267bb4 100644 --- a/usr.sbin/ofwdump/ofw_util.h +++ b/usr.sbin/ofwdump/ofw_util.h @@ -41,6 +41,9 @@ phandle_t ofw_finddevice(int, char *); int ofw_firstprop(int, phandle_t, char *, int); int ofw_nextprop(int, phandle_t, char *, char *, int); int ofw_getprop(int, phandle_t, const char *, void *, int); +int ofw_getproplen(int, phandle_t, const char *); +int ofw_getprop_alloc(int, phandle_t, const char *, void **, int *, + int); void ofw_dump(int, char *, int, int, char *, int, int); |