summaryrefslogtreecommitdiff
path: root/lib/libusbhid
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libusbhid')
-rw-r--r--lib/libusbhid/Makefile3
-rw-r--r--lib/libusbhid/data.c25
-rw-r--r--lib/libusbhid/descr.c6
-rw-r--r--lib/libusbhid/parse.c29
-rw-r--r--lib/libusbhid/shlib_version2
-rw-r--r--lib/libusbhid/usage.c135
-rw-r--r--lib/libusbhid/usbhid.310
-rw-r--r--lib/libusbhid/usbhid.h34
8 files changed, 142 insertions, 102 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);