int loaddevdesc(Dev *d) { uchar buf[Ddevlen+255]; int nr; int type; Ep *ep0; type = Rd2h|Rstd|Rdev; nr = sizeof(buf); memset(buf, 0, Ddevlen); if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0) return -1; /* * Several hubs are returning descriptors of 17 bytes, not 18. * We accept them and leave number of configurations as zero. * (a get configuration descriptor also fails for them!) */ if(nr < Ddevlen){ print("%s: %s: warning: device with short descriptor\n", argv0, d->dir); if(nr < Ddevlen-1){ werrstr("short device descriptor (%d bytes)", nr); return -1; } } d->usb = emallocz(sizeof(Usbdev), 1); ep0 = mkep(d->usb, 0); ep0->dir = Eboth; ep0->type = Econtrol; ep0->maxpkt = d->maxpkt = 8; /* a default */ nr = parsedev(d, buf, nr); if(nr >= 0){ d->usb->vendor = loaddevstr(d, d->usb->vsid); if(strcmp(d->usb->vendor, "none") != 0){ d->usb->product = loaddevstr(d, d->usb->psid); d->usb->serial = loaddevstr(d, d->usb->ssid); } } return nr; }
int _aucat_open(struct aucat *hdl, const char *str, unsigned int mode, unsigned int type) { extern char *__progname; int eof; char host[NI_MAXHOST], opt[AMSG_OPTMAX]; const char *p = str; unsigned int unit, devnum; if (*p == '@') { p = parsestr(++p, host, NI_MAXHOST); if (p == NULL) return 0; } else *host = '\0'; if (*p == ',') { p = parsedev(++p, &unit); if (p == NULL) return 0; } else unit = 0; if (*p != '/' && *p != ':') { DPRINTF("%s: '/' expected\n", str); return 0; } p = parsedev(++p, &devnum); if (p == NULL) return 0; if (*p == '.') { p = parsestr(++p, opt, AMSG_OPTMAX); if (p == NULL) return 0; } else strlcpy(opt, "default", AMSG_OPTMAX); if (*p != '\0') { DPRINTF("%s: junk at end of dev name\n", p); return 0; } devnum += type * 16; /* XXX */ DPRINTFN(2, "_aucat_open: host=%s unit=%u devnum=%u opt=%s\n", host, unit, devnum, opt); if (host[0] != '\0') { if (!aucat_connect_tcp(hdl, host, unit)) return 0; } else { if (!aucat_connect_un(hdl, unit)) return 0; } if (fcntl(hdl->fd, F_SETFD, FD_CLOEXEC) < 0) { DPERROR("FD_CLOEXEC"); goto bad_connect; } hdl->rstate = RSTATE_MSG; hdl->rtodo = sizeof(struct amsg); hdl->wstate = WSTATE_IDLE; hdl->wtodo = 0xdeadbeef; hdl->maxwrite = 0; /* * say hello to server */ AMSG_INIT(&hdl->wmsg); hdl->wmsg.cmd = htonl(AMSG_AUTH); if (!aucat_mkcookie(hdl->wmsg.u.auth.cookie)) goto bad_connect; hdl->wtodo = sizeof(struct amsg); if (!_aucat_wmsg(hdl, &eof)) goto bad_connect; AMSG_INIT(&hdl->wmsg); hdl->wmsg.cmd = htonl(AMSG_HELLO); hdl->wmsg.u.hello.version = AMSG_VERSION; hdl->wmsg.u.hello.mode = htons(mode); hdl->wmsg.u.hello.devnum = devnum; strlcpy(hdl->wmsg.u.hello.who, __progname, sizeof(hdl->wmsg.u.hello.who)); strlcpy(hdl->wmsg.u.hello.opt, opt, sizeof(hdl->wmsg.u.hello.opt)); hdl->wtodo = sizeof(struct amsg); if (!_aucat_wmsg(hdl, &eof)) goto bad_connect; hdl->rtodo = sizeof(struct amsg); if (!_aucat_rmsg(hdl, &eof)) { DPRINTF("aucat_init: mode refused\n"); goto bad_connect; } if (ntohl(hdl->rmsg.cmd) != AMSG_ACK) { DPRINTF("aucat_init: protocol err\n"); goto bad_connect; } return 1; bad_connect: while (close(hdl->fd) < 0 && errno == EINTR) ; /* retry */ return 0; }