M alphapc/screen.h => alphapc/screen.h +1 -1
@@ 122,7 122,7 @@ enum {
};
/* mouse.c */
-extern void mousectl(char*[], int);
+extern void mousectl(Cmdbuf*);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
M ip/arp.c => ip/arp.c +55 -38
@@ 27,6 27,12 @@ char *arpstate[] =
"WAIT",
};
+enum
+{
+ CMadd,
+ CMflush,
+};
+
/*
* one per Fs
*/
@@ 38,6 44,13 @@ struct Arp
Arpent cache[NCACHE];
};
+static
+Cmdtab arpcmd[] =
+{
+ CMadd, "add", 0,
+ CMflush, "flush", 1,
+};
+
char *Ebadarp = "bad arp";
#define haship(s) ((s)[IPaddrlen-1]%NHASH)
@@ 256,56 269,40 @@ arpwrite(Fs *fs, char *s, int len)
Arp *arp;
Block *bp;
Arpent *a;
+ Cmdbuf *cb;
+ Cmdtab *ct;
Medium *m;
- char *f[4], buf[256];
uchar ip[IPaddrlen], mac[MAClen];
arp = fs->arp;
- if(len == 0)
- error(Ebadarp);
- if(len >= sizeof(buf))
- len = sizeof(buf)-1;
- strncpy(buf, s, len);
- buf[len] = 0;
- if(len > 0 && buf[len-1] == '\n')
- buf[len-1] = 0;
-
- n = tokenize(buf, f, 4);
- if(strcmp(f[0], "flush") == 0){
- qlock(arp);
- for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
- memset(a->ip, 0, sizeof(a->ip));
- memset(a->mac, 0, sizeof(a->mac));
- a->hash = nil;
- a->state = 0;
- a->used = 0;
- while(a->hold != nil) {
- bp = a->hold->list;
- freeblist(a->hold);
- a->hold = bp;
- }
- }
- memset(arp->hash, 0, sizeof(arp->hash));
- qunlock(arp);
- } else if(strcmp(f[0], "add") == 0) {
- switch(n) {
+ cb = parsecmd(s, len);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
+
+ ct = lookupcmd(cb, arpcmd, nelem(arpcmd));
+
+ switch(ct->index){
+ case CMadd:
+ switch(cb->nf) {
default:
- error(Ebadarg);
+ cmderror(cb, Ecmdargs);
case 3:
- parseip(ip, f[1]);
+ parseip(ip, cb->f[1]);
r = v4lookup(fs, ip+IPv4off);
if(r == nil)
- error("Destination unreachable");
+ error("destination unreachable");
m = r->ifc->m;
- n = parsemac(mac, f[2], m->maclen);
+ n = parsemac(mac, cb->f[2], m->maclen);
break;
case 4:
- m = ipfindmedium(f[1]);
+ m = ipfindmedium(cb->f[1]);
if(m == nil)
error(Ebadarp);
- parseip(ip, f[2]);
- n = parsemac(mac, f[3], m->maclen);
+ parseip(ip, cb->f[2]);
+ n = parsemac(mac, cb->f[3], m->maclen);
break;
}
@@ 313,9 310,29 @@ arpwrite(Fs *fs, char *s, int len)
error(Ebadarp);
m->ares(fs, V6, ip, mac, n, 0);
- } else
- error(Ebadarp);
+ break;
+
+ case CMflush:
+ qlock(arp);
+ for(a = arp->cache; a < &arp->cache[NCACHE]; a++){
+ memset(a->ip, 0, sizeof(a->ip));
+ memset(a->mac, 0, sizeof(a->mac));
+ a->hash = nil;
+ a->state = 0;
+ a->used = 0;
+ while(a->hold != nil) {
+ bp = a->hold->list;
+ freeblist(a->hold);
+ a->hold = bp;
+ }
+ }
+ memset(arp->hash, 0, sizeof(arp->hash));
+ qunlock(arp);
+ break;
+ }
+ poperror();
+ free(cb);
return len;
}
M ip/devip.c => ip/devip.c +50 -15
@@ 54,6 54,30 @@ QLock fslock;
Fs *ipfs[Nfs]; /* attached fs's */
Queue *qlog;
+enum
+{
+ CMaddmulti,
+ CMannounce,
+ CMbind,
+ CMconnect,
+ CMremmulti,
+ CMtos,
+ CMttl,
+ CMwildcard,
+};
+
+Cmdtab ipctlmsg[] =
+{
+ CMaddmulti, "addmulti", 0,
+ CMannounce, "announce", 0,
+ CMbind, "bind", 0,
+ CMconnect, "connect", 0,
+ CMremmulti, "remmulti", 0,
+ CMtos, "tos", 0,
+ CMttl, "ttl", 0,
+ CMwildcard, "*", 0,
+};
+
extern void nullmediumlink(void);
extern void pktmediumlink(void);
long ndbwrite(Fs *f, char *a, ulong off, int n);
@@ 1023,6 1047,7 @@ ipwrite(Chan* ch, void *v, long n, vlong off)
Proto *x;
char *p;
Cmdbuf *cb;
+ Cmdtab *ct;
uchar ia[IPaddrlen], ma[IPaddrlen];
Fs *f;
char *a;
@@ 1049,9 1074,7 @@ ipwrite(Chan* ch, void *v, long n, vlong off)
case Qiproute:
return routewrite(f, ch, a, n);
case Qlog:
- p = netlogctl(f, a, n);
- if(p != nil)
- error(p);
+ netlogctl(f, a, n);
return n;
case Qndb:
return ndbwrite(f, a, offset, n);
@@ 1069,19 1092,27 @@ ipwrite(Chan* ch, void *v, long n, vlong off)
}
if(cb->nf < 1)
error("short control request");
- if(strcmp(cb->f[0], "connect") == 0)
+
+ ct = lookupcmd(cb, ipctlmsg, nelem(ipctlmsg));
+ switch(ct->index){
+ case CMconnect:
connectctlmsg(x, c, cb);
- else if(strcmp(cb->f[0], "announce") == 0)
+ break;
+ case CMannounce:
announcectlmsg(x, c, cb);
- else if(strcmp(cb->f[0], "bind") == 0)
+ break;
+ case CMbind:
bindctlmsg(x, c, cb);
- else if(strcmp(cb->f[0], "ttl") == 0)
+ break;
+ case CMttl:
ttlctlmsg(c, cb);
- else if(strcmp(cb->f[0], "tos") == 0)
+ break;
+ case CMtos:
tosctlmsg(c, cb);
- else if(strcmp(cb->f[0], "addmulti") == 0){
- if(cb->nf < 2)
- error("addmulti needs interface address");
+ break;
+ case CMaddmulti:
+ if(cb->nf != 2 && cb->nf != 3)
+ cmderror(cb, Ecmdargs);
if(cb->nf == 2){
if(!ipismulticast(c->raddr))
error("addmulti for a non multicast address");
@@ 1094,19 1125,23 @@ ipwrite(Chan* ch, void *v, long n, vlong off)
parseip(ia, cb->f[1]);
ipifcaddmulti(c, ma, ia);
}
- } else if(strcmp(cb->f[0], "remmulti") == 0){
+ break;
+ case CMremmulti:
if(cb->nf < 2)
error("remmulti needs interface address");
if(!ipismulticast(c->raddr))
error("remmulti for a non multicast address");
parseip(ia, cb->f[1]);
ipifcremmulti(c, c->raddr, ia);
- } else if(x->ctl != nil) {
+ break;
+ case CMwildcard:
+ if(x->ctl == nil)
+ cmderror(cb, "unknown control request");
p = x->ctl(c, cb->f, cb->nf);
if(p != nil)
error(p);
- } else
- error("unknown control request");
+ }
+
qunlock(c);
free(cb);
poperror();
M ip/ip.h => ip/ip.h +1 -1
@@ 336,7 336,7 @@ enum
void netloginit(Fs*);
void netlogopen(Fs*);
void netlogclose(Fs*);
-char* netlogctl(Fs*, char*, int);
+void netlogctl(Fs*, char*, int);
long netlogread(Fs*, void*, ulong, long);
void netlog(Fs*, int, char*, ...);
void ifcloginit(Fs*);
M ip/iproute.c => ip/iproute.c +41 -22
@@ 16,6 16,22 @@ Route* v4freelist;
Route* v6freelist;
RWlock routelock;
+enum
+{
+ RWadd,
+ RWflush,
+ RWremove,
+ RWtag,
+};
+
+static
+Cmdtab routecmd[] = {
+ RWadd, "add", 4,
+ RWflush, "flush", 2,
+ RWremove, "remove", 3,
+ RWtag, "tag", 2,
+};
+
static void
freeroute(Route *r)
{
@@ 763,6 779,7 @@ routewrite(Fs *f, Chan *c, char *p, int n)
int h, changed;
char *tag;
Cmdbuf *cb;
+ Cmdtab *ct;
uchar addr[IPaddrlen];
uchar mask[IPaddrlen];
uchar gate[IPaddrlen];
@@ 774,7 791,25 @@ routewrite(Fs *f, Chan *c, char *p, int n)
nexterror();
}
- if(strcmp(cb->f[0], "flush") == 0){
+ ct = lookupcmd(cb, routecmd, nelem(routecmd));
+
+ switch(ct->index){
+ case RWadd:
+ parseip(addr, cb->f[1]);
+ parseipmask(mask, cb->f[2]);
+ parseip(gate, cb->f[3]);
+ tag = "none";
+ if(c != nil){
+ a = c->aux;
+ tag = a->tag;
+ }
+ if(memcmp(addr, v4prefix, IPv4off) == 0)
+ v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
+ else
+ v6addroute(f, tag, addr, mask, gate, 0);
+ break;
+
+ case RWflush:
tag = cb->f[1];
for(h = 0; h < nelem(f->v4root); h++)
for(changed = 1; changed;){
@@ 788,34 823,18 @@ routewrite(Fs *f, Chan *c, char *p, int n)
changed = routeflush(f, f->v6root[h], tag);
wunlock(&routelock);
}
- } else if(strcmp(cb->f[0], "remove") == 0){
- if(cb->nf < 3)
- error(Ebadarg);
+ break;
+
+ case RWremove:
parseip(addr, cb->f[1]);
parseipmask(mask, cb->f[2]);
if(memcmp(addr, v4prefix, IPv4off) == 0)
v4delroute(f, addr+IPv4off, mask+IPv4off, 1);
else
v6delroute(f, addr, mask, 1);
- } else if(strcmp(cb->f[0], "add") == 0){
- if(cb->nf < 4)
- error(Ebadarg);
- parseip(addr, cb->f[1]);
- parseipmask(mask, cb->f[2]);
- parseip(gate, cb->f[3]);
- tag = "none";
- if(c != nil){
- a = c->aux;
- tag = a->tag;
- }
- if(memcmp(addr, v4prefix, IPv4off) == 0)
- v4addroute(f, tag, addr+IPv4off, mask+IPv4off, gate+IPv4off, 0);
- else
- v6addroute(f, tag, addr, mask, gate, 0);
- } else if(strcmp(cb->f[0], "tag") == 0) {
- if(cb->nf < 2)
- error(Ebadarg);
+ break;
+ case RWtag:
a = c->aux;
na = newipaux(a->owner, cb->f[1]);
c->aux = na;
M ip/netlog.c => ip/netlog.c +47 -28
@@ 53,7 53,21 @@ static Netlogflag flags[] =
{ nil, 0, },
};
-static char Ebadnetctl[] = "unknown netlog ctl message";
+char Ebadnetctl[] = "too few arguments for netlog control message";
+
+enum
+{
+ CMset,
+ CMclear,
+ CMonly,
+};
+
+static
+Cmdtab routecmd[] = {
+ CMset, "set", 0,
+ CMclear, "clear", 0,
+ CMonly, "only", 0,
+};
void
netloginit(Fs *f)
@@ 150,48 164,52 @@ netlogread(Fs *f, void *a, ulong, long n)
return n;
}
-char*
-netlogctl(Fs *f, char* s, int len)
+void
+netlogctl(Fs *f, char* s, int n)
{
- int i, n, set;
+ int i, set;
Netlogflag *fp;
- char *fields[10], *p, buf[256];
+ Cmdbuf *cb;
+ Cmdtab *ct;
- if(len == 0)
- return Ebadnetctl;
+ cb = parsecmd(s, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
+
+ if(cb->nf < 2)
+ error(Ebadnetctl);
- if(len >= sizeof(buf))
- len = sizeof(buf)-1;
- strncpy(buf, s, len);
- buf[len] = 0;
- if(len > 0 && buf[len-1] == '\n')
- buf[len-1] = 0;
+ ct = lookupcmd(cb, routecmd, nelem(routecmd));
- n = tokenize(buf, fields, 10);
- if(n < 2)
- return Ebadnetctl;
+ SET(set);
- if(strcmp("set", fields[0]) == 0)
+ switch(ct->index){
+ case CMset:
set = 1;
- else if(strcmp("clear", fields[0]) == 0)
+ break;
+
+ case CMclear:
set = 0;
- else if(strcmp("only", fields[0]) == 0){
- parseip(f->alog->iponly, fields[1]);
+ break;
+
+ case CMonly:
+ parseip(f->alog->iponly, cb->f[1]);
if(ipcmp(f->alog->iponly, IPnoaddr) == 0)
f->alog->iponlyset = 0;
else
f->alog->iponlyset = 1;
- return nil;
- } else
- return Ebadnetctl;
+ free(cb);
+ return;
- p = strchr(fields[n-1], '\n');
- if(p)
- *p = 0;
+ default:
+ cmderror(cb, "unknown ip control message");
+ }
for(i = 1; i < n; i++){
for(fp = flags; fp->name; fp++)
- if(strcmp(fp->name, fields[i]) == 0)
+ if(strcmp(fp->name, cb->f[i]) == 0)
break;
if(fp->name == nil)
continue;
@@ 201,7 219,8 @@ netlogctl(Fs *f, char* s, int len)
f->alog->logmask &= ~fp->mask;
}
- return nil;
+ free(cb);
+ poperror();
}
void
M pc/devfloppy.c => pc/devfloppy.c +45 -19
@@ 92,7 92,7 @@ FController fl;
* predeclared
*/
static int cmddone(void*);
-static void floppyformat(FDrive*, char*);
+static void floppyformat(FDrive*, Cmdbuf*);
static void floppykproc(void*);
static void floppypos(FDrive*,long);
static int floppyrecal(FDrive*);
@@ 116,6 116,22 @@ Dirtab floppydir[]={
};
#define NFDIR 2 /* directory entries/drive */
+enum
+{
+ CMdebug,
+ CMeject,
+ CMformat,
+ CMreset,
+};
+
+static Cmdtab floppyctlmsg[] =
+{
+ CMdebug, "debug", 1,
+ CMeject, "eject", 1,
+ CMformat, "format", 0,
+ CMreset, "reset", 1,
+};
+
static void
fldump(void)
{
@@ 396,14 412,14 @@ floppyread(Chan *c, void *a, long n, vlong off)
return rv;
}
-#define SNCMP(a, b) strncmp(a, b, sizeof(b)-1)
static long
floppywrite(Chan *c, void *a, long n, vlong off)
{
FDrive *dp;
long rv, i;
char *aa = a;
- char ctlmsg[64];
+ Cmdbuf *cb;
+ Cmdtab *ct;
ulong offset = off;
rv = 0;
@@ 433,28 449,36 @@ floppywrite(Chan *c, void *a, long n, vlong off)
break;
case Qctl:
rv = n;
+ cb = parsecmd(a, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
qlock(&fl);
if(waserror()){
qunlock(&fl);
nexterror();
}
- if(n >= sizeof(ctlmsg))
- n = sizeof(ctlmsg) - 1;
- memmove(ctlmsg, aa, n);
- ctlmsg[n] = 0;
- if(SNCMP(ctlmsg, "eject") == 0){
+ ct = lookupcmd(cb, floppyctlmsg, nelem(floppyctlmsg));
+ switch(ct->index){
+ case CMeject:
floppyeject(dp);
- } else if(SNCMP(ctlmsg, "reset") == 0){
+ break;
+ case CMformat:
+ floppyformat(dp, cb);
+ break;
+ case CMreset:
fl.confused = 1;
floppyon(dp);
- } else if(SNCMP(ctlmsg, "format") == 0){
- floppyformat(dp, ctlmsg);
- } else if(SNCMP(ctlmsg, "debug") == 0){
+ break;
+ case CMdebug:
floppydebug = 1;
- } else
- error(Ebadctl);
+ break;
+ }
poperror();
qunlock(&fl);
+ poperror();
+ free(cb);
break;
default:
panic("floppywrite: bad qid");
@@ 893,20 917,19 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
* format a track
*/
static void
-floppyformat(FDrive *dp, char *params)
+floppyformat(FDrive *dp, Cmdbuf *cb)
{
int cyl, h, sec;
ulong track;
uchar *buf, *bp;
FType *t;
- char *f[3];
/*
* set the type
*/
- if(tokenize(params, f, 3) > 1){
+ if(cb->nf == 2){
for(t = floppytype; t < &floppytype[nelem(floppytype)]; t++){
- if(strcmp(f[1], t->name)==0 && t->dt==dp->dt){
+ if(strcmp(cb->f[1], t->name)==0 && t->dt==dp->dt){
dp->t = t;
floppydir[1+NFDIR*dp->dev].length = dp->t->cap;
break;
@@ 914,9 937,12 @@ floppyformat(FDrive *dp, char *params)
}
if(t >= &floppytype[nelem(floppytype)])
error(Ebadarg);
- } else {
+ } else if(cb->nf == 1){
floppysetdef(dp);
t = dp->t;
+ } else {
+ cmderror(cb, "invalid floppy format command");
+ SET(t);
}
/*
M pc/devpccard.c => pc/devpccard.c +36 -24
@@ 241,6 241,18 @@ static ulong mantissa[16] = {
static char Enocard[] = "No card in slot";
+enum
+{
+ CMdown,
+ CMpower,
+};
+
+static Cmdtab pccardctlmsg[] =
+{
+ CMdown, "down", 2,
+ CMpower, "power", 1,
+};
+
static void cbint(Ureg *, void *);
static int powerup(Cardbus *);
static void configure(Cardbus *);
@@ 1314,37 1326,37 @@ pccardwrite(Chan *c, void *v, long n, vlong)
{
Rune r;
ulong n0;
- int i, nf;
- char buf[255], *field[Ncmd], *device;
+ char *device;
+ Cmdbuf *cbf;
+ Cmdtab *ct;
Cardbus *cb;
n0 = n;
switch(TYPE(c)){
case Qctl:
cb = &cbslots[SLOTNO(c)];
- if(n > sizeof(buf)-1) n = sizeof(buf)-1;
- memmove(buf, v, n);
- buf[n] = '\0';
-
- nf = tokenize(buf, field, Ncmd);
- for (i = 0; i != nf; i++) {
- if (!strcmp(field[i], "down")) {
-
- if (i + 1 < nf && *field[i + 1] == '#') {
- device = field[++i];
- device += chartorune(&r, device);
- if ((n = devno(r, 1)) >= 0 && devtab[n]->config)
- devtab[n]->config(0, device, nil);
- }
- qengine(cb, CardEjected);
- }
- else if (!strcmp(field[i], "power")) {
- if ((cb->cb_regs[SocketState] & SS_CCD) == 0)
- qengine(cb, CardDetected);
- }
- else
- error(Ebadarg);
+
+ cbf = parsecmd(v, n);
+ if(waserror()){
+ free(cbf);
+ nexterror();
+ }
+ ct = lookupcmd(cbf, pccardctlmsg, nelem(pccardctlmsg));
+ switch(ct->index){
+ case CMdown:
+ device = cbf->f[1];
+ device += chartorune(&r, device);
+ if ((n = devno(r, 1)) >= 0 && devtab[n]->config)
+ devtab[n]->config(0, device, nil);
+ qengine(cb, CardEjected);
+ break;
+ case CMpower:
+ if ((cb->cb_regs[SocketState] & SS_CCD) == 0)
+ qengine(cb, CardDetected);
+ break;
}
+ poperror();
+ free(cbf);
break;
}
return n0 - n;
M pc/devusb.c => pc/devusb.c +114 -61
@@ 279,6 279,7 @@ struct Ctlr {
static Ctlr ubus;
static char Estalled[] = "usb endpoint stalled";
+static char Ebadusbmsg[] = "invalid parameters to USB ctl message";
static QLock usbstate; /* protects name space state */
static Udev* usbdev[32];
@@ 287,6 288,42 @@ static struct {
Endpt* f;
} activends;
+enum
+{
+ BCMdisable,
+ BCMenable,
+ BCMreset,
+};
+
+enum
+{
+ CMclass,
+ CMdata,
+ CMdebug,
+ CMep,
+ CMmaxpkt,
+ CMspeed,
+ CMunstall,
+};
+
+static Cmdtab usbbusctlmsg[] =
+{
+ BCMdisable, "disable", 2,
+ BCMenable, "enable", 2,
+ BCMreset, "reset", 2,
+};
+
+static Cmdtab usbctlmsg[] =
+{
+ CMclass, "class", 4,
+ CMdata, "data", 3,
+ CMdebug, "debug", 3,
+ CMep, "ep", 6,
+ CMmaxpkt, "maxpkt", 3,
+ CMspeed, "speed", 2,
+ CMunstall, "unstall", 2,
+};
+
static long readusb(Endpt*, void*, long);
static long writeusb(Endpt*, void*, long, int);
@@ 2003,93 2040,109 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
{
Udev *d;
Endpt *e;
- int id, nw, nf, t, i;
+ Cmdbuf *cb;
+ Cmdtab *ct;
+ int id, nw, t, i;
char cmd[50], *fields[10];
if(c->qid.type == QTDIR)
error(Egreg);
t = QID(c->qid);
if(t == Qbusctl){
- if(n >= sizeof(cmd)-1)
- n = sizeof(cmd)-1;
- memmove(cmd, a, n);
- cmd[n] = 0;
- nf = tokenize(cmd, fields, nelem(fields));
- if(nf < 2)
- error(Ebadarg);
+ cb = parsecmd(a, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
+
+ ct = lookupcmd(cb, usbbusctlmsg, nelem(usbbusctlmsg));
id = strtol(fields[1], nil, 0);
if(id != 1 && id != 2)
- error(Ebadarg); /* there are two ports on the root hub */
- if(strcmp(fields[0], "reset") == 0)
- portreset(id);
- else if(strcmp(fields[0], "enable") == 0)
- portenable(id, 1);
- else if(strcmp(fields[0], "disable") == 0)
+ cmderror(cb, "usb port number not 1 or 2 in");
+ switch(ct->index){
+ case BCMdisable:
portenable(id, 0);
- else
- error(Ebadarg);
+ break;
+ case BCMenable:
+ portenable(id, 1);
+ break;
+ case BCMreset:
+ portreset(id);
+ break;
+ }
+
+ poperror();
+ free(cb);
return n;
}
d = usbdevice(c);
t = QID(c->qid);
switch(t){
case Qctl:
- if(n >= sizeof(cmd)-1)
- n = sizeof(cmd)-1;
- memmove(cmd, a, n);
- cmd[n] = 0;
- nf = tokenize(cmd, fields, nelem(fields));
- if(nf > 1 && strcmp(fields[0], "speed") == 0){
- d->ls = strtoul(fields[1], nil, 0) == 0;
- } else if(nf > 3 && strcmp(fields[0], "class") == 0){
- i = strtoul(fields[2], nil, 0);
- d->npt = strtoul(fields[1], nil, 0);
+ cb = parsecmd(a, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
+
+ ct = lookupcmd(cb, usbctlmsg, nelem(usbctlmsg));
+ switch(ct->index){
+ case CMspeed:
+ d->ls = strtoul(cb->f[1], nil, 0) == 0;
+ break;
+ case CMclass:
+ i = strtoul(cb->f[2], nil, 0);
+ d->npt = strtoul(cb->f[1], nil, 0);
/* class config# csp ( == class subclass proto) */
if (i < 0 || i >= nelem(d->ep)
|| d->npt > nelem(d->ep) || i >= d->npt)
- error(Ebadarg);
- if (i == 0) {
- d->csp = strtoul(fields[3], nil, 0);
- }
+ cmderror(cb, Ebadusbmsg);
+ if (i == 0)
+ d->csp = strtoul(cb->f[3], nil, 0);
if(d->ep[i] == nil)
d->ep[i] = devendpt(d, i, 1);
- d->ep[i]->csp = strtoul(fields[3], nil, 0);
- }else if(nf > 2 && strcmp(fields[0], "data") == 0){
- i = strtoul(fields[1], nil, 0);
+ d->ep[i]->csp = strtoul(cb->f[3], nil, 0);
+ break;
+ case CMdata:
+ i = strtoul(cb->f[1], nil, 0);
if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadarg);
+ error(Ebadusbmsg);
e = d->ep[i];
- e->data01 = strtoul(fields[2], nil, 0) != 0;
- }else if(nf > 2 && strcmp(fields[0], "maxpkt") == 0){
- i = strtoul(fields[1], nil, 0);
+ e->data01 = strtoul(cb->f[2], nil, 0) != 0;
+ break;
+ case CMmaxpkt:
+ i = strtoul(cb->f[1], nil, 0);
if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadarg);
+ error(Ebadusbmsg);
e = d->ep[i];
- e->maxpkt = strtoul(fields[2], nil, 0);
+ e->maxpkt = strtoul(cb->f[2], nil, 0);
if(e->maxpkt > 1500)
e->maxpkt = 1500;
- }else if(nf > 2 && strcmp(fields[0], "debug") == 0){
- i = strtoul(fields[1], nil, 0);
+ break;
+ case CMdebug:
+ i = strtoul(cb->f[1], nil, 0);
if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadarg);
+ error(Ebadusbmsg);
if (i == -1)
debug = 0;
else {
debug = 1;
e = d->ep[i];
- e->debug = strtoul(fields[2], nil, 0);
+ e->debug = strtoul(cb->f[2], nil, 0);
}
- }else if(nf > 1 && strcmp(fields[0], "unstall") == 0){
- i = strtoul(fields[1], nil, 0);
+ break;
+ case CMunstall:
+ i = strtoul(cb->f[1], nil, 0);
if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil)
- error(Ebadarg);
+ error(Ebadusbmsg);
e = d->ep[i];
e->err = nil;
- }else if(nf == 6 && strcmp(fields[0], "ep") == 0){
+ break;
+ case CMep:
/* ep n `bulk' mode maxpkt nbuf OR
* ep n period mode samplesize KHz
*/
- i = strtoul(fields[1], nil, 0);
+ i = strtoul(cb->f[1], nil, 0);
if(i < 0 || i >= nelem(d->ep)) {
XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep));
error(Ebadarg);
@@ 2104,7 2157,7 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
}
if (e->active)
error(Eperm);
- if(strcmp(fields[2], "bulk") == 0){
+ if(strcmp(cb->f[2], "bulk") == 0){
Ctlr *ub;
e->iso = 0;
@@ 2119,34 2172,34 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
panic("usbwrite: allocqh");
}
queueqh(e->epq);
- e->mode = strcmp(fields[3],"r") == 0? OREAD :
- strcmp(fields[3],"w") == 0? OWRITE : ORDWR;
- i = strtoul(fields[4], nil, 0);
+ e->mode = strcmp(cb->f[3],"r") == 0? OREAD :
+ strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR;
+ i = strtoul(cb->f[4], nil, 0);
if(i < 8 || i > 1023)
i = 8;
e->maxpkt = i;
- i = strtoul(fields[5], nil, 0);
+ i = strtoul(cb->f[5], nil, 0);
if(i >= 1 && i <= 32)
e->nbuf = i;
} else {
/* ep n period mode samplesize KHz */
- i = strtoul(fields[2], nil, 0);
+ i = strtoul(cb->f[2], nil, 0);
if(i > 0 && i <= 1000){
e->pollms = i;
}else {
XPRINT("field 4: 0 <= %d <= 1000\n", i);
error(Ebadarg);
}
- e->mode = strcmp(fields[3],"r") == 0? OREAD :
- strcmp(fields[3],"w") == 0? OWRITE : ORDWR;
- i = strtoul(fields[4], nil, 0);
+ e->mode = strcmp(cb->f[3],"r") == 0? OREAD :
+ strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR;
+ i = strtoul(cb->f[4], nil, 0);
if(i >= 1 && i <= 8){
e->samplesz = i;
}else {
XPRINT("field 4: 0 < %d <= 8\n", i);
error(Ebadarg);
}
- i = strtoul(fields[5], nil, 0);
+ i = strtoul(cb->f[5], nil, 0);
if(i >= 1 && i <= 100000){
/* Hz */
e->hz = i;
@@ 2161,10 2214,10 @@ usbwrite(Chan *c, void *a, long n, vlong offset)
}
poperror();
qunlock(&usbstate);
- }else {
- XPRINT("command %s, fields %d\n", fields[0], nf);
- error(Ebadarg);
}
+
+ poperror();
+ free(cb);
return n;
case Qsetup: /* SETUP endpoint 0 */
M pc/devvga.c => pc/devvga.c +90 -87
@@ 28,6 28,36 @@ static Dirtab vgadir[] = {
"vgaovlctl", { Qvgaovlctl, 0 }, 0, 0660,
};
+enum {
+ CMactualsize,
+ CMblank,
+ CMblanktime,
+ CMdrawinit,
+ CMhwaccel,
+ CMhwblank,
+ CMhwgc,
+ CMlinear,
+ CMpalettedepth,
+ CMpanning,
+ CMsize,
+ CMtype,
+};
+
+static Cmdtab vgactlmsg[] = {
+ CMactualsize, "actualsize", 2,
+ CMblank, "blank", 1,
+ CMblanktime, "blanktime", 2,
+ CMdrawinit, "drawinit", 1,
+ CMhwaccel, "hwaccel", 2,
+ CMhwblank, "hwblank", 2,
+ CMhwgc, "hwgc", 2,
+ CMlinear, "linear", 0,
+ CMpalettedepth, "palettedepth", 2,
+ CMpanning, "panning", 2,
+ CMsize, "size", 3,
+ CMtype, "type", 2,
+};
+
static void
vgareset(void)
{
@@ 175,25 205,21 @@ vgaread(Chan* c, void* a, long n, vlong off)
static char Ebusy[] = "vga already configured";
static void
-vgactl(char* a)
+vgactl(Cmdbuf *cb)
{
- int align, i, n, size, x, y, z;
- char *chanstr, *field[6], *p;
+ int align, i, size, x, y, z;
+ char *chanstr, *p;
ulong chan;
+ Cmdtab *ct;
VGAscr *scr;
extern VGAdev *vgadev[];
extern VGAcur *vgacur[];
- n = tokenize(a, field, nelem(field));
- if(n < 1)
- error(Ebadarg);
-
scr = &vgascreen[0];
- if(strcmp(field[0], "hwgc") == 0){
- if(n < 2)
- error(Ebadarg);
-
- if(strcmp(field[1], "off") == 0){
+ ct = lookupcmd(cb, vgactlmsg, nelem(vgactlmsg));
+ switch(ct->index){
+ case CMhwgc:
+ if(strcmp(cb->f[1], "off") == 0){
lock(&cursor);
if(scr->cur){
if(scr->cur->disable)
@@ 205,7 231,7 @@ vgactl(char* a)
}
for(i = 0; vgacur[i]; i++){
- if(strcmp(field[1], vgacur[i]->name))
+ if(strcmp(cb->f[1], vgacur[i]->name))
continue;
lock(&cursor);
if(scr->cur && scr->cur->disable)
@@ 216,13 242,11 @@ vgactl(char* a)
unlock(&cursor);
return;
}
- }
- else if(strcmp(field[0], "type") == 0){
- if(n < 2)
- error(Ebadarg);
+ break;
+ case CMtype:
for(i = 0; vgadev[i]; i++){
- if(strcmp(field[1], vgadev[i]->name))
+ if(strcmp(cb->f[1], vgadev[i]->name))
continue;
if(scr->dev && scr->dev->disable)
scr->dev->disable(scr);
@@ 231,14 255,13 @@ vgactl(char* a)
scr->dev->enable(scr);
return;
}
- }
- else if(strcmp(field[0], "size") == 0){
- if(n < 3)
- error(Ebadarg);
+ break;
+
+ case CMsize:
if(drawhasclients())
error(Ebusy);
- x = strtoul(field[1], &p, 0);
+ x = strtoul(cb->f[1], &p, 0);
if(x == 0 || x > 2048)
error(Ebadarg);
if(*p)
@@ 252,7 275,7 @@ vgactl(char* a)
z = strtoul(p, &p, 0);
- chanstr = field[2];
+ chanstr = cb->f[2];
if((chan = strtochan(chanstr)) == 0)
error("bad channel");
@@ 266,14 289,12 @@ vgactl(char* a)
vgascreenwin(scr);
cursoron(1);
return;
- }
- else if(strcmp(field[0], "actualsize") == 0){
+
+ case CMactualsize:
if(scr->gscreen == nil)
error("set the screen size first");
- if(n < 2)
- error(Ebadarg);
- x = strtoul(field[1], &p, 0);
+ x = strtoul(cb->f[1], &p, 0);
if(x == 0 || x > 2048)
error(Ebadarg);
if(*p)
@@ 289,60 310,48 @@ vgactl(char* a)
physgscreenr = Rect(0,0,x,y);
scr->gscreen->clipr = physgscreenr;
return;
- }
- else if(strcmp(field[0], "palettedepth") == 0){
- if(n < 2)
- error(Ebadarg);
-
- x = strtoul(field[1], &p, 0);
+
+ case CMpalettedepth:
+ x = strtoul(cb->f[1], &p, 0);
if(x != 8 && x != 6)
error(Ebadarg);
scr->palettedepth = x;
return;
- }
- else if(strcmp(field[0], "drawinit") == 0){
+
+ case CMdrawinit:
memimagedraw(scr->gscreen, scr->gscreen->r, memblack, ZP, nil, ZP);
if(scr && scr->dev && scr->dev->drawinit)
scr->dev->drawinit(scr);
return;
- }
- else if(strcmp(field[0], "linear") == 0){
- if(n < 2)
+
+ case CMlinear:
+ if(cb->nf!=2 && cb->nf!=3)
error(Ebadarg);
-
- size = strtoul(field[1], 0, 0);
- if(n < 3)
+ size = strtoul(cb->f[1], 0, 0);
+ if(cb->nf == 2)
align = 0;
else
- align = strtoul(field[2], 0, 0);
+ align = strtoul(cb->f[2], 0, 0);
if(screenaperture(size, align))
error("not enough free address space");
return;
- }
-/* else if(strcmp(field[0], "memset") == 0){
- if(n < 4)
- error(Ebadarg);
- memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3]));
+/*
+ case CMmemset:
+ memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3]));
return;
- }
*/
- else if(strcmp(field[0], "blank") == 0){
- if(n < 1)
- error(Ebadarg);
+
+ case CMblank:
drawblankscreen(1);
return;
- }
- else if(strcmp(field[0], "blanktime") == 0){
- if(n < 2)
- error(Ebadarg);
- blanktime = strtoul(field[1], 0, 0);
+
+ case CMblanktime:
+ blanktime = strtoul(cb->f[1], 0, 0);
return;
- }
- else if(strcmp(field[0], "panning") == 0){
- if(n < 2)
- error(Ebadarg);
- if(strcmp(field[1], "on") == 0){
+
+ case CMpanning:
+ if(strcmp(cb->f[1], "on") == 0){
if(scr == nil || scr->cur == nil)
error("set screen first");
if(!scr->cur->doespanning)
@@ 350,37 359,33 @@ vgactl(char* a)
scr->gscreen->clipr = scr->gscreen->r;
panning = 1;
}
- else if(strcmp(field[1], "off") == 0){
+ else if(strcmp(cb->f[1], "off") == 0){
scr->gscreen->clipr = physgscreenr;
panning = 0;
}else
- error(Ebadarg);
+ break;
return;
- }
- else if(strcmp(field[0], "hwaccel") == 0){
- if(n < 2)
- error(Ebadarg);
- if(strcmp(field[1], "on") == 0)
+
+ case CMhwaccel:
+ if(strcmp(cb->f[1], "on") == 0)
hwaccel = 1;
- else if(strcmp(field[1], "off") == 0)
+ else if(strcmp(cb->f[1], "off") == 0)
hwaccel = 0;
else
- error(Ebadarg);
+ break;
return;
- }
- else if(strcmp(field[0], "hwblank") == 0){
- if(n < 2)
- error(Ebadarg);
- if(strcmp(field[1], "on") == 0)
+
+ case CMhwblank:
+ if(strcmp(cb->f[1], "on") == 0)
hwblank = 1;
- else if(strcmp(field[1], "off") == 0)
+ else if(strcmp(cb->f[1], "off") == 0)
hwblank = 0;
else
- error(Ebadarg);
+ break;
return;
}
- error(Ebadarg);
+ cmderror(cb, "bad VGA control message");
}
char Enooverlay[] = "No overlay support";
@@ 388,8 393,8 @@ char Enooverlay[] = "No overlay support";
static long
vgawrite(Chan* c, void* a, long n, vlong off)
{
- char *p;
ulong offset = off;
+ Cmdbuf *cb;
VGAscr *scr;
switch((ulong)c->qid.path){
@@ 400,16 405,14 @@ vgawrite(Chan* c, void* a, long n, vlong off)
case Qvgactl:
if(offset || n >= READSTR)
error(Ebadarg);
- p = malloc(READSTR);
+ cb = parsecmd(a, n);
if(waserror()){
- free(p);
+ free(cb);
nexterror();
}
- memmove(p, a, n);
- p[n] = 0;
- vgactl(p);
+ vgactl(cb);
poperror();
- free(p);
+ free(cb);
return n;
case Qvgaovl:
M pc/mouse.c => pc/mouse.c +64 -29
@@ 27,6 27,30 @@ static int packetsize;
static int resolution;
static int accelerated;
+enum
+{
+ CMaccelerated,
+ CMintellimouse,
+ CMlinear,
+ CMps2,
+ CMps2intellimouse,
+ CMres,
+ CMreset,
+ CMserial,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+ CMaccelerated, "accelerated", 0,
+ CMintellimouse, "intellimouse", 1,
+ CMlinear, "linear", 1,
+ CMps2, "ps2", 1,
+ CMps2intellimouse, "ps2intellimouse", 1,
+ CMres, "res", 0,
+ CMreset, "reset", 1,
+ CMserial, "serial", 0,
+};
+
/*
* setup a serial mouse
*/
@@ 232,35 256,35 @@ resetmouse(void)
}
void
-mousectl(char* field[], int n)
+mousectl(Cmdbuf *cb)
{
- if(strncmp(field[0], "serial", 6) == 0){
- switch(n){
- case 1:
- serialmouse(atoi(field[0]+6), 0, 1);
- break;
- case 2:
- serialmouse(atoi(field[1]), 0, 0);
- break;
- case 3:
- default:
- serialmouse(atoi(field[1]), field[2], 0);
- break;
- }
- } else if(strcmp(field[0], "ps2") == 0){
+ Cmdtab *ct;
+
+ ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+ switch(ct->index){
+ case CMaccelerated:
+ setaccelerated(cb->nf == 1 ? 1 : atoi(cb->f[1]));
+ break;
+ case CMintellimouse:
+ setintellimouse();
+ break;
+ case CMlinear:
+ setlinear();
+ break;
+ case CMps2:
ps2mouse();
- } else if(strcmp(field[0], "ps2intellimouse") == 0){
+ break;
+ case CMps2intellimouse:
ps2mouse();
setintellimouse();
- } else if(strcmp(field[0], "accelerated") == 0){
- setaccelerated(n == 1 ? 1 : atoi(field[1]));
- } else if(strcmp(field[0], "linear") == 0){
- setlinear();
- } else if(strcmp(field[0], "res") == 0){
- if(n >= 2)
- n = atoi(field[1]);
- setres(n);
- } else if(strcmp(field[0], "reset") == 0){
+ break;
+ case CMres:
+ if(cb->nf >= 2)
+ setres(atoi(cb->f[1]));
+ else
+ setres(1);
+ break;
+ case CMreset:
resetmouse();
if(accelerated)
setaccelerated(accelerated);
@@ 268,9 292,20 @@ mousectl(char* field[], int n)
setres(resolution);
if(intellimouse)
setintellimouse();
- } else if(strcmp(field[0], "intellimouse") == 0){
- setintellimouse();
+ break;
+ case CMserial:
+ switch(cb->nf){
+ case 1:
+ serialmouse(atoi(cb->f[0]+6), 0, 1);
+ break;
+ case 2:
+ serialmouse(atoi(cb->f[1]), 0, 0);
+ break;
+ case 3:
+ default:
+ serialmouse(atoi(cb->f[1]), cb->f[2], 0);
+ break;
+ }
+ break;
}
- else
- error(Ebadctl);
}
M pc/screen.h => pc/screen.h +1 -1
@@ 122,7 122,7 @@ enum {
};
/* mouse.c */
-extern void mousectl(char*[], int);
+extern void mousectl(Cmdbuf*);
/* screen.c */
extern int hwaccel; /* use hw acceleration; default on */
M pc/vgamach64xx.c => pc/vgamach64xx.c +43 -39
@@ 1007,14 1007,11 @@ mach64xxdrawinit(VGAscr *scr)
}
static void
-ovl_configure(VGAscr *scr, Chan *c, int nfields, char **field)
+ovl_configure(VGAscr *scr, Chan *c, char **field)
{
int w, h;
char *format;
- if (nfields != 4)
- error(Ebadarg);
-
w = (int)strtol(field[1], nil, 0);
h = (int)strtol(field[2], nil, 0);
format = field[3];
@@ 1071,14 1068,11 @@ ovl_configure(VGAscr *scr, Chan *c, int nfields, char **field)
}
static void
-ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
+ovl_enable(VGAscr *scr, Chan *c, char **field)
{
int x, y, w, h;
long h_inc, v_inc;
- if (nfields != 5)
- error(Ebadarg);
-
x = (int)strtol(field[1], nil, 0);
y = (int)strtol(field[2], nil, 0);
w = (int)strtol(field[3], nil, 0);
@@ 1114,11 1108,8 @@ ovl_enable(VGAscr *scr, Chan *c, int nfields, char **field)
}
static void
-ovl_status(VGAscr *scr, Chan *, int nfields, char **field)
+ovl_status(VGAscr *scr, Chan *, char **field)
{
- if (nfields != 1)
- error(Ebadarg);
-
pprint("%s: %s %.4uX, VT/GT %s, PRO %s, ovlclock %d, rev B %s, refclock %ld\n",
scr->dev->name, field[0], mach64type->m64_id,
mach64type->m64_vtgt? "yes": "no",
@@ 1132,19 1123,17 @@ ovl_status(VGAscr *scr, Chan *, int nfields, char **field)
}
static void
-ovl_openctl(VGAscr *, Chan *c, int nfields, char **)
+ovl_openctl(VGAscr *, Chan *c, char **)
{
- if (nfields != 1)
- error(Ebadarg);
if (ovl_chan)
error(Einuse);
ovl_chan = c;
}
static void
-ovl_closectl(VGAscr *scr, Chan *c, int nfields, char **)
+ovl_closectl(VGAscr *scr, Chan *c, char **)
{
- if (c != ovl_chan || nfields != 1) return;
+ if (c != ovl_chan) return;
waitforidle(scr);
scr->mmio[mmoffset[OverlayScaleCntl]] &=
@@ 1153,39 1142,54 @@ ovl_closectl(VGAscr *scr, Chan *c, int nfields, char **)
ovl_width = ovl_height = ovl_fib = 0;
}
-static struct {
- char *ovl_command;
- void (*ovl_f)(VGAscr *, Chan *, int, char **);
-} ovl_cmds[] = {
- { "openctl", ovl_openctl },
- { "configure", ovl_configure, },
- { "enable", ovl_enable, },
- { "closectl", ovl_closectl },
- { "status", ovl_status },
+enum
+{
+ CMclosectl,
+ CMconfigure,
+ CMenable,
+ CMopenctl,
+ CMstatus,
+};
+
+static void (*ovl_cmds[])(VGAscr *, Chan *, char **) =
+{
+ [CMclosectl] ovl_closectl,
+ [CMconfigure] ovl_configure,
+ [CMenable] ovl_enable,
+ [CMopenctl] ovl_openctl,
+ [CMstatus] ovl_status,
+};
+
+static Cmdtab mach64xxcmd[] =
+{
+ CMclosectl, "closectl", 1,
+ CMconfigure, "configure", 4,
+ CMenable, "enable", 5,
+ CMopenctl, "openctl", 1,
+ CMstatus, "status", 1,
};
static void
-mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int)
+mach64xxovlctl(VGAscr *scr, Chan *c, void *a, int n)
{
-#define MAXARGS 10
- char *field[MAXARGS];
- int nfields, i;
+ Cmdbuf *cb;
+ Cmdtab *ct;
if (!mach64type->m64_vtgt)
error(Enodev);
- nfields = tokenize(a, field, nelem(field));
- if (nfields < 1)
- error(Ebadarg);
+ cb = parsecmd(a, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
- for (i = 0; i != nelem(ovl_cmds); i++)
- if (!strcmp(field[0], ovl_cmds[i].ovl_command))
- break;
+ ct = lookupcmd(cb, mach64xxcmd, nelem(mach64xxcmd));
- if (i == nelem(ovl_cmds))
- error(Ebadarg);
+ ovl_cmds[ct->index](scr, c, cb->f);
- ovl_cmds[i].ovl_f(scr, c, nfields, field);
+ poperror();
+ free(cb);
}
static int
M port/devmouse.c => port/devmouse.c +41 -17
@@ 43,6 43,20 @@ struct Mouseinfo
uchar qfull; /* queue is full */
};
+enum
+{
+ CMbuttonmap,
+ CMswap,
+ CMwildcard,
+};
+
+static Cmdtab mousectlmsg[] =
+{
+ CMbuttonmap, "buttonmap", 0,
+ CMswap, "swap", 1,
+ CMwildcard, "*", 0,
+};
+
Mouseinfo mouse;
Cursorinfo cursor;
int mouseshifted;
@@ 307,8 321,10 @@ mousewrite(Chan *c, void *va, long n, vlong)
{
char *p;
Point pt;
- char buf[64], *field[3];
- int nf, b, msec;
+ Cmdbuf *cb;
+ Cmdtab *ct;
+ char buf[64];
+ int b, msec;
p = va;
switch((ulong)c->qid.path){
@@ 336,29 352,37 @@ mousewrite(Chan *c, void *va, long n, vlong)
return n;
case Qmousectl:
- if(n >= sizeof(buf))
- n = sizeof(buf)-1;
- strncpy(buf, va, n);
- if(buf[n - 1] == '\n')
- buf[n-1] = 0;
- else
- buf[n] = 0;
- nf = tokenize(buf, field, 3);
- if(strcmp(field[0], "swap") == 0){
+ cb = parsecmd(va, n);
+ if(waserror()){
+ free(cb);
+ nexterror();
+ }
+
+ ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
+
+ switch(ct->index){
+ case CMswap:
if(mouseswap)
setbuttonmap("123");
else
setbuttonmap("321");
mouseswap ^= 1;
- }
- else if(strcmp(field[0], "buttonmap") == 0){
- if(nf == 1)
+ break;
+
+ case CMbuttonmap:
+ if(cb->nf == 1)
setbuttonmap("123");
else
- setbuttonmap(field[1]);
+ setbuttonmap(cb->f[1]);
+ break;
+
+ case CMwildcard:
+ mousectl(cb);
+ break;
}
- else
- mousectl(field, nf);
+
+ free(cb);
+ poperror();
return n;
case Qmousein:
M port/devproc.c => port/devproc.c +1 -3
@@ 73,6 73,7 @@ Dirtab procdir[] =
"profile", {Qprofile}, 0, 0400,
};
+static
Cmdtab proccmd[] = {
CMclose, "close", 2,
CMclosefiles, "closefiles", 1,
@@ 1060,9 1061,6 @@ procctlreq(Proc *p, char *va, int n)
nexterror();
}
- if(cb->nf <= 0)
- error(Ebadctl);
-
ct = lookupcmd(cb, proccmd, nelem(proccmd));
switch(ct->index){
M port/error.h => port/error.h +1 -1
@@ 22,7 22,6 @@ extern char Etoosmall[]; /* read or write too small */
extern char Enoport[]; /* network port not available */
extern char Ehungup[]; /* i/o on hungup channel */
extern char Ebadctl[]; /* bad process or channel control request */
-extern char Eargctl[]; /* wrong number of arguments in control request */
extern char Enodev[]; /* no free devices */
extern char Eprocdied[]; /* process exited */
extern char Enochild[]; /* no living children */
@@ 48,3 47,4 @@ extern char Enoattach[]; /* mount/attach disallowed */
extern char Eshortstat[]; /* stat buffer too small */
extern char Ebadstat[]; /* malformed stat buffer */
extern char Enegoff[]; /* negative i/o offset */
+extern char Ecmdargs[]; /* wrong #args in control message */
M port/parse.c => port/parse.c +31 -7
@@ 68,23 68,47 @@ parsecmd(char *p, int n)
}
/*
+ * Reconstruct original message, for error diagnostic
+ */
+void
+cmderror(Cmdbuf *cb, char *s)
+{
+ int i;
+ char *p, *e;
+
+ p = up->genbuf;
+ e = p+ERRMAX-10;
+ p = seprint(p, e, "%s \"", s);
+ for(i=0; i<cb->nf; i++){
+ if(i > 0)
+ p = seprint(p, e, " ");
+ p = seprint(p, e, "%q", cb->f[i]);
+ }
+ strcpy(p, "\"");
+ error(up->genbuf);
+}
+
+/*
* Look up entry in table
*/
Cmdtab*
-lookupcmd(Cmdbuf *cb, Cmdtab *ct, int nct)
+lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab)
{
int i;
+ Cmdtab *ct;
if(cb->nf == 0)
- error(Ebadctl);
+ error("empty control message");
- for(i=0; i<nct; i++, ct++){
- if(strcmp(cb->f[0], ct->cmd) != 0)
+ for(ct = ctab, i=0; i<nctab; i++, ct++){
+ if(strcmp(ct->cmd, "*") !=0) /* wildcard always matches */
+ if(strcmp(ct->cmd, cb->f[0]) != 0)
continue;
- if(ct->narg!=0 && ct->narg!=cb->nf)
- error(Eargctl);
+ if(ct->narg != 0 && ct->narg != cb->nf)
+ cmderror(cb, Ecmdargs);
return ct;
}
- error(Ebadctl);
+
+ cmderror(cb, "unknown control message");
return nil;
}
M port/portfns.h => port/portfns.h +1 -0
@@ 38,6 38,7 @@ void closemount(Mount*);
void closepgrp(Pgrp*);
void closergrp(Rgrp*);
long clrfpintr(void);
+void cmderror(Cmdbuf*, char*);
int cmount(Chan**, Chan*, int, char*);
void cnameclose(Cname*);
void confinit(void);