diff options
-rw-r--r-- | lib/libusbhid/Makefile | 3 | ||||
-rw-r--r-- | lib/libusbhid/data.c | 25 | ||||
-rw-r--r-- | lib/libusbhid/descr.c | 6 | ||||
-rw-r--r-- | lib/libusbhid/parse.c | 29 | ||||
-rw-r--r-- | lib/libusbhid/shlib_version | 2 | ||||
-rw-r--r-- | lib/libusbhid/usage.c | 135 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.3 | 10 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.h | 34 | ||||
-rw-r--r-- | usr.bin/usbhidaction/usbhidaction.c | 38 | ||||
-rw-r--r-- | usr.bin/usbhidctl/usbhid.c | 5 |
10 files changed, 164 insertions, 123 deletions
diff --git a/lib/libusbhid/Makefile b/lib/libusbhid/Makefile index bc9019379d6..9293669de9d 100644 --- a/lib/libusbhid/Makefile +++ b/lib/libusbhid/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.2 2002/09/06 00:23:12 brad Exp $ +# $OpenBSD: Makefile,v 1.3 2004/06/04 00:47:32 deraadt Exp $ # $NetBSD: Makefile,v 1.5 1999/07/23 09:44:38 mrg Exp $ LIB= usbhid @@ -10,6 +10,7 @@ MLINKS= usbhid.3 hid_dispose_report_desc.3 \ usbhid.3 hid_get_item.3 \ usbhid.3 hid_get_report_desc.3 \ usbhid.3 hid_init.3 \ + usbhid.3 hid_start.3 \ usbhid.3 hid_locate.3 \ usbhid.3 hid_parse_usage_in_page.3 \ usbhid.3 hid_parse_usage_page.3 \ diff --git a/lib/libusbhid/data.c b/lib/libusbhid/data.c index 371fd99dfee..dd9ad515ad0 100644 --- a/lib/libusbhid/data.c +++ b/lib/libusbhid/data.c @@ -1,4 +1,4 @@ -/* $OpenBSD: data.c,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $OpenBSD: data.c,v 1.3 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: data.c,v 1.1 2001/12/28 17:45:26 augustss Exp $ */ /* @@ -33,15 +33,9 @@ int hid_get_data(const void *p, const hid_item_t *h) { - const unsigned char *buf; - unsigned int hpos; - unsigned int hsize; - int data; - int i, end, offs; - - buf = p; - hpos = h->pos; /* bit position of data */ - hsize = h->report_size; /* bit length of data */ + const unsigned char *buf = p; + unsigned int hpos = h->pos, hsize = h->report_size; + int data, i, end, offs; if (hsize == 0) return (0); @@ -63,15 +57,10 @@ hid_get_data(const void *p, const hid_item_t *h) void hid_set_data(void *p, const hid_item_t *h, int data) { - unsigned char *buf; - unsigned int hpos; - unsigned int hsize; + unsigned char *buf = p; + unsigned int hpos = h->pos, hsize = h->report_size; int i, end, offs, mask; - buf = p; - hpos = h->pos; /* bit position of data */ - hsize = h->report_size; /* bit length of data */ - if (hsize != 32) { mask = (1 << hsize) - 1; data &= mask; @@ -87,5 +76,5 @@ hid_set_data(void *p, const hid_item_t *h, int data) for (i = 0; i <= end; i++) buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) | - ((data >> (i*8)) & 0xff); + ((data >> (i*8)) & 0xff); } diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c index 35095a406c6..847763606ed 100644 --- a/lib/libusbhid/descr.c +++ b/lib/libusbhid/descr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: descr.c,v 1.3 2002/05/10 00:09:17 nate Exp $ */ +/* $OpenBSD: descr.c,v 1.4 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: descr.c,v 1.2 2002/02/20 20:31:07 christos Exp $ */ /* @@ -58,10 +58,8 @@ hid_use_report_desc(unsigned char *data, unsigned int size) report_desc_t r; r = malloc(sizeof(*r) + size); - if (r == 0) { - errno = ENOMEM; + if (r == NULL) return (NULL); - } r->size = size; memcpy(r->data, data, size); return (r); diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c index 4bc72344a5a..015a092bddc 100644 --- a/lib/libusbhid/parse.c +++ b/lib/libusbhid/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $OpenBSD: parse.c,v 1.3 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: parse.c,v 1.2 2001/12/29 20:44:22 augustss Exp $ */ /* @@ -93,6 +93,8 @@ hid_start_parse(report_desc_t d, int kindset, int id) struct hid_data *s; s = malloc(sizeof *s); + if (s == NULL) + return (NULL); memset(s, 0, sizeof *s); s->start = s->p = d->data; s->end = d->data + d->size; @@ -142,17 +144,12 @@ hid_get_item(hid_data_t s, hid_item_t *h) static int hid_get_item_raw(hid_data_t s, hid_item_t *h) { - hid_item_t *c; + hid_item_t *c = &s->cur, *hi, nc; unsigned int bTag = 0, bType = 0, bSize; unsigned char *data; - int dval; - unsigned char *p; - hid_item_t *hi; - hid_item_t nc; - int i; hid_kind_t retkind; - - c = &s->cur; + unsigned char *p; + int dval, i; top: if (s->multimax) { @@ -169,7 +166,7 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h) *h = *c; /* * 'multimax' is only non-zero if the current - * item kind is input/output/feature + * item kind is input/output/feature */ h->pos = s->kindpos[c->kind]; s->kindpos[c->kind] += c->report_size; @@ -249,8 +246,7 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h) c->report_count = 1; if (s->minset) { for (i = c->usage_minimum; - i <= c->usage_maximum; - i++) { + i <= c->usage_maximum; i++) { s->usages[s->nusage] = i; if (s->nusage < MAXUSAGE-1) s->nusage++; @@ -338,15 +334,16 @@ hid_get_item_raw(hid_data_t s, hid_item_t *h) break; case 8: c->report_ID = dval; - s->kindpos[hid_input] = - s->kindpos[hid_output] = - s->kindpos[hid_feature] = 0; + s->kindpos[hid_input] = 0; + s->kindpos[hid_output] = 0; + s->kindpos[hid_feature] = 0; break; case 9: c->report_count = dval; break; case 10: /* Push */ hi = malloc(sizeof *hi); + /* XXX unchecked malloc */ *hi = s->cur; c->next = hi; break; @@ -425,7 +422,7 @@ hid_report_size(report_desc_t r, enum hid_kind k, int id) int hid_locate(report_desc_t desc, unsigned int u, enum hid_kind k, - hid_item_t *h, int id) + hid_item_t *h, int id) { hid_data_t d; diff --git a/lib/libusbhid/shlib_version b/lib/libusbhid/shlib_version index 1edea46de91..b52599a164f 100644 --- a/lib/libusbhid/shlib_version +++ b/lib/libusbhid/shlib_version @@ -1,2 +1,2 @@ -major=1 +major=2 minor=0 diff --git a/lib/libusbhid/usage.c b/lib/libusbhid/usage.c index 5d0b2ee8b6a..346f60aa9a1 100644 --- a/lib/libusbhid/usage.c +++ b/lib/libusbhid/usage.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usage.c,v 1.5 2003/12/20 18:33:41 matthieu Exp $ */ +/* $OpenBSD: usage.c,v 1.6 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: usage.c,v 1.1 2001/12/28 17:45:27 augustss Exp $ */ /* @@ -32,6 +32,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include "usbhid.h" @@ -60,7 +61,7 @@ dump_hid_table(void) printf("%d\t%s\n", pages[i].usage, pages[i].name); for (j = 0; j < pages[i].pagesize; j++) { printf("\t%d\t%s\n", pages[i].page_contents[j].usage, - pages[i].page_contents[j].name); + pages[i].page_contents[j].name); } } } @@ -69,18 +70,24 @@ dump_hid_table(void) void hid_init(const char *hidname) { - FILE *f; + if (hid_start(hidname) == -1) + errx(1, "hid_init: failed"); +} + +int +hid_start(const char *hidname) +{ char line[100], name[100], *p, *n; - int no; - int lineno; - struct usage_page *curpage = 0; + struct usage_page *curpage = NULL; + int lineno, no; + FILE *f; - if (hidname == 0) + if (hidname == NULL) hidname = _PATH_HIDTABLE; f = fopen(hidname, "r"); if (f == NULL) - err(1, "%s", hidname); + return -1; for (lineno = 1; ; lineno++) { if (fgets(line, sizeof line, f) == NULL) break; @@ -93,62 +100,102 @@ hid_init(const char *hidname) if (sscanf(line, " * %99[^\n]", name) == 1) no = -1; else if (sscanf(line, " 0x%x %99[^\n]", &no, name) != 2 && - sscanf(line, " %d %99[^\n]", &no, name) != 2) - errx(1, "file %s, line %d, syntax error", - hidname, lineno); + sscanf(line, " %d %99[^\n]", &no, name) != 2) { + warnx("file %s, line %d, syntax error", + hidname, lineno); + errno = EINVAL; + goto fail; + } for (p = name; *p; p++) if (isspace(*p) || *p == '.') *p = '_'; n = strdup(name); if (!n) - err(1, "strdup"); + goto fail; + if (isspace(line[0])) { - if (!curpage) - errx(1, "file %s, line %d, syntax error", - hidname, lineno); + if (!curpage) { + warnx("file %s, line %d, syntax error", + hidname, lineno); + free(n); + errno = EINVAL; + goto fail; + } if (curpage->pagesize >= curpage->pagesizemax) { - curpage->pagesizemax += 10; - curpage->page_contents = - realloc(curpage->page_contents, - curpage->pagesizemax * - sizeof (struct usage_in_page)); - if (!curpage->page_contents) - err(1, "realloc"); + void *new; + int len; + + len = curpage->pagesizemax + 10; + new = realloc(curpage->page_contents, + len * sizeof (struct usage_in_page)); + if (!curpage->page_contents) { + free(curpage->page_contents); + curpage->page_contents = NULL; + free(n); + goto fail; + } + curpage->pagesizemax = len; + curpage->page_contents = new; } curpage->page_contents[curpage->pagesize].name = n; curpage->page_contents[curpage->pagesize].usage = no; curpage->pagesize++; } else { if (npages >= npagesmax) { - if (pages == 0) { - npagesmax = 5; - pages = malloc(npagesmax * - sizeof (struct usage_page)); + int len; + void *new; + + if (pages == NULL) { + len = 5; + pages = calloc(len, + sizeof (struct usage_page)); } else { - npagesmax += 5; - pages = realloc(pages, - npagesmax * - sizeof (struct usage_page)); + len = npagesmax * 5; + new = realloc(pages, + len * sizeof (struct usage_page)); + if (!new) + goto fail; + pages = new; + bzero(pages + npagesmax, + npagesmax - npagesmax); } - if (!pages) - err(1, "alloc"); + if (!pages) { + free(n); + goto fail; + } + npagesmax = len; } curpage = &pages[npages++]; curpage->name = n; curpage->usage = no; curpage->pagesize = 0; curpage->pagesizemax = 10; - curpage->page_contents = - malloc(curpage->pagesizemax * - sizeof (struct usage_in_page)); + curpage->page_contents = malloc(curpage->pagesizemax * + sizeof (struct usage_in_page)); if (!curpage->page_contents) - err(1, "malloc"); + goto fail; } } fclose(f); #ifdef DEBUG dump_hid_table(); #endif + return 0; + +fail: + if (f) + fclose(f); + for (no = 0; no++; no < npages) { + if (pages[no].name) + free((char *)pages[no].name); + if (pages[no].page_contents) + free((char *)pages[no].page_contents); + } + free(pages); + pages = NULL; + npages = 0; + npagesmax = 0; + return -1; } const char * @@ -158,7 +205,7 @@ hid_usage_page(int i) int k; if (!pages) - errx(1, "no hid table"); + return NULL; for (k = 0; k < npages; k++) if (pages[k].usage == i) @@ -170,10 +217,9 @@ hid_usage_page(int i) const char * hid_usage_in_page(unsigned int u) { + int i = HID_USAGE(u), j, k, us; int page = HID_PAGE(u); - int i = HID_USAGE(u); static char b[100]; - int j, k, us; for (k = 0; k < npages; k++) if (pages[k].usage == page) @@ -183,7 +229,7 @@ hid_usage_in_page(unsigned int u) for (j = 0; j < pages[k].pagesize; j++) { us = pages[k].page_contents[j].usage; if (us == -1) { - snprintf(b, sizeof b, "%s %d", + snprintf(b, sizeof b, "%s %d", pages[k].page_contents[j].name, i); return b; } @@ -201,7 +247,7 @@ hid_parse_usage_page(const char *name) int k; if (!pages) - errx(1, "no hid table"); + return NULL; for (k = 0; k < npages; k++) if (strcmp(pages[k].name, name) == 0) @@ -214,8 +260,8 @@ int hid_parse_usage_in_page(const char *name) { const char *sep; - int k, j; unsigned int l; + int k, j; sep = strchr(name, ':'); if (sep == NULL) @@ -229,6 +275,7 @@ hid_parse_usage_in_page(const char *name) sep++; for (j = 0; j < pages[k].pagesize; j++) if (strcmp(pages[k].page_contents[j].name, sep) == 0) - return (pages[k].usage << 16) | pages[k].page_contents[j].usage; - return (-1); + return (pages[k].usage << 16) | + pages[k].page_contents[j].usage; + return -1; } diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3 index 49db00c8a4b..a152f3ce9e8 100644 --- a/lib/libusbhid/usbhid.3 +++ b/lib/libusbhid/usbhid.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: usbhid.3,v 1.6 2003/05/24 18:30:32 jmc Exp $ +.\" $OpenBSD: usbhid.3,v 1.7 2004/06/04 00:47:32 deraadt Exp $ .\" $NetBSD: usbhid.3,v 1.5 2002/02/07 07:00:52 ross Exp $ .\" .\" Copyright (c) 1999, 2001 Lennart Augustsson <augustss@netbsd.org> @@ -40,6 +40,7 @@ .Nm hid_locate , .Nm hid_usage_page , .Nm hid_usage_in_page , +.Nm hid_start , .Nm hid_init , .Nm hid_get_data , .Nm hid_set_data @@ -73,6 +74,8 @@ .Ft void .Fn hid_init "char *file" .Ft int +.Fn hid_start "char *file" +.Ft int .Fn hid_get_data "void *data" "hid_item_t *h" .Ft void .Fn hid_set_data "void *data" "hid_item_t *h" "u_int data" @@ -180,11 +183,14 @@ if it cannot be found. .Pp Before any of these functions can be called the usage table must be parsed, this is done by calling -.Fn hid_init +.Fn hid_start with the name of the table. Passing .Fa NULL to this function will cause it to use the default table. +A return value of -1 indicates that an error has occured, and +.Va errno +is set. .Ss DATA EXTRACTION FUNCTIONS Given the data obtained from a HID device and an item in the report descriptor the diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h index 7172ca5fac8..4b98482c6c0 100644 --- a/lib/libusbhid/usbhid.h +++ b/lib/libusbhid/usbhid.h @@ -1,4 +1,4 @@ -/* $OpenBSD: usbhid.h,v 1.2 2002/05/10 00:09:17 nate Exp $ */ +/* $OpenBSD: usbhid.h,v 1.3 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: usbhid.h,v 1.1 2001/12/28 17:45:27 augustss Exp $ */ /* @@ -78,24 +78,26 @@ typedef struct hid_item { #define HID_USAGE(u) ((u) & 0xffff) /* Obtaining a report descriptor, descr.c: */ -report_desc_t hid_get_report_desc(int file); -report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size); -void hid_dispose_report_desc(report_desc_t); +report_desc_t hid_get_report_desc(int file); +report_desc_t hid_use_report_desc(unsigned char *data, unsigned int size); +void hid_dispose_report_desc(report_desc_t); /* Parsing of a HID report descriptor, parse.c: */ -hid_data_t hid_start_parse(report_desc_t d, int kindset, int id); -void hid_end_parse(hid_data_t s); -int hid_get_item(hid_data_t s, hid_item_t *h); -int hid_report_size(report_desc_t d, enum hid_kind k, int id); -int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h, int id); +hid_data_t hid_start_parse(report_desc_t d, int kindset, int id); +void hid_end_parse(hid_data_t s); +int hid_get_item(hid_data_t s, hid_item_t *h); +int hid_report_size(report_desc_t d, enum hid_kind k, int id); +int hid_locate(report_desc_t d, unsigned int usage, enum hid_kind k, + hid_item_t *h, int id); /* Conversion to/from usage names, usage.c: */ -const char *hid_usage_page(int i); -const char *hid_usage_in_page(unsigned int u); -void hid_init(const char *file); -int hid_parse_usage_in_page(const char *name); -int hid_parse_usage_page(const char *name); +const char *hid_usage_page(int i); +const char *hid_usage_in_page(unsigned int u); +void hid_init(const char *file); +int hid_start(const char *file); +int hid_parse_usage_in_page(const char *name); +int hid_parse_usage_page(const char *name); /* Extracting/insertion of data, data.c: */ -int hid_get_data(const void *p, const hid_item_t *h); -void hid_set_data(void *p, const hid_item_t *h, int data); +int hid_get_data(const void *p, const hid_item_t *h); +void hid_set_data(void *p, const hid_item_t *h, int data); diff --git a/usr.bin/usbhidaction/usbhidaction.c b/usr.bin/usbhidaction/usbhidaction.c index 83c9433f9d2..e2ae2473396 100644 --- a/usr.bin/usbhidaction/usbhidaction.c +++ b/usr.bin/usbhidaction/usbhidaction.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usbhidaction.c,v 1.3 2004/04/03 21:01:25 jmc Exp $ */ +/* $OpenBSD: usbhidaction.c,v 1.4 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: usbhidaction.c,v 1.7 2002/01/18 14:38:59 augustss Exp $ */ /* @@ -127,11 +127,12 @@ main(int argc, char **argv) if (conf == NULL || dev == NULL) usage(); - hid_init(NULL); + if (hid_start(NULL) == -1) + errx(1, "hid_init"); if (dev[0] != '/') { snprintf(devnamebuf, sizeof(devnamebuf), "/dev/%s%s", - isdigit(dev[0]) ? "uhid" : "", dev); + isdigit(dev[0]) ? "uhid" : "", dev); dev = devnamebuf; } @@ -233,7 +234,6 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) struct hid_data *d; struct hid_item h; int u, lo, hi, range; - f = fopen(conf, "r"); if (f == NULL) @@ -256,12 +256,12 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) if (sscanf(buf, "%s %s %[^\n]", name, value, action) != 3) { if (isdemon) { syslog(LOG_WARNING, "config file `%s', line %d" - ", syntax error: %s", conf, line, buf); + ", syntax error: %s", conf, line, buf); freecommands(cmds); return (NULL); } else { errx(1, "config file `%s', line %d," - ", syntax error: %s", conf, line, buf); + ", syntax error: %s", conf, line, buf); } } @@ -279,22 +279,22 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) if (sscanf(value, "%d", &cmd->value) != 1) { if (isdemon) { syslog(LOG_WARNING, - "config file `%s', line %d, " - "bad value: %s\n", - conf, line, value); + "config file `%s', line %d, " + "bad value: %s\n", + conf, line, value); freecommands(cmds); return (NULL); } else { errx(1, "config file `%s', line %d, " - "bad value: %s\n", - conf, line, value); + "bad value: %s\n", + conf, line, value); } } } coll[0] = 0; for (d = hid_start_parse(repd, 1 << hid_input, reportid); - hid_get_item(d, &h); ) { + hid_get_item(d, &h); ) { if (verbose > 2) printf("kind=%d usage=%x\n", h.kind, h.usage); if (h.flags & HIO_CONST) @@ -313,7 +313,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) } for (u = lo; u <= hi; u++) { snprintf(usage, sizeof usage, "%s:%s", - hid_usage_page(HID_PAGE(u)), + hid_usage_page(HID_PAGE(u)), hid_usage_in_page(u)); if (verbose > 2) printf("usage %s\n", usage); @@ -322,11 +322,11 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) if (coll[0]) { snprintf(usage, sizeof usage, "%s.%s:%s", coll+1, - hid_usage_page(HID_PAGE(u)), + hid_usage_page(HID_PAGE(u)), hid_usage_in_page(u)); if (verbose > 2) printf("usage %s\n", - usage); + usage); if (!strcasecmp(usage, name)) goto foundhid; } @@ -335,7 +335,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) case hid_collection: snprintf(coll + strlen(coll), sizeof coll - strlen(coll), ".%s:%s", - hid_usage_page(HID_PAGE(h.usage)), + hid_usage_page(HID_PAGE(h.usage)), hid_usage_in_page(h.usage)); break; case hid_endcollection: @@ -353,12 +353,12 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) } if (isdemon) { syslog(LOG_WARNING, "config file `%s', line %d, HID " - "item not found: `%s'\n", conf, line, name); + "item not found: `%s'\n", conf, line, name); freecommands(cmds); return (NULL); } else { errx(1, "config file `%s', line %d, HID item " - "not found: `%s'\n", conf, line, name); + "not found: `%s'\n", conf, line, name); } foundhid: @@ -375,7 +375,7 @@ parse_conf(const char *conf, report_desc_t repd, int reportid, int ignore) if (verbose) printf("PARSE:%d %s, %d, '%s'\n", cmd->line, name, - cmd->value, cmd->action); + cmd->value, cmd->action); } fclose(f); return (cmds); diff --git a/usr.bin/usbhidctl/usbhid.c b/usr.bin/usbhidctl/usbhid.c index 99cc70bf3f4..de27a1bbd37 100644 --- a/usr.bin/usbhidctl/usbhid.c +++ b/usr.bin/usbhidctl/usbhid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usbhid.c,v 1.5 2004/04/03 21:01:25 jmc Exp $ */ +/* $OpenBSD: usbhid.c,v 1.6 2004/06/04 00:47:32 deraadt Exp $ */ /* $NetBSD: usbhid.c,v 1.22 2002/02/20 20:30:42 christos Exp $ */ /* @@ -932,7 +932,8 @@ main(int argc, char **argv) /* NOTREACHED */ } - hid_init(table); + if (hid_start(table) == -1) + errx(1, "hid_init"); if (dev[0] != '/') { snprintf(devnamebuf, sizeof(devnamebuf), "/dev/%s%s", |